Skip to content

Add 2.0 deprecation warnings for 1.4 second-wave removals (#263)#286

Merged
derek73 merged 3 commits into
masterfrom
feature/263-1.4-deprecation-warnings
Jul 12, 2026
Merged

Add 2.0 deprecation warnings for 1.4 second-wave removals (#263)#286
derek73 merged 3 commits into
masterfrom
feature/263-1.4-deprecation-warnings

Conversation

@derek73

@derek73 derek73 commented Jul 12, 2026

Copy link
Copy Markdown
Owner

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_default assignment (Remove empty_attribute_default; empty attributes always return '' #255): once None support goes, the only legal value left is the default -- a dial with one position isn't configuration. Assignment now emits DeprecationWarning via a new _EmptyAttributeDefaultAttribute descriptor and rejects non-str/non-None values outright with TypeError; reading the attribute is unaffected.
  • TupleManager/RegexTupleManager unknown-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 displaying CONSTANTS.regexes in a notebook doesn't misfire the warning.
  • HumanName slice __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 via name["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, naming add() as the replacement. Previously only the bytes-decode path warned, so the method's own removal was silently unwarned on the str path.
  • 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 use inspect.getattr_static instead of getattr to detect descriptor types without triggering __get__ -- needed because the new _EmptyAttributeDefaultAttribute.__get__(obj=None, ...) intentionally returns '' (not self) to preserve the pre-existing str-only mypy inference on empty_attribute_default (matches the deliberate typing choice from PR #250). That same ''-not-self choice is also load-bearing for Constants.__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

  • TDD throughout: every new warning path had a failing test before implementation
  • Suite verified noise-free, including under -W error::DeprecationWarning (1540 passed / 22 xfailed, zero warnings beyond one pre-existing unrelated marker warning)
  • mypy clean, ruff clean, Sphinx doctest + html builds clean
  • Two independent multi-agent review passes (code, tests, comments, silent-failures, type design) caught and fixed real gaps before landing: a sunder-probe false positive on TupleManager unknown-key access silently returns None / EMPTY_REGEX; raise AttributeError in 2.0 #256; an overly-broad warning-suppression scope in 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 on empty_attribute_default; a stale "~8 properties" comment; and three test-coverage gaps (Constants.copy() preserving a customized empty_attribute_default, an exact-warning-count check on add_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.rst updated 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

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>
@derek73 derek73 self-assigned this Jul 12, 2026
@derek73 derek73 added this to the v1.4 milestone Jul 12, 2026
Repository owner deleted a comment from codecov-commenter Jul 12, 2026
- 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-commenter

codecov-commenter commented Jul 12, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.67%. Comparing base (4aaedb8) to head (afb5571).
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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>
@derek73 derek73 merged commit b6c0679 into master Jul 12, 2026
8 checks passed
@derek73 derek73 deleted the feature/263-1.4-deprecation-warnings branch July 12, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add 2.0 deprecation warnings for second-wave removals (1.4 sweep)

2 participants