-
-
Notifications
You must be signed in to change notification settings - Fork 29.2k
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
unittest.mock.patch decorator doesn't work with async functions #81177
Comments
I came across this while using AsyncMock but it seems to apply to Mock/MagicMock too. When patch decorator is used to wrap an async function to mock sync or async functions it doesn't seem to work. Manually adding patcher or using patch as context manager works. Meanwhile sync_main which is not an async function works fine. Is this an expected behavior with @patch and async def? Does evaluating an async function with asyncio.run has any effect on this? Debugging it tells me the correct object is being replaced with AsyncMock inside patch. import asyncio
from unittest.mock import patch, AsyncMock
mock = AsyncMock()
async def foo():
pass
def bar():
pass @patch(f"{name}.foo", mock) @patch(f"{name}.foo", mock) if __name__ == "__main__":
asyncio.run(main())
sync_main() ./python.exe foo.py |
Thank you very much for raising the question. @patch(...) creates _patch class instance. def __call__(self, func):
if isinstance(func, type):
return self.decorate_class(func)
return self.decorate_callable(func) The code can be modified to def __call__(self, func):
if isinstance(func, type):
return self.decorate_class(func)
if inspect.iscoroutinefunction(func):
return self.decorate_async_func(func)
return self.decorate_callable(func) decorate_async_func can do all the same as decorate_callable with the only difference: internal Pretty straightforward. I did not check the code though. Do want somebody to be a champion? |
Thanks @asvetlov for the explanation. I tried the patch and it works fine for my example with no test failures for mock. I will try to make a PR. Only func(*args, **keywargs) needs to be changed and await requires an async function which I seem to need duplicating the function. I will try if I can refactor that. I will post a PR where this can be discussed. |
I quickly threw in Andrew's code to check it and looks like it does fix the problem. I'd be happy to add it in but I'll give @XTreak first dibs. Thanks for finding this :) |
Oops, didn't see your post. Thanks! |
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:
The text was updated successfully, but these errors were encountered: