[issue38729] mock.create_autospec generates incorrect signature for some decorated methods

2019-11-08 Thread Ben Reilly


Ben Reilly  added the comment:

Yes, your description sounds right, and I had zero-ed in on the same park of 
the mock code when I was doing my investigation.

I know that this is a peculiar situation, but one thing to note is that 
`inspect.signature` gets the signature right on these wrapped methods. You can 
see this if you were to add in an appropriate spot the following code to the 
script:


from inspect import signature

print(signature(a.with_arg))  # prints `(x)`
print(signature(a.no_arg))# prints `()`


Is there a reason why mock calculates the signature on its own rather than 
relying on `inspect`?

--

___
Python tracker 
<https://bugs.python.org/issue38729>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue30587] Mock with spec object does not ensure method call signatures

2019-11-07 Thread Ben Reilly


Change by Ben Reilly :


--
nosy: +breilly_box

___
Python tracker 
<https://bugs.python.org/issue30587>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38729] mock.create_autospec generates incorrect signature for some decorated methods

2019-11-06 Thread Ben Reilly


Change by Ben Reilly :


--
components: +Tests

___
Python tracker 
<https://bugs.python.org/issue38729>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38729] mock.create_autospec generates incorrect signature for some decorated methods

2019-11-06 Thread Ben Reilly


New submission from Ben Reilly :

mock.create_autospec is meant to create a mock that will ensure, among other 
things, that method calls on the mock correspond to real methods on the 
original object and that the arguments match the signature of the original 
method. However, if the original method is decorated with a method that returns 
a callable object, the signature check may fail.

Attached is a script that demonstrates the error.

The essential part of the script looks like this:

def decorator(m):
return Wrapper(m)

class Wrapper(object):
def __init__(self, method):
self.method = method
update_wrapper(self, method)

def __call__(self, instance, *args, **kwargs):
return self.__get__(instance, type(instance))(*args, **kwargs)

def __get__(self, instance, owner):
... # do the wrapping


The `decorator` method returns an instance of the `Wrapper` class, which is 
callable. Mock will calculate the signature of a method wrapped with 
`decorator` to be equal to that of `Wrapper.__call__`, namely `(instance, 
*args, **kwargs)`. Consequently, calls to the mocked method...

1. will incorrectly fail if the method usually takes no arguments, and
2. will incorrectly pass if the method takes at least one argument but too many 
arguments are provided.

This list of incorrect behaviour is not exhaustive, but hopefully you get the 
point.

If anyone's concerned about real-life examples, this kind of wrapper is used, 
for example, in the public Box SDK, as shown here: 
https://github.com/box/box-python-sdk/blob/b7f41d9a3f8be0ff3622a0c417bf31d2fbbee969/boxsdk/util/api_call_decorator.py#L10

--
files: decorator.py
messages: 356159
nosy: breilly_box
priority: normal
severity: normal
status: open
title: mock.create_autospec generates incorrect signature for some decorated 
methods
type: behavior
versions: Python 3.7
Added file: https://bugs.python.org/file48698/decorator.py

___
Python tracker 
<https://bugs.python.org/issue38729>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com