Author xtreak
Recipients cjw296, gregory.p.smith, lisroach, lukasz.langa, mariocj89, michael.foord, ned.deily, xtreak
Date 2019-10-14.14:25:08
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
The following program causes AttributeError while retrieving the spec signature of a call. It seems that not all mocks specced should have _spec_signature where if autospec is used and the mock is attached with attach_mock then the "mock" attribute has the correct object from which _spec_signature has to be derived. On the attribute being not present we can fallback to the sig being None. This can be workaround by disabling autospec but since this is present in 3.7.5RC1 and 3.8.0RC1 I am tagging it as regression. 

I am also attaching a patch with script to reproduce this that should pass with the patch. I will try to make a PR tonight. Sorry for the last minute report I just stumbled upon this while debugging This change was introduced as part of by me. I am tagging the nosy list from issue for review of the patch.

import unittest
from unittest.mock import patch, Mock, call, ANY

class Foo:
    def set_foo(self, val): pass

class FooTest(unittest.TestCase):
    @patch(f"{__name__}.Foo.set_foo", autospec=True)
    def test_autospec_attach_mock_assert(self, mock_set_foo):
        manager = Mock()
        manager.attach_mock(mock_set_foo, "set_foo_func")
        obj = Foo()
        manager.assert_has_calls([call.set_foo_func(ANY, 3)])

if __name__ == "__main__":

➜  Python-3.7.5rc1 ./python
ERROR: test_autospec_attach_mock_assert (__main__.FooTest)
Traceback (most recent call last):
  File "/home/xtreak/Python-3.7.5rc1/Lib/unittest/", line 1255, in patched
    return func(*args, **keywargs)
  File "", line 16, in test_autospec_attach_mock_assert
    manager.assert_has_calls([call.set_foo_func(ANY, 3)])
  File "/home/xtreak/Python-3.7.5rc1/Lib/unittest/", line 897, in assert_has_calls
    expected = [self._call_matcher(c) for c in calls]
  File "/home/xtreak/Python-3.7.5rc1/Lib/unittest/", line 897, in <listcomp>
    expected = [self._call_matcher(c) for c in calls]
  File "/home/xtreak/Python-3.7.5rc1/Lib/unittest/", line 812, in _call_matcher
    sig = self._get_call_signature_from_name(_call[0])
  File "/home/xtreak/Python-3.7.5rc1/Lib/unittest/", line 798, in _get_call_signature_from_name
    sig = child._spec_signature
AttributeError: 'function' object has no attribute '_spec_signature'

Ran 1 test in 0.003s

FAILED (errors=1)

Patch : 

➜  Python-3.7.5rc1 diff -u Lib/unittest/ Lib/unittest/
--- Lib/unittest/	2019-10-01 22:53:17.000000000 +0530
+++ Lib/unittest/	2019-10-14 19:18:00.038416294 +0530
@@ -795,7 +795,16 @@
                 children = child._mock_children
-                sig = child._spec_signature
+                # If an autospecced object is attached using attach_mock the
+                # child would be a function with mock object as attribute from
+                # which signature has to be derived. If there is no signature
+                # attribute then fallback to None to ensure old signature is 
+                # not used.
+                child = _extract_mock(child)
+                try:
+                    sig = child._spec_signature
+                except AttributeError:
+                    sig = None
         return sig
Date User Action Args
2019-10-14 14:25:09xtreaksetrecipients: + xtreak, gregory.p.smith, cjw296, ned.deily, michael.foord, lukasz.langa, lisroach, mariocj89
2019-10-14 14:25:09xtreaksetmessageid: <>
2019-10-14 14:25:09xtreaklinkissue38473 messages
2019-10-14 14:25:08xtreakcreate