You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mock uses incorrect signature for partial and partialmethod with autospec #79644
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2018-12-11.14:47:32.441>labels= ['3.7', '3.8', 'type-bug', 'library']
title='mock uses incorrect signature for partial and partialmethod with autospec'updated_at=<Date2018-12-11.14:47:32.441>user='https://github.com/tirkarthi'
When we call create_autospec it calls _get_signature_object that gets the signature for the given parameter. With functools.partial it returns a partial object and hence while getting the signature it returns the signature for the constructor of partial instead of the underlying function passed to functools.partial. I think a check needs to be added to make sure not to use func.__init__ when it's a partial object.
When we call create_autospect on a class that has a partialmethod the self parameter is not skipped in the signature and thus it creates a signature with self causing error. The fix would be to handle partialmethod also in _must_skip that determines whether to skip self or not.
Sample reproducer :
fromfunctoolsimportpartial, partialmethodfromunittest.mockimportcreate_autospecimportinspectdeffoo(a, b):
passp=partial(foo, 1)
m=create_autospec(p)
m(1, 2, 3) # passes since signature is set as (*args, **kwargs) the signature of functools.partial constructor. This should throw TypeError under autospecclassA:
deff(self, a, b):
print(a, b)
g=partialmethod(f, 1)
m=create_autospec(A)
m().g(1, 2) # passes since signature is set as (self, b) and self is not skipped in _must_skip thus self=1, b=2. This should throw TypeError under autospec since the valid call is m().g(2)
Activity
tirkarthi commentedon Dec 11, 2018
This is a bug report for https://bugs.python.org/issue17185#msg331149 that I was asked to raise as a separate issue.
When we call create_autospec it calls _get_signature_object that gets the signature for the given parameter. With functools.partial it returns a partial object and hence while getting the signature it returns the signature for the constructor of partial instead of the underlying function passed to functools.partial. I think a check needs to be added to make sure not to use func.__init__ when it's a partial object.
When we call create_autospect on a class that has a partialmethod the self parameter is not skipped in the signature and thus it creates a signature with self causing error. The fix would be to handle partialmethod also in _must_skip that determines whether to skip self or not.
Sample reproducer :
pythongh-79644: Fix create_autospec signature handling for functools …
pythongh-79644: Fix create_autospec signature handling for functools …