gh-79644: Fix create_autospec signature handling for functools partial and partialmethod#153580
Open
claudiubelu wants to merge 1 commit into
Open
gh-79644: Fix create_autospec signature handling for functools partial and partialmethod#153580claudiubelu wants to merge 1 commit into
claudiubelu wants to merge 1 commit into
Conversation
…partial and partialmethod Fixes both cases reported in pythongh-79644: 1. functools.partial: _get_signature_object() fell through to inspecting func.__call__ for anything that wasn't a plain function / method. For a functools.partial, that resolves to the C slot wrapper's own generic "(*args, **kwargs)" signature rather than the partial's effective, post-partial-application one. inspect.signature() already has first-class support for computing a functools.partial's effective signature directly; skip the func.__call__ detour and let it do so. 2. functools.partialmethod: _must_skip() special-cases staticmethod / classmethod / plain functions to decide whether `self` should be dropped from an autospecced method's signature, but had no branch for functools.partialmethod. The raw partialmethod object stored in klass.__dict__ matched none of those cases and fell through to the "not a method" branch, always returning False regardless of `is_type`. The resolved attribute used to build the child mock's signature (obtained via getattr(), which goes through the descriptor protocol) is a plain function whose signature still includes `self` when accessed unbound at the class level, so without this fix self's position was checked against the partialmethod's own pre-bound argument instead of being skipped. Signed-off-by: Claudiu Belu <cbelu@cloudbasesolutions.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.
Fixes both cases reported in gh-79644 (#79644):
functools.partial:_get_signature_object()fell through to inspectingfunc.__call__for anything that wasn't a plain function / method. For afunctools.partial, that resolves to the C slot wrapper's own generic(*args, **kwargs)signature rather than the partial's effective, post-partial-application one.inspect.signature()already has first-class support for computing afunctools.partial's effective signature directly; skip thefunc.__call__detour and let it do so.functools.partialmethod:_must_skip()special-casesstaticmethod/classmethod/ plain functions to decide whetherselfshould be dropped from an autospecced method's signature, but had no branch forfunctools.partialmethod. The rawpartialmethodobject stored inklass.__dict__matched none of those cases and fell through to the "not a method" branch, always returning False regardless ofis_type. The resolved attribute used to build the child mock's signature (obtained viagetattr(), which goes through the descriptor protocol) is a plain function whose signature still includesselfwhen accessed unbound at the class level, so without this fix self's position was checked against thepartialmethod's own pre-bound argument instead of being skipped.