summaryrefslogtreecommitdiff
path: root/Lib/asyncio
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/events.py30
-rw-r--r--Lib/asyncio/tasks.py10
-rw-r--r--Lib/asyncio/test_utils.py7
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