]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-85934: Use getattr_static when adding mock spec (#22209)
authormelanie witt <melwittt@gmail.com>
Tue, 23 May 2023 23:10:34 +0000 (16:10 -0700)
committerGitHub <noreply@github.com>
Tue, 23 May 2023 23:10:34 +0000 (17:10 -0600)
Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
Co-authored-by: Oleg Iarygin <oleg@arhadthedev.net>
Lib/test/test_unittest/testmock/testmock.py
Lib/unittest/mock.py
Misc/NEWS.d/next/Library/2020-09-16-16-53-06.bpo-41768.8_fWkC.rst [new file with mode: 0644]

index d1cae47a40eed4ff840302801a04c0efaf252973..c7895e73ad9a8c259743bda9410e14ab0c7d2dc6 100644 (file)
@@ -38,6 +38,17 @@ class Something(object):
     def smeth(a, b, c, d=None): pass
 
 
+class SomethingElse(object):
+    def __init__(self):
+        self._instance = None
+
+    @property
+    def instance(self):
+        if not self._instance:
+            self._instance = 'object'
+        return self._instance
+
+
 class Typos():
     autospect = None
     auto_spec = None
@@ -2293,6 +2304,26 @@ class MockTest(unittest.TestCase):
             f'{__name__}.Typos', autospect=True, set_spec=True, auto_spec=True):
             pass
 
+    def test_property_not_called_with_spec_mock(self):
+        obj = SomethingElse()
+        self.assertIsNone(obj._instance, msg='before mock')
+        mock = Mock(spec=obj)
+        self.assertIsNone(obj._instance, msg='after mock')
+        self.assertEqual('object', obj.instance)
+
+    def test_decorated_async_methods_with_spec_mock(self):
+        class Foo():
+            @classmethod
+            async def class_method(cls):
+                pass
+            @staticmethod
+            async def static_method():
+                pass
+            async def method(self):
+                pass
+        mock = Mock(spec=Foo)
+        for m in (mock.method, mock.class_method, mock.static_method):
+            self.assertIsInstance(m, AsyncMock)
 
 if __name__ == '__main__':
     unittest.main()
index 7ca085760650afad5b5fe2ca9b8e890affd50ed3..22f81e55b567f2359a4d9b69fa67bfe459f50a36 100644 (file)
@@ -526,7 +526,13 @@ class NonCallableMock(Base):
             spec_list = dir(spec)
 
             for attr in spec_list:
-                if iscoroutinefunction(getattr(spec, attr, None)):
+                static_attr = inspect.getattr_static(spec, attr, None)
+                unwrapped_attr = static_attr
+                try:
+                    unwrapped_attr = inspect.unwrap(unwrapped_attr)
+                except ValueError:
+                    pass
+                if iscoroutinefunction(unwrapped_attr):
                     _spec_asyncs.append(attr)
 
             spec = spec_list
diff --git a/Misc/NEWS.d/next/Library/2020-09-16-16-53-06.bpo-41768.8_fWkC.rst b/Misc/NEWS.d/next/Library/2020-09-16-16-53-06.bpo-41768.8_fWkC.rst
new file mode 100644 (file)
index 0000000..bfd3a29
--- /dev/null
@@ -0,0 +1,2 @@
+:mod:`unittest.mock` speccing no longer calls class properties.
+Patch by Melanie Witt.