[Python-checkins] cpython (merge 3.4 -> default): (Merge 3.4) asyncio: Set __qualname__ attribute of CoroWrapper in @coroutine

victor.stinner python-checkins at python.org
Wed Jun 18 01:16:38 CEST 2014


http://hg.python.org/cpython/rev/0773c3c69844
changeset: 91256:0773c3c69844
parent: 91254:a2f115bfa513
parent: 91255:2a8ad880f7bf
user: Victor Stinner <victor.stinner at gmail.com>
date: Wed Jun 18 01:15:27 2014 +0200
summary:
 (Merge 3.4) asyncio: Set __qualname__ attribute of CoroWrapper in @coroutine
decorator on Python 3.5.
- Drop __slots__ optimization of CoroWrapper to be able to set the __qualname__
 attribute.
- Add tests on __name__, __qualname__ and __module__ of a coroutine function
 and coroutine object.
- Fix test_tasks when run in debug mode (PYTHONASYNCIODEBUG env var set) on
 Python 3.3 or 3.4
files:
 Lib/asyncio/tasks.py | 10 ++-
 Lib/test/test_asyncio/test_tasks.py | 48 ++++++++++++++--
 2 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -32,12 +32,12 @@
 _DEBUG = (not sys.flags.ignore_environment
 and bool(os.environ.get('PYTHONASYNCIODEBUG')))
 
+_PY35 = (sys.version_info >= (3, 5))
+
 
 class CoroWrapper:
 # Wrapper for coroutine in _DEBUG mode.
 
- __slots__ = ['gen', 'func', '__name__', '__doc__', '__weakref__']
-
 def __init__(self, gen, func):
 assert inspect.isgenerator(gen), gen
 self.gen = gen
@@ -111,8 +111,10 @@
 @functools.wraps(func)
 def wrapper(*args, **kwds):
 w = CoroWrapper(coro(*args, **kwds), func)
- w.__name__ = coro.__name__
- w.__doc__ = coro.__doc__
+ w.__name__ = func.__name__
+ if _PY35:
+ w.__qualname__ = func.__qualname__
+ w.__doc__ = func.__doc__
 return w
 
 wrapper._is_coroutine = True # For iscoroutinefunction().
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -9,9 +9,13 @@
 from test.script_helper import assert_python_ok
 
 import asyncio
+from asyncio import tasks
 from asyncio import test_utils
 
 
+PY35 = (sys.version_info >= (3, 5))
+
+
 @asyncio.coroutine
 def coroutine_function():
 pass
@@ -117,10 +121,22 @@
 yield from []
 return 'abc'
 
+ self.assertEqual(notmuch.__name__, 'notmuch')
+ if PY35:
+ self.assertEqual(notmuch.__qualname__,
+ 'TaskTests.test_task_repr.<locals>.notmuch')
+ self.assertEqual(notmuch.__module__, __name__)
+
 filename, lineno = test_utils.get_function_source(notmuch)
 src = "%s:%s" % (filename, lineno)
 
- t = asyncio.Task(notmuch(), loop=self.loop)
+ gen = notmuch()
+ self.assertEqual(gen.__name__, 'notmuch')
+ if PY35:
+ self.assertEqual(gen.__qualname__,
+ 'TaskTests.test_task_repr.<locals>.notmuch')
+
+ t = asyncio.Task(gen, loop=self.loop)
 t.add_done_callback(Dummy())
 self.assertEqual(repr(t),
 'Task(<notmuch at %s>)<PENDING, [Dummy()]>' % src)
@@ -143,6 +159,12 @@
 def notmuch():
 pass
 
+ self.assertEqual(notmuch.__name__, 'notmuch')
+ self.assertEqual(notmuch.__module__, __name__)
+ if PY35:
+ self.assertEqual(notmuch.__qualname__,
+ 'TaskTests.test_task_repr_custom.<locals>.notmuch')
+
 class T(asyncio.Future):
 def __repr__(self):
 return 'T[]'
@@ -152,16 +174,26 @@
 return super().__repr__()
 
 gen = notmuch()
+ if PY35 or tasks._DEBUG:
+ # On Python >= 3.5, generators now inherit the name of the
+ # function, as expected, and have a qualified name (__qualname__
+ # attribute). In debug mode, @coroutine decorator uses CoroWrapper
+ # which gets its name (__name__ attribute) from the wrapped
+ # coroutine function.
+ coro_name = 'notmuch'
+ else:
+ # On Python < 3.5, generators inherit the name of the code, not of
+ # the function. See: http://bugs.python.org/issue21205
+ coro_name = 'coro'
+ self.assertEqual(gen.__name__, coro_name)
+ if PY35:
+ self.assertEqual(gen.__qualname__,
+ 'TaskTests.test_task_repr_custom.<locals>.notmuch')
+
 t = MyTask(gen, loop=self.loop)
 filename = gen.gi_code.co_filename
 lineno = gen.gi_frame.f_lineno
- if sys.version_info >= (3, 5):
- name = 'notmuch'
- else:
- # On Python < 3.5, generators inherit the name of the code, not of
- # the function. See: http://bugs.python.org/issue21205
- name = 'coro'
- self.assertEqual(repr(t), 'T[](<%s at %s:%s>)' % (name, filename, lineno))
+ self.assertEqual(repr(t), 'T[](<%s at %s:%s>)' % (coro_name, filename, lineno))
 
 def test_task_basics(self):
 @asyncio.coroutine
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /