Skip to content

gh-153581: Fix create_autospec producing an uncallable mock for functools.partialmethod - #153582

Open
claudiubelu wants to merge 2 commits into
python:mainfrom
claudiubelu:fix-gh153581-partialmethod-noncallable-autospec
Open

claudiubelu wants to merge 2 commits into
python:mainfrom
claudiubelu:fix-gh153581-partialmethod-noncallable-autospec

Conversation

@claudiubelu

@claudiubelu claudiubelu commented Jul 11, 2026 •

Copy link
Copy Markdown

functools.partialmethod objects have no __call__ of their own (they are non-data descriptors, only callable once resolved through attribute access), so create_autospec's _callable() check treated them as non-callable and forced Klass = NonCallableMagicMock. Autospeccing such an attribute directly (e.g.: mock.patch.object(cls, name, autospec=True)) therefore produced a mock that raised TypeError on every call, even though the real attribute is perfectly callable.

_callable() now judges callability from the wrapped function (partialmethod.func) instead. _get_signature_object() gained a matching branch that computes the partialmethod's effective signature, self dropped, the partialmethod's own pre-bound positional / keyword arguments applied, so the resulting mock also enforces the correct call signature rather than accepting anything.

@sobolevn sobolevn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(not a full review)

Comment thread Lib/test/test_unittest/testmock/testpatch.py Outdated
Comment thread Lib/test/test_unittest/testmock/testpatch.py Outdated
@claudiubelu

Copy link
Copy Markdown
Author

/cc @ambv Hello, we talked briefly about this bugfix.

… functools.partialmethod

functools.partialmethod objects have no __call__ of their own (they are
non-data descriptors, only callable once resolved through attribute
access), so create_autospec's _callable() check treated them as
non-callable and forced Klass = NonCallableMagicMock. Autospeccing such
an attribute directly (e.g.: mock.patch.object(cls, name, autospec=True))
therefore produced a mock that raised TypeError on every call, even
though the real attribute is perfectly callable.

_callable() now judges callability from the wrapped function
(partialmethod.func) instead. _get_signature_object() gained a matching
branch that computes the partialmethod's effective signature, self
dropped, the partialmethod's own pre-bound positional/keyword arguments
applied, so the resulting mock also enforces the correct call
signature rather than accepting anything.
@claudiubelu
claudiubelu force-pushed the fix-gh153581-partialmethod-noncallable-autospec branch from e05053a to 009253c Compare October 28, 2026 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants