-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
All unittest.mock autospec-generated methods are coroutine functions #85794
Comments
Given a class: class Foo:
def bar(self):
pass And an autospec'd mock of it: foo_mock = mock.create_autospec(spec=Foo) The result of asyncio.iscoroutinefunction(Foo.bar) # -> False
asyncio.iscoroutinefunction(foo_mock.bar) # -> True This behavior is the same on Python 3.7 and 3.8. I've attached a demonstration script, repro4.py. Here is the output on Python 3.7.9: $ python3.7 repro4.py
baz is a coroutine function? False
Foo.bar is a coroutine function? False
foo_instance.bar is a coroutine function? False
baz_mock is a coroutine function? False
foo_mock.bar is a coroutine function? True
foo_mock_instance.bar is a coroutine function? True
foo_mock_mock.bar is a coroutine function? False
foo_mock_mock_instance.bar is a coroutine function? False
foo_mock_instance.bar() -> <MagicMock name='mock().bar()' id='140602586963280'>
foo_mock_mock_instance.bar() -> <Mock name='mock().bar()' id='140602587010192'> And on Python 3.8.2: python3.8 repro4.py |
Note that this can interact poorly with AsyncMock, introduced in Python 3.8, because it causes a mock generated from a mock produces an object with async methods rather than regular ones. In Python 3.7 chaining mocks like this would produce regular methods. (This is how I discovered this issue.) |
Got bitten by this issue also. My reproduction, on python 3.12 # misc.py
from asgiref.sync import sync_to_async
class A:
def method1(self):
return 1
async def use_method1():
a = A()
await sync_to_async(a.method1)() # test_misc.py
import inspect
from unittest.mock import patch, _is_async_func
from misc import use_method1
async def test_mock():
await use_method1()
with (
patch("misc.A", autospec=True) as FakeA,
):
assert inspect.isfunction(FakeA.method1)
# FAIL AssertionError
assert not _is_async_func(FakeA.method1)
# FAIL AssertionError
assert not inspect.iscoroutinefunction(FakeA.method1)
# FAIL AssertionError
assert not bool(FakeA.method1.__code__.co_flags & inspect.CO_COROUTINE)
# FAIL raises TypeError: sync_to_async can only be applied to sync functions.
await use_method1() |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs
The text was updated successfully, but these errors were encountered: