Kaydet (Commit) 830b43d0 authored tarafından Xtreak's avatar Xtreak Kaydeden (comit) Pablo Galindo

bpo-36593: Fix isinstance check for Mock objects with spec executed under tracing (GH-12790)

In Python having a trace function in effect while mock is imported causes isinstance to be wrong for MagicMocks. This is due to the usage of super() in some class methods, as this sets the __class__ attribute. To avoid this, as a workaround, alias the usage of super .
üst fde9b33d
...@@ -739,7 +739,7 @@ class NonCallableMock(Base): ...@@ -739,7 +739,7 @@ class NonCallableMock(Base):
obj = self._mock_children.get(name, _missing) obj = self._mock_children.get(name, _missing)
if name in self.__dict__: if name in self.__dict__:
super().__delattr__(name) _safe_super(NonCallableMock, self).__delattr__(name)
elif obj is _deleted: elif obj is _deleted:
raise AttributeError(name) raise AttributeError(name)
if obj is not _missing: if obj is not _missing:
......
...@@ -1847,6 +1847,44 @@ class MockTest(unittest.TestCase): ...@@ -1847,6 +1847,44 @@ class MockTest(unittest.TestCase):
self.assertRaises(TypeError, mock.child, 1) self.assertRaises(TypeError, mock.child, 1)
self.assertEqual(mock.mock_calls, [call.child(1, 2)]) self.assertEqual(mock.mock_calls, [call.child(1, 2)])
def test_isinstance_under_settrace(self):
# bpo-36593 : __class__ is not set for a class that has __class__
# property defined when it's used with sys.settrace(trace) set.
# Delete the module to force reimport with tracing function set
# restore the old reference later since there are other tests that are
# dependent on unittest.mock.patch. In testpatch.PatchTest
# test_patch_dict_test_prefix and test_patch_test_prefix not restoring
# causes the objects patched to go out of sync
old_patch = unittest.mock.patch
# Directly using __setattr__ on unittest.mock causes current imported
# reference to be updated. Use a lambda so that during cleanup the
# re-imported new reference is updated.
self.addCleanup(lambda patch: setattr(unittest.mock, 'patch', patch),
old_patch)
with patch.dict('sys.modules'):
del sys.modules['unittest.mock']
def trace(frame, event, arg):
return trace
sys.settrace(trace)
self.addCleanup(sys.settrace, None)
from unittest.mock import (
Mock, MagicMock, NonCallableMock, NonCallableMagicMock
)
mocks = [
Mock, MagicMock, NonCallableMock, NonCallableMagicMock
]
for mock in mocks:
obj = mock(spec=Something)
self.assertIsInstance(obj, Something)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Fix ``isinstance`` check for Mock objects with spec when the code is
executed under tracing. Patch by Karthikeyan Singaravelan.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment