mirror of
https://github.com/python/cpython.git
synced 2025-10-17 20:28:43 +00:00
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:
parent
f54432e2a1
commit
307bccc6ff
5 changed files with 123 additions and 31 deletions
|
@ -5,6 +5,7 @@ import gc
|
|||
import io
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import signal
|
||||
import socket
|
||||
try:
|
||||
|
@ -1737,52 +1738,46 @@ else:
|
|||
return asyncio.SelectorEventLoop(selectors.SelectSelector())
|
||||
|
||||
|
||||
def noop():
|
||||
pass
|
||||
|
||||
|
||||
class HandleTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.loop = None
|
||||
|
||||
def test_handle(self):
|
||||
def callback(*args):
|
||||
return args
|
||||
|
||||
args = ()
|
||||
h = asyncio.Handle(callback, args, mock.Mock())
|
||||
h = asyncio.Handle(callback, args, self.loop)
|
||||
self.assertIs(h._callback, callback)
|
||||
self.assertIs(h._args, args)
|
||||
self.assertFalse(h._cancelled)
|
||||
|
||||
r = repr(h)
|
||||
self.assertTrue(r.startswith(
|
||||
'Handle('
|
||||
'<function HandleTests.test_handle.<locals>.callback'))
|
||||
self.assertTrue(r.endswith('())'))
|
||||
|
||||
h.cancel()
|
||||
self.assertTrue(h._cancelled)
|
||||
|
||||
r = repr(h)
|
||||
self.assertTrue(r.startswith(
|
||||
'Handle('
|
||||
'<function HandleTests.test_handle.<locals>.callback'))
|
||||
self.assertTrue(r.endswith('())<cancelled>'), r)
|
||||
|
||||
def test_handle_from_handle(self):
|
||||
def callback(*args):
|
||||
return args
|
||||
m_loop = object()
|
||||
h1 = asyncio.Handle(callback, (), loop=m_loop)
|
||||
h1 = asyncio.Handle(callback, (), loop=self.loop)
|
||||
self.assertRaises(
|
||||
AssertionError, asyncio.Handle, h1, (), m_loop)
|
||||
AssertionError, asyncio.Handle, h1, (), self.loop)
|
||||
|
||||
def test_callback_with_exception(self):
|
||||
def callback():
|
||||
raise ValueError()
|
||||
|
||||
m_loop = mock.Mock()
|
||||
m_loop.call_exception_handler = mock.Mock()
|
||||
self.loop = mock.Mock()
|
||||
self.loop.call_exception_handler = mock.Mock()
|
||||
|
||||
h = asyncio.Handle(callback, (), m_loop)
|
||||
h = asyncio.Handle(callback, (), self.loop)
|
||||
h._run()
|
||||
|
||||
m_loop.call_exception_handler.assert_called_with({
|
||||
self.loop.call_exception_handler.assert_called_with({
|
||||
'message': test_utils.MockPattern('Exception in callback.*'),
|
||||
'exception': mock.ANY,
|
||||
'handle': h
|
||||
|
@ -1790,9 +1785,50 @@ class HandleTests(unittest.TestCase):
|
|||
|
||||
def test_handle_weakref(self):
|
||||
wd = weakref.WeakValueDictionary()
|
||||
h = asyncio.Handle(lambda: None, (), object())
|
||||
h = asyncio.Handle(lambda: None, (), self.loop)
|
||||
wd['h'] = h # Would fail without __weakref__ slot.
|
||||
|
||||
def test_repr(self):
|
||||
# simple function
|
||||
h = asyncio.Handle(noop, (), self.loop)
|
||||
src = test_utils.get_function_source(noop)
|
||||
self.assertEqual(repr(h),
|
||||
'Handle(noop at %s:%s, ())' % src)
|
||||
|
||||
# cancelled handle
|
||||
h.cancel()
|
||||
self.assertEqual(repr(h),
|
||||
'Handle(noop at %s:%s, ())<cancelled>' % src)
|
||||
|
||||
# decorated function
|
||||
cb = asyncio.coroutine(noop)
|
||||
h = asyncio.Handle(cb, (), self.loop)
|
||||
self.assertEqual(repr(h),
|
||||
'Handle(noop at %s:%s, ())' % src)
|
||||
|
||||
# partial function
|
||||
cb = functools.partial(noop)
|
||||
h = asyncio.Handle(cb, (), self.loop)
|
||||
filename, lineno = src
|
||||
regex = (r'^Handle\(functools.partial\('
|
||||
r'<function noop .*>\) at %s:%s, '
|
||||
r'\(\)\)$' % (re.escape(filename), lineno))
|
||||
self.assertRegex(repr(h), regex)
|
||||
|
||||
# partial method
|
||||
if sys.version_info >= (3, 4):
|
||||
method = HandleTests.test_repr
|
||||
cb = functools.partialmethod(method)
|
||||
src = test_utils.get_function_source(method)
|
||||
h = asyncio.Handle(cb, (), self.loop)
|
||||
|
||||
filename, lineno = src
|
||||
regex = (r'^Handle\(functools.partialmethod\('
|
||||
r'<function HandleTests.test_repr .*>, , \) at %s:%s, '
|
||||
r'\(\)\)$' % (re.escape(filename), lineno))
|
||||
self.assertRegex(repr(h), regex)
|
||||
|
||||
|
||||
|
||||
class TimerTests(unittest.TestCase):
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue