[issue37251] Mocking a MagicMock with a function spec results in an AsyncMock

Lisa Roach report at bugs.python.org
Wed Jun 19 20:21:24 EDT 2019


Lisa Roach <lisaroach14 at gmail.com> added the comment:

Thanks for the patch!

To answer your question, I do not think we can remove _is_async_func in favor of _is_async_obj, _is_async_obj will evaluate to True in cases where _is_async_func would not. 

For example:

>>> class NewCoroutine(Awaitable):
...     def __await__():
...         pass
...
>>> c = NewCoroutine()
>>> import inspect
>>> inspect.isawaitable(c)
True
>>> inspect.iscoroutinefunction(c)
False


BUT I think removing the `if getattr(obj, '__code__', None)` from `_is_async_obj` actually makes this work correctly. It is possible for a coroutine object to not have a __code__, but I don't think it is possible for a coroutine function to be missing a __code__. 

Before removing the __code__ check:

>>> from unittest.mock import _is_async_func, _is_async_obj
>>> import asyncio
>>> _is_async_obj(asyncio.sleep(1))
<stdin>:1: RuntimeWarning: coroutine 'sleep' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
False
>>> _is_async_func(asyncio.sleep(1))
False

_is_async_obj evaluates to False when it should be True

After removing it:

>>> from unittest.mock import _is_async_func, _is_async_obj
>>> import asyncio
>>> _is_async_obj(asyncio.sleep(1))
<stdin>:1: RuntimeWarning: coroutine 'sleep' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
True
>>> _is_async_func(asyncio.sleep(1))
False

It correctly evaluates to True

All tests pass as well. What do you think?

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue37251>
_______________________________________


More information about the Python-bugs-list mailing list