Skip to content

Instantly share code, notes, and snippets.

@rutsky
Created November 12, 2015 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rutsky/65cee7728135b05d49c3 to your computer and use it in GitHub Desktop.
Save rutsky/65cee7728135b05d49c3 to your computer and use it in GitHub Desktop.
Inconsistent attribute access in asyncio.coroutine in debug mode
"""
$ python3 --version
Python 3.4.3
$ python3 asyncio_debug_attr_access.py
f result
$ PYTHONASYNCIODEBUG=X python3 asyncio_debug_attr_access.py
Traceback (most recent call last):
File "asyncio_debug_attr_access.py", line 21, in <module>
print(loop.run_until_complete(coro_func()))
File "/usr/lib/python3.4/asyncio/coroutines.py", line 154, in wrapper
w.__name__ = func.__name__
File "/usr/lib/python3.4/unittest/mock.py", line 570, in __getattr__
raise AttributeError(name)
AttributeError: __name__
Exception ignored in: $
"""
import asyncio
import contextlib
from unittest.mock import Mock
def f():
return "f result"
if __name__ == "__main__":
loop = asyncio.get_event_loop()
with contextlib.closing(loop):
mocked_f = Mock(wraps=f)
# Mocked function doesn't have special attributes like "__name__"
assert not hasattr(mocked_f, "__name__")
# In Python 3.4 with PYTHONASYNCIODEBUG asyncio.coroutine tries to get
# mocked_f.__name__, which leads to error (looks like this behaviour is
# fixed in Python 3.5).
# Without PYTHONASYNCIODEBUG all works as expected.
coro_func = asyncio.coroutine(mocked_f)
print(loop.run_until_complete(coro_func()))
mocked_f.assert_called_once_with()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment