Author xtreak
Recipients Claudiu.Popa, and, cjw296, kushal.das, mariocj89, michael.foord, xtreak
Date 2018-12-20.19:45:51
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1545335155.43.0.788709270274.issue21478@psf.upfronthosting.co.za>
In-reply-to
Content
I think this should be handled in _check_and_set_parent where if value's type is FunctionType then value.mock should be used against which parent and name should be set since create_autospec returns function with mock attached to 'mock' attribute and all helper methods attached. There could be a case where a function is directly attached to mock where value will be of FunctionType but value.mock will not be set since it's not created with create_autospec and the AttributeError has to silenced. I think the below patch will handle both scenarios. This doesn't cause any test failure and hence it will be good to convert the original report as a unit test. Feedback welcome on the approach. I will raise a PR with tests and I am updating the relevant versions where this fix can be applied.

Sample program

from unittest import mock

def foo(a, b):
    pass

parent = mock.Mock()
a = mock.create_autospec(foo)
parent.child = a # 'a' is FunctionType and has a.mock attribute set (create_autospec -> _set_signature -> _setup_func)

parent.child_func = foo # 'foo' is FunctionType with no mock attribute set that could cause AttributeError

parent.child(1, 2) # Recorded
parent.child_func(2, 3) # Not recorded since it's actual call to child_func and has no parent set due to AttributeError
print(parent.method_calls) # [call.child(1, 2)]

Patch : 

diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 38189c9aec..143263722d 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -321,6 +321,12 @@ class _CallList(list):


 def _check_and_set_parent(parent, value, name, new_name):
+    if isinstance(value, FunctionTypes):
+        try:
+            value = value.mock
+        except AttributeError:
+            pass
+
     if not _is_instance_mock(value):
         return False
     if ((value._mock_name or value._mock_new_name) or
History
Date User Action Args
2018-12-20 19:45:55xtreaksetrecipients: + xtreak, cjw296, michael.foord, Claudiu.Popa, kushal.das, and, mariocj89
2018-12-20 19:45:55xtreaksetmessageid: <1545335155.43.0.788709270274.issue21478@psf.upfronthosting.co.za>
2018-12-20 19:45:54xtreaklinkissue21478 messages
2018-12-20 19:45:51xtreakcreate