fix: PEP 702 crash, decoration-time guards, and docs for v0.8#169
Merged
Conversation
… capture - Capture dep_meta in _dep_cfg closure variable after DeprecationConfig is built - Replace __deprecated__ attribute lookup in wrapped_fn with closure read - Add regression test: PEP 702 outer / pyDeprecate inner stack no longer crashes --- Co-authored-by: Claude Code <noreply@anthropic.com>
…e overwrite - Add `_Pep702ProxyTarget` to `tests/collection_targets.py` as the wrapped class for the B1b regression fixture - Add stacked-proxy fixture and `pep702_proxy_stacked` thunk to `tests/collection_deprecate.py` (PEP 702 wrapping the `deprecated_class` proxy) - Add `TestPEP702ProxyStackingRegression` in `tests/unittests/test_proxy.py` with three checks: instantiation does not crash, instance is a `_Pep702ProxyTarget`, outer PEP 702 `DeprecationWarning` is emitted on call The B1b verification confirms `_DeprecatedProxy` is inherently safe — PEP 702's `arg.__deprecated__ = msg` assignment routes through the proxy's forwarding `__setattr__` onto the wrapped class, leaving the proxy's own `object.__setattr__`-stored slot intact. No source-side change to `src/deprecate/proxy.py` was required. --- Co-authored-by: Claude Code <noreply@anthropic.com>
…deprecated - Import _has_deprecation_meta from _types - Add guard in packing(): detect callable-over-callable-target stacking, emit UserWarning - Add test: stacked callable targets warn at decoration, not call time --- Co-authored-by: Claude Code <noreply@anthropic.com>
- Probe template_mgs with all placeholder keys at decoration time in packing() - Apply same validation in proxy.py if template_mgs accepted there - Add test: malformed template raises ValueError at decoration, not call time --- Co-authored-by: Claude Code <noreply@anthropic.com>
- Add 0: suppresses all warnings (equiv stream=None) to num_warns docstring --- Co-authored-by: Claude Code <noreply@anthropic.com>
…utators - README: add parenthetical listing what read_only blocks and what bypasses it - proxy.py docstrings: enumerate blocked and not-blocked method names explicitly - docs/troubleshooting.md: add FAQ entry for custom mutator bypass - docs/overrides/main.html: add FAQPage JSON-LD entry for the limitation - test: assert custom mutator method bypasses read_only guard (documents known limit) --- Co-authored-by: Claude Code <noreply@anthropic.com>
- Move PEP 702 preference callout above the feature matrix with forwarding framing - Add DeprecationConfig shared-contract note after feature table - Add isinstance/issubclass proxy transparency note in deprecated_instance section - Add chains and all CLI subcommand ASCII examples in Audit Tools section - Add cross-class guard troubleshooting entry with v0.8 false-positive fix notes - Add cross-class guard FAQ entry in docs/overrides/main.html JSON-LD --- Co-authored-by: Claude Code <noreply@anthropic.com>
for more information, see https://pre-commit.ci
Borda
commented
May 20, 2026
Co-authored-by: Jirka Borovec <6035284+Borda@users.noreply.github.com>
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (10 files)
Reviewed by step-3.5-flash · 179,813 tokens |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves pyDeprecate’s robustness and diagnostics around decorator stacking (notably PEP 702 / typing_extensions.deprecated), adds earlier validation for custom warning templates, and expands user-facing documentation for proxy/read-only behavior and troubleshooting.
Changes:
- Add decoration-time validation for
template_mgsto surface malformed%placeholders early (decorator + proxy paths). - Harden
@deprecatedand proxy behavior when stacked with PEP 702 deprecation decorators; add regression tests. - Expand README and troubleshooting docs (read-only proxy limitations, cross-class method target errors, audit examples).
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/deprecate/deprecation.py |
Adds _validate_template_mgs, callable-target stacking guard, and PEP 702 stacking fix by capturing DeprecationConfig in a closure. |
src/deprecate/proxy.py |
Validates template_mgs at proxy creation time and documents the read-only mutator interception scope. |
tests/unittests/test_deprecation.py |
Adds regression tests for PEP 702 stacking, template validation, and stacked-callable-target guard behavior. |
tests/unittests/test_proxy.py |
Adds read-only limitation test and PEP 702 proxy-stacking regression coverage. |
tests/collection_targets.py |
Adds targets used by new stacking/guard tests. |
tests/collection_deprecate.py |
Adds fixtures for PEP 702 stacking scenarios (function + proxy). |
tests/requirements.txt |
Adds typing_extensions for PEP 702 regression tests. |
README.md |
Adds guidance on when to prefer stdlib PEP 702 deprecation and expands audit CLI examples. |
docs/troubleshooting.md |
Adds new troubleshooting sections for read-only proxy limitations and cross-class method target errors. |
docs/overrides/main.html |
Extends FAQ structured data for the new troubleshooting topics. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
TypeGuard narrowing via _has_deprecation_meta() hid __name__ from mypy; callables always carry __name__, so it belongs on the protocol. --- Co-authored-by: Claude Code <noreply@anthropic.com>
…uard Replace invented error text with the actual message raised by `_check_cross_class_method_target` in `deprecation.py` — previous wording did not match the real exception output. --- Co-authored-by: Claude Code <noreply@anthropic.com>
…uard Replace invented error text with the actual message raised by `_check_cross_class_method_target` in `deprecation.py` — previous wording did not match the real exception output. --- Co-authored-by: Claude Code <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.
Before submitting
What does this PR do?
This pull request introduces several improvements and clarifications to the deprecation library, focusing on error surfacing, proxy behavior, and documentation. The most significant changes include early validation of custom warning templates, enhanced documentation and user guidance around proxy mutability and cross-class method deprecation, and improved robustness when stacking deprecation decorators. These updates aim to make deprecation handling safer, more transparent, and easier to debug for users.
Validation and Error Surfacing:
_validate_template_mgsto validate customtemplate_mgswarning templates at decoration time, catching typos and malformed placeholders before runtime. This is now called in both@deprecatedand proxy initialization. [1] [2] [3] [4]Proxy and Read-Only Behavior:
read_only=Truefordeprecated_instanceand proxies only intercepts standard collection mutators (e.g.,append,pop,update), not custom methods. Provided workarounds and detailed lists of intercepted methods. [1] [2] [3] [4] F698R700)Decorator Robustness and Stacking:
@deprecatedwith other deprecation decorators (e.g., PEP 702/typing_extensions.deprecated), ensuring correct reading of deprecation metadata and preventing crashes if attributes are overwritten. [1] [2]@deprecateddecorators, surfacing potentialTypeErrorat decoration time instead of runtime.Cross-Class Method Targeting:
TypeErroris raised and listing fixes and false positive resolutions. [1] [2]Documentation and Audit Tools:
pyDeprecate. [1] [2] [3]These changes collectively improve developer experience, error detection, and the clarity of the deprecation workflow.
PR review
Anyone in the community is free to review the PR once the tests have passed.
If we didn't discuss your PR in Github issues there's a high chance it will not be merged.
Did you have fun?
Make sure you had fun coding 🙃