Skip to content

fix: PEP 702 crash, decoration-time guards, and docs for v0.8#169

Merged
Borda merged 14 commits into
mainfrom
dev/update
May 20, 2026
Merged

fix: PEP 702 crash, decoration-time guards, and docs for v0.8#169
Borda merged 14 commits into
mainfrom
dev/update

Conversation

@Borda

@Borda Borda commented May 20, 2026

Copy link
Copy Markdown
Owner
Before submitting
  • Was this discussed/approved via a Github issue? (no need for typos and docs improvements)
  • Did you make sure to update the docs?
  • Did you write any new necessary tests?

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:

  • Added _validate_template_mgs to validate custom template_mgs warning templates at decoration time, catching typos and malformed placeholders before runtime. This is now called in both @deprecated and proxy initialization. [1] [2] [3] [4]

Proxy and Read-Only Behavior:

  • Clarified in documentation and docstrings that read_only=True for deprecated_instance and 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:

  • Improved robustness when stacking @deprecated with 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]
  • Added a guard and warning for unsupported stacking of callable-targeted @deprecated decorators, surfacing potential TypeError at decoration time instead of runtime.

Cross-Class Method Targeting:

  • Improved error messages and documentation for the cross-class method target guard, clarifying when and why TypeError is raised and listing fixes and false positive resolutions. [1] [2]

Documentation and Audit Tools:

  • Expanded documentation with examples of audit tool output, deprecated-to-deprecated chain detection, and clarified when to prefer standard library deprecation tools versus 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 🙃

Borda and others added 7 commits May 20, 2026 01:44
… 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>
Copilot AI review requested due to automatic review settings May 20, 2026 06:57
@dosubot dosubot Bot added bug / fix Something isn't working documentation Improvements or additions to documentation enhancement New feature or request tests labels May 20, 2026
Comment thread README.md Outdated
Co-authored-by: Jirka Borovec <6035284+Borda@users.noreply.github.com>
@kilo-code-bot

kilo-code-bot Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (10 files)
  • README.md — doc additions (read_only/mutator, isinstance pass-through)
  • docs/overrides/main.html — FAQ JSON-LD additions
  • docs/troubleshooting.md — troubleshooting entries (TypeError quote reformatted to code block)
  • src/deprecate/deprecation.py — core logic: template_mgs probe, closure capture, stacked-target guard
  • src/deprecate/proxy.py — proxy docstring and template_mgs probe
  • tests/collection_deprecate.py — PEP 702 stacking fixtures (B1a, B1b)
  • tests/collection_targets.py — regression targets and helper fixtures
  • tests/requirements.txt — typing_extensions dependency
  • tests/unittests/test_deprecation.py — PEP 702 stacking + template_mgs + stacked-callable tests
  • tests/unittests/test_proxy.py — PEP 702 proxy stacking + custom-mutator tests

Reviewed by step-3.5-flash · 179,813 tokens

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_mgs to surface malformed % placeholders early (decorator + proxy paths).
  • Harden @deprecated and 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.

Comment thread src/deprecate/deprecation.py Outdated
Comment thread docs/troubleshooting.md Outdated
Borda and others added 5 commits May 20, 2026 09:04
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>
@Borda Borda merged commit 8c1834c into main May 20, 2026
48 checks passed
@Borda Borda deleted the dev/update branch May 20, 2026 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug / fix Something isn't working documentation Improvements or additions to documentation enhancement New feature or request tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants