Add 2.0 deprecation warnings for 1.4 second-wave removals (#263)#286
Merged
Conversation
One themed PR, mirroring how the 1.3.0 sweep shipped (#253), so every decided 2.0 removal in the second wave warns ahead of time: - empty_attribute_default assignment (#255): once None support goes, the only legal value left is the default, so assignment now warns via a new descriptor; reads stay silent. - TupleManager/RegexTupleManager unknown-key attribute access (#256): a misspelled or omitted key currently degrades silently (None/ EMPTY_REGEX); now warns naming the miss and the known keys. Excludes single-underscore introspection probes (IPython's _repr_html_, etc.) alongside the existing dunder guard. - HumanName slice __getitem__ and all of __setitem__ (#258): field access by position has no real use case, and item assignment duplicates plain attribute assignment. - SetManager.add_with_encoding() (#245): the method itself now warns on every call regardless of argument type, naming add() as the replacement -- previously only the bytes-decode path warned. - Constants.__setstate__'s legacy-pickle migration shim (#279): warns once per call (not once per skipped key) when it loads a pre-1.3.0 blob, telling users to re-pickle. Same standards as #253: TDD throughout, suite verified noise-free including under -W error::DeprecationWarning, mypy/ruff clean, Sphinx doctest + html builds clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Fix conftest.py's empty_attribute_default fixture teardown: the DeprecationWarning-ignore filter wrapped the restore of all 8 scalar config attrs instead of just the one deprecated assignment, which would have silently swallowed any future deprecation warning added to the other 7 -- a silent-failure hunter finding. Scoped to match the already-narrow setup block. - Add a type check to _EmptyAttributeDefaultAttribute.__set__: a cheap, immediate TypeError for non-str/non-None values instead of deferring the whole invariant to 2.0 (type-design-analyzer finding). - Document why __get__(obj=None) returns '' rather than `self` (unlike its _SetManagerAttribute sibling): it's load-bearing for Constants.__repr__'s default-value comparison, not just mypy inference (type-design-analyzer finding). - Fix a stale "~8 public str-typed properties" comment (actually 12) in two test files (comment-analyzer finding). - Add tests: Constants.copy() preserves a customized empty_attribute_default without warning; add_with_encoding()'s str path emits exactly one warning, not two; the legacy-pickle warning fires once per __setstate__ call even with two stale keys, not once per key (test-analyzer findings). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #286 +/- ##
==========================================
- Coverage 97.70% 97.67% -0.04%
==========================================
Files 13 13
Lines 917 947 +30
==========================================
+ Hits 896 925 +29
- Misses 21 22 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
len(name), list(name), and name['first'] examples removed: the string-key access is already demonstrated earlier in the same doctest (name["title"]), and len()/list() aren't central to the quick-start walkthrough this section is meant to be. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
One themed PR, mirroring how the 1.3.0 sweep shipped (#253), so every decided 2.0 removal in the second wave warns ahead of time. Closes #263; the parent 2.0-removal issues (#255, #256, #258, #245, #279) stay open for their actual removal halves.
empty_attribute_defaultassignment (Remove empty_attribute_default; empty attributes always return '' #255): onceNonesupport goes, the only legal value left is the default -- a dial with one position isn't configuration. Assignment now emitsDeprecationWarningvia a new_EmptyAttributeDefaultAttributedescriptor and rejects non-str/non-None values outright withTypeError; reading the attribute is unaffected.TupleManager/RegexTupleManagerunknown-key attribute access (TupleManager unknown-key access silently returns None / EMPTY_REGEX; raise AttributeError in 2.0 #256): a misspelled or omitted key (CONSTANTS.regexes.parenthesys,CONSTANTS.capitalization_exceptions.phd_typo) currently degrades silently (None/EMPTY_REGEX) with no traceback pointing at the typo. Now warns naming the miss and the known keys;.get()remains available for intentional soft access. Single-underscore introspection probes (IPython's_repr_html_,_ipython_canary_method_should_not_exist_, etc.) are excluded alongside the existing dunder guard, so displayingCONSTANTS.regexesin a notebook doesn't misfire the warning.HumanNameslice__getitem__and all of__setitem__(Deprecate slice __getitem__ and __setitem__ on HumanName #258): field access by position (name[1:-3]) has no real use case, and item assignment (name['first'] = x) duplicates plain attribute assignment. Both now warn; string-key access (name['first']) is unaffected.docs/usage.rst's quick-start doctest drops the now-deprecated slicing/item-assignment examples -- string-key access was already demonstrated there vianame["title"].SetManager.add_with_encoding()(Drop bytes input in 2.0; require str #245): the method itself now warns on every call regardless of argument type, namingadd()as the replacement. Previously only the bytes-decode path warned, so the method's own removal was silently unwarned on thestrpath.Constants.__setstate__'s legacy-pickle migration shim (Constants.__setstate__ loads pre-1.3.0 pickle blobs via a silent migration shim; drop the shim in 2.0 #279): warns once per__setstate__call (not once per skipped key, verified with two stale keys in one blob) when it loads a pre-1.3.0 blob carrying a stale computed-property key, telling users to re-pickle.Notable implementation detail
__getstate__/__setstate__now useinspect.getattr_staticinstead ofgetattrto detect descriptor types without triggering__get__-- needed because the new_EmptyAttributeDefaultAttribute.__get__(obj=None, ...)intentionally returns''(notself) to preserve the pre-existingstr-only mypy inference onempty_attribute_default(matches the deliberate typing choice from PR #250). That same''-not-selfchoice is also load-bearing forConstants.__repr__'s default-value comparison, not just mypy -- documented inline. Restoring pickled/copied state bypasses the descriptor's warning-emitting setter, since that isn't a user assignment.Test plan
-W error::DeprecationWarning(1540 passed / 22 xfailed, zero warnings beyond one pre-existing unrelated marker warning)tests/conftest.py's autouse fixture that would have silently swallowed any future deprecation warning on the other 7 scalar config attrs; missing type validation onempty_attribute_default; a stale "~8 properties" comment; and three test-coverage gaps (Constants.copy()preserving a customizedempty_attribute_default, an exact-warning-count check onadd_with_encoding()'s str path, and a genuine once-per-call-not-per-key check for Constants.__setstate__ loads pre-1.3.0 pickle blobs via a silent migration shim; drop the shim in 2.0 #279)docs/release_log.rstupdated under 1.4.0 Unreleased;docs/usage.rst's quick-start doctest trimmed of the deprecated/redundant slicing, len(), list(), and item-access examples🤖 Generated with Claude Code