Skip to content

Commit 78fed8a

Browse files
hauntsaninjacjw296
authored andcommitted
gh-100287: Fix unittest.mock.seal with AsyncMock (#100496)
Backports: e4b43ebb3afbd231a4e5630e7e358aa3093f8677 Signed-off-by: Chris Withers <chris@simplistix.co.uk>
1 parent 36e4a68 commit 78fed8a

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix the interaction of :func:`unittest.mock.seal` with :class:`unittest.mock.AsyncMock`.

mock/mock.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1027,15 +1027,15 @@ def _get_child_mock(self, **kw):
10271027
10281028
For non-callable mocks the callable variant will be used (rather than
10291029
any custom subclass)."""
1030-
_new_name = kw.get("_new_name")
1031-
if _new_name in self.__dict__['_spec_asyncs']:
1032-
return AsyncMock(**kw)
1033-
10341030
if self._mock_sealed:
10351031
attribute = f".{kw['name']}" if "name" in kw else "()"
10361032
mock_name = self._extract_mock_name() + attribute
10371033
raise AttributeError(mock_name)
10381034

1035+
_new_name = kw.get("_new_name")
1036+
if _new_name in self.__dict__['_spec_asyncs']:
1037+
return AsyncMock(**kw)
1038+
10391039
_type = type(self)
10401040
if issubclass(_type, MagicMock) and _new_name in _async_method_magics:
10411041
# Any asynchronous magic becomes an AsyncMock

mock/tests/testasync.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from contextlib import contextmanager
88

99
from mock import (ANY, call, AsyncMock, patch, MagicMock, Mock,
10-
create_autospec, sentinel)
10+
create_autospec, sentinel, seal)
1111
from mock.backports import IsolatedAsyncioTestCase, iscoroutinefunction
1212
from mock.mock import _CallList
1313

@@ -306,6 +306,14 @@ def test_spec_normal_methods_on_class_with_mock(self):
306306
self.assertIsInstance(mock.async_method, AsyncMock)
307307
self.assertIsInstance(mock.normal_method, Mock)
308308

309+
def test_spec_normal_methods_on_class_with_mock_seal(self):
310+
mock = Mock(AsyncClass)
311+
seal(mock)
312+
with self.assertRaises(AttributeError):
313+
mock.normal_method
314+
with self.assertRaises(AttributeError):
315+
mock.async_method
316+
309317
def test_spec_async_attributes_instance(self):
310318
async_instance = AsyncClass()
311319
async_instance.async_func_attr = async_func
@@ -1097,3 +1105,7 @@ async def f(x=None): pass
10971105
)) as cm:
10981106
self.mock.assert_has_awaits([call(), call(1, 2)])
10991107
self.assertIsInstance(cm.exception.__cause__, TypeError)
1108+
1109+
1110+
if __name__ == '__main__':
1111+
unittest.main()

0 commit comments

Comments
 (0)