Lukas Anzinger <l.anzin...@gmail.com> added the comment:

I can reproduce the problem and have analyzed it a bit. My use case is a bit 
different, I want to use autospec=True and wraps= so that I can mock unbound 
methods but return the result from the original method (see also 
https://docs.python.org/3/library/unittest.mock-examples.html#mocking-unbound-methods).

The problem in the mock code is that mock.return_value actually calls 
__get_return_value() which replaces the actual return value mock.DEFAULT (which 
is stored in self._mock_return_value) with a new child mock. When the mock is 
then called and _mock_call() is executed, the wrapped function is not executed 
because self._mock_return_value is not mock.DEFAULT anymore:


    if (self._mock_wraps is not None and
         self._mock_return_value is DEFAULT):
        return self._mock_wraps(*args, **kwargs)
    if ret_val is DEFAULT:
        ret_val = self.return_value
    return ret_val


Since self._mock_return_value is not DEFAULT anymore it doesn't matter if the 
mock wraps something and it will instead just return a new mock.

I think that the side effect of the assignment to self.return_value in 
_setup_func() is not intentional, i.e. the child mock should actually be 
created only if there is an outside access to return_value, but not when it is 
just wrapped in a function. The assignment can be made side effect free by 
assigning the internal attribute _mock_return_value (see attached patch). This 
solves the problem for me.
 
I've attached a patch that fixes the problem and doesn't seem to introduce a 
regression (all unittest.mock tests pass).

If somebody is interested in getting this merged, I'm happy to provide a 
regression test and everything else that is needed to get this merged.

Cheers,

Lukas

----------
keywords: +patch
nosy: +Lukas Anzinger
versions: +Python 3.7
Added file: 
https://bugs.python.org/file47267/0001-bpo-31807-unittest.mock-Fix-common-use-of-autospec-T.patch

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue31807>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to