mirror of
https://github.com/python/cpython.git
synced 2025-08-26 19:55:24 +00:00
asyncio, Tulip issue 137: In debug mode, save traceback where Future, Task and
Handle objects are created. Pass the traceback to call_exception_handler() in the 'source_traceback' key. The traceback is truncated to hide internal calls in asyncio, show only the traceback from user code. Add tests for the new source_traceback, and a test for the 'Future/Task exception was never retrieved' log.
This commit is contained in:
parent
bbd96c6f47
commit
80f53aa9a0
8 changed files with 180 additions and 26 deletions
|
@ -195,6 +195,8 @@ class Task(futures.Future):
|
|||
def __init__(self, coro, *, loop=None):
|
||||
assert iscoroutine(coro), repr(coro) # Not a coroutine function!
|
||||
super().__init__(loop=loop)
|
||||
if self._source_traceback:
|
||||
del self._source_traceback[-1]
|
||||
self._coro = iter(coro) # Use the iterator just in case.
|
||||
self._fut_waiter = None
|
||||
self._must_cancel = False
|
||||
|
@ -207,10 +209,13 @@ class Task(futures.Future):
|
|||
if _PY34:
|
||||
def __del__(self):
|
||||
if self._state == futures._PENDING:
|
||||
self._loop.call_exception_handler({
|
||||
context = {
|
||||
'task': self,
|
||||
'message': 'Task was destroyed but it is pending!',
|
||||
})
|
||||
}
|
||||
if self._source_traceback:
|
||||
context['source_traceback'] = self._source_traceback
|
||||
self._loop.call_exception_handler(context)
|
||||
futures.Future.__del__(self)
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -620,7 +625,10 @@ def async(coro_or_future, *, loop=None):
|
|||
raise ValueError('loop argument must agree with Future')
|
||||
return coro_or_future
|
||||
elif iscoroutine(coro_or_future):
|
||||
return Task(coro_or_future, loop=loop)
|
||||
task = Task(coro_or_future, loop=loop)
|
||||
if task._source_traceback:
|
||||
del task._source_traceback[-1]
|
||||
return task
|
||||
else:
|
||||
raise TypeError('A Future or coroutine is required')
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue