diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 7400fb7..aeea2aa 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -2199,6 +2199,15 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, except AttributeError: continue + # If our autospeccing already created this attribute through + # _setup_func above, skip it! + if ( + hasattr(mock, entry) and + hasattr(spec, 'mock') and + hasattr(spec.mock, '_mock_delegate') + ): + continue + kwargs = {'spec': original} if spec_set: kwargs = {'spec_set': original} diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py index dfce369..62fdca2 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/unittest/test/testmock/testpatch.py @@ -1843,5 +1843,23 @@ class PatchTest(unittest.TestCase): self.assertEqual(foo(), 1) self.assertEqual(foo(), 0) + + def test_double_patch_instance_method(self): + # See http://bugs.python.org/issue26704 + class C: + def f(self): + pass + + c = C() + + with patch.object(c, 'f', autospec=True) as patch1: + with patch.object(c, 'f', autospec=True) as patch2: + c.f() + self.assertEqual(patch2.call_count, 1) + self.assertEqual(patch1.call_count, 0) + c.f() + self.assertEqual(patch1.call_count, 1) + + if __name__ == '__main__': unittest.main()