Skip to content

Commit f1a297a

Browse files
authored
bpo-37251: Removes __code__ check from _is_async_obj. (GH-15830)
1 parent 5a7d2e1 commit f1a297a

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

Lib/unittest/mock.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,9 @@
4646
_safe_super = super
4747

4848
def _is_async_obj(obj):
49-
if getattr(obj, '__code__', None):
50-
return asyncio.iscoroutinefunction(obj) or inspect.isawaitable(obj)
51-
else:
49+
if _is_instance_mock(obj) and not isinstance(obj, AsyncMock):
5250
return False
51+
return asyncio.iscoroutinefunction(obj) or inspect.isawaitable(obj)
5352

5453

5554
def _is_async_func(func):

Lib/unittest/test/testmock/testasync.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ async def async_method(self):
1818
def normal_method(self):
1919
pass
2020

21+
class AwaitableClass:
22+
def __await__(self):
23+
yield
24+
2125
async def async_func():
2226
pass
2327

@@ -160,6 +164,10 @@ def test_create_autospec_instance(self):
160164
with self.assertRaises(RuntimeError):
161165
create_autospec(async_func, instance=True)
162166

167+
def test_create_autospec_awaitable_class(self):
168+
awaitable_mock = create_autospec(spec=AwaitableClass())
169+
self.assertIsInstance(create_autospec(awaitable_mock), AsyncMock)
170+
163171
def test_create_autospec(self):
164172
spec = create_autospec(async_func_args)
165173
awaitable = spec(1, 2, c=3)
@@ -321,6 +329,13 @@ def test_is_child_AsyncMock(self):
321329
self.assertIsInstance(mock.normal_method, MagicMock)
322330
self.assertIsInstance(mock, MagicMock)
323331

332+
def test_magicmock_lambda_spec(self):
333+
mock_obj = MagicMock()
334+
mock_obj.mock_func = MagicMock(spec=lambda x: x)
335+
336+
with patch.object(mock_obj, "mock_func") as cm:
337+
self.assertIsInstance(cm, MagicMock)
338+
324339

325340
class AsyncArguments(unittest.TestCase):
326341
def test_add_return_value(self):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Remove `__code__` check in AsyncMock that incorrectly
2+
evaluated function specs as async objects but failed to evaluate classes
3+
with `__await__` but no `__code__` attribute defined as async objects.

0 commit comments

Comments
 (0)