diff options
Diffstat (limited to 'Lib/asyncio')
-rw-r--r-- | Lib/asyncio/events.py | 30 | ||||
-rw-r--r-- | Lib/asyncio/tasks.py | 10 | ||||
-rw-r--r-- | Lib/asyncio/test_utils.py | 7 |
3 files changed, 45 insertions, 2 deletions
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 4a9a9a3885..de161df65f 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -8,9 +8,29 @@ __all__ = ['AbstractEventLoopPolicy', 'get_child_watcher', 'set_child_watcher', ] +import functools +import inspect import subprocess import threading import socket +import sys + + +_PY34 = sys.version_info >= (3, 4) + +def _get_function_source(func): + if _PY34: + func = inspect.unwrap(func) + elif hasattr(func, '__wrapped__'): + func = func.__wrapped__ + if inspect.isfunction(func): + code = func.__code__ + return (code.co_filename, code.co_firstlineno) + if isinstance(func, functools.partial): + return _get_function_source(func.func) + if _PY34 and isinstance(func, functools.partialmethod): + return _get_function_source(func.func) + return None class Handle: @@ -26,7 +46,15 @@ class Handle: self._cancelled = False def __repr__(self): - res = 'Handle({}, {})'.format(self._callback, self._args) + cb_repr = getattr(self._callback, '__qualname__', None) + if not cb_repr: + cb_repr = str(self._callback) + + source = _get_function_source(self._callback) + if source: + cb_repr += ' at %s:%s' % source + + res = 'Handle({}, {})'.format(cb_repr, self._args) if self._cancelled: res += '<cancelled>' return res diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 8b8fb82ed2..e6fd3d380b 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -188,7 +188,15 @@ class Task(futures.Future): i = res.find('<') if i < 0: i = len(res) - res = res[:i] + '(<{}>)'.format(self._coro.__name__) + res[i:] + text = self._coro.__name__ + coro = self._coro + if inspect.isgenerator(coro): + filename = coro.gi_code.co_filename + if coro.gi_frame is not None: + text += ' at %s:%s' % (filename, coro.gi_frame.f_lineno) + else: + text += ' done at %s' % filename + res = res[:i] + '(<{}>)'.format(text) + res[i:] return res def get_stack(self, *, limit=None): diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py index 9c3656ac2b..1062bae132 100644 --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -372,3 +372,10 @@ class MockPattern(str): """ def __eq__(self, other): return bool(re.search(str(self), other, re.S)) + + +def get_function_source(func): + source = events._get_function_source(func) + if source is None: + raise ValueError("unable to get the source of %r" % (func,)) + return source |