asyncio: Tulip issue 173: Enhance repr(Handle) and repr(Task)

repr(Handle) is shorter for function: "foo" instead of "<function foo at
0x...>". It now also includes the source of the callback, filename and line
number where it was defined, if available.

repr(Task) now also includes the current position in the code, filename and
line number, if available. If the coroutine (generator) is done, the line
number is omitted and "done" is added.
This commit is contained in:
Victor Stinner 2014-06-12 18:39:26 +02:00
parent f54432e2a1
commit 307bccc6ff
5 changed files with 123 additions and 31 deletions

View file

@ -116,21 +116,30 @@ class TaskTests(unittest.TestCase):
yield from []
return 'abc'
filename, lineno = test_utils.get_function_source(notmuch)
src = "%s:%s" % (filename, lineno)
t = asyncio.Task(notmuch(), loop=self.loop)
t.add_done_callback(Dummy())
self.assertEqual(repr(t), 'Task(<notmuch>)<PENDING, [Dummy()]>')
self.assertEqual(repr(t),
'Task(<notmuch at %s>)<PENDING, [Dummy()]>' % src)
t.cancel() # Does not take immediate effect!
self.assertEqual(repr(t), 'Task(<notmuch>)<CANCELLING, [Dummy()]>')
self.assertEqual(repr(t),
'Task(<notmuch at %s>)<CANCELLING, [Dummy()]>' % src)
self.assertRaises(asyncio.CancelledError,
self.loop.run_until_complete, t)
self.assertEqual(repr(t), 'Task(<notmuch>)<CANCELLED>')
self.assertEqual(repr(t),
'Task(<notmuch done at %s>)<CANCELLED>' % filename)
t = asyncio.Task(notmuch(), loop=self.loop)
self.loop.run_until_complete(t)
self.assertEqual(repr(t), "Task(<notmuch>)<result='abc'>")
self.assertEqual(repr(t),
"Task(<notmuch done at %s>)<result='abc'>" % filename)
def test_task_repr_custom(self):
@asyncio.coroutine
def coro():
def notmuch():
pass
class T(asyncio.Future):
@ -141,10 +150,14 @@ class TaskTests(unittest.TestCase):
def __repr__(self):
return super().__repr__()
gen = coro()
gen = notmuch()
t = MyTask(gen, loop=self.loop)
self.assertEqual(repr(t), 'T[](<coro>)')
gen.close()
filename = gen.gi_code.co_filename
lineno = gen.gi_frame.f_lineno
# FIXME: check for the name "coro" instead of "notmuch" because
# @asyncio.coroutine drops the name of the wrapped function:
# http://bugs.python.org/issue21205
self.assertEqual(repr(t), 'T[](<coro at %s:%s>)' % (filename, lineno))
def test_task_basics(self):
@asyncio.coroutine