feat: accept staticmethod/classmethod descriptors as target#192
Open
Borda wants to merge 8 commits into
Open
Conversation
`_normalize_target` now unwraps `staticmethod` and `classmethod` objects passed as `target`, extracting `.__func__` before forwarding to the callable path. Enables `target=bbb` inside a class body where `bbb` is still the raw descriptor, removing the need for `target=bbb.__func__`. - Add descriptor unwrap branch in `_normalize_target` (staticmethod + classmethod) - Extend `target` type annotation on `deprecated()`, `_normalize_target`, `_raise_warn_callable`, `_build_call_plan` to include `staticmethod | classmethod` - Add `ServiceCls.old_static_redirect` and `old_static_redirect_mapped` fixtures in `collection_deprecate.py` - Add `TestStaticMethodDescriptorTarget` (3 tests) in `test_property.py` - Add use-cases doc subsection for same-class static forwarding with and without `args_mapping` - Add no-redundant-naming test rule to AGENTS.md --- Co-authored-by: Claude Code <noreply@anthropic.com>
for more information, see https://pre-commit.ci
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (6 files)
Incremental check: Verified changes since previous review (commit f5023e3). All changes are non-code improvements:
No new code issues detected. Reviewed by laguna-m.1-20260312:free · 1,151,287 tokens |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends pyDeprecate’s call-forwarding to accept raw staticmethod/classmethod descriptor objects as target (e.g. using target=bbb inside a class body), by unwrapping descriptors to their underlying .__func__ during target normalization.
Changes:
- Unwrap
staticmethod/classmethodtargets in_normalize_target()and widentargettype annotations accordingly. - Add test coverage and new collection fixtures for staticmethod descriptor-target forwarding (including
args_mapping). - Document the new “same-class staticmethod forwarding without
.__func__” use-case and add an agent/testing guideline note.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/deprecate/deprecation.py |
Adds descriptor unwrapping in _normalize_target and updates target type annotations. |
tests/unittests/test_property.py |
Adds unit tests validating forwarding behavior when target is a raw staticmethod descriptor. |
tests/collection_deprecate.py |
Adds ServiceCls staticmethod wrappers that forward via descriptor targets (and with args_mapping). |
docs/guide/use-cases.md |
Documents same-class staticmethod forwarding using target=<descriptor> without .__func__. |
AGENTS.md |
Adds a “no redundant naming” test naming rule and a reference link to CONTRIBUTING. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…descriptor targets - Add descriptor unwrap in `_raise_warn_callable` before `callable(target)` check: `callable(staticmethod(fn))` is False on Py3.9 and `callable(classmethod(fn))` is always False, so without this fix the no-target warning template fires incorrectly (target name omitted from FutureWarning message). - Add decoration-time TypeError guard in `_normalize_target` for asymmetric classmethod usage: when `classmethod.__func__` is the target but source has no `cls` parameter, `cls` would be missing at call time; now raises at decoration time with a clear message. - Fix cross-class guard to inspect `__func__` for descriptor targets: raw descriptor lacks `__qualname__` on the instance, so the guard now unwraps before comparing. --- Co-authored-by: Claude Code <noreply@anthropic.com>
…s to use collection fixtures - Add `ServiceCls.old_class_redirect` and `old_class_redirect_mapped` to collection_deprecate.py — classmethod descriptor forwarding fixtures mirroring the staticmethod equivalents. - Add `TestClassMethodDescriptorTarget` (4 tests): forwards_call, with_args_mapping, no_decoration_time_warning, and asymmetric_raises_at_decoration_time (verifies the new TypeError guard in `_normalize_target`). - Refactor `TestStaticMethodDescriptorTarget.test_forwards_call` and `test_with_args_mapping` to use `ServiceCls` collection fixtures (three-layer rule); keep `test_no_decoration_time_warning` inline (it tests class-body evaluation, not call time). - Add `match="in favor of"` and target-name assertions to forwarding tests — verifies the `_raise_warn_callable` fix (warning message now names the target on all Python versions). --- Co-authored-by: Claude Code <noreply@anthropic.com>
…descriptor target support --- Co-authored-by: Claude Code <noreply@anthropic.com>
…o Decision Flowchart Agents reading the flowchart now learn that target=new_method (raw descriptor in class body) is the correct form — no .__func__ needed. Documents the classmethod symmetric-only constraint and adds an anti-pattern entry for manual .__func__ access. --- 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?
_normalize_targetnow unwrapsstaticmethodandclassmethodobjects passed astarget, extracting.__func__before forwarding to the callable path. Enablestarget=bbbinside a class body wherebbbis still the raw descriptor, removing the need fortarget=bbb.__func__._normalize_target(staticmethod + classmethod)targettype annotation ondeprecated(),_normalize_target,_raise_warn_callable,_build_call_planto includestaticmethod | classmethodServiceCls.old_static_redirectandold_static_redirect_mappedfixtures incollection_deprecate.pyTestStaticMethodDescriptorTarget(3 tests) intest_property.pyargs_mappingPR 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 🙃