summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/futures.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2013-12-20 23:19:33 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2013-12-20 23:19:33 (GMT)
commite40c078627c957892cffab06a33272f1ff9eb216 (patch)
tree3c70ed0e69764d6285c27b72801f5d626ef13278 /Lib/asyncio/futures.py
parent26b80cfde0eb884fc32879c2ffcfeb22d2d91780 (diff)
downloadcpython-e40c078627c957892cffab06a33272f1ff9eb216.zip
cpython-e40c078627c957892cffab06a33272f1ff9eb216.tar.gz
cpython-e40c078627c957892cffab06a33272f1ff9eb216.tar.bz2
Issue #19967: Defer the formating of the traceback in asyncio.Future destructor
Diffstat (limited to 'Lib/asyncio/futures.py')
-rw-r--r--Lib/asyncio/futures.py25
1 files changed, 14 insertions, 11 deletions
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 0188f52..9ee13e3 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -131,8 +131,8 @@ class Future:
_blocking = False # proper use of future (yield vs yield from)
- _traceback = None # Used for Python 3.4 and later
- _tb_logger = None # Used for Python 3.3 only
+ _log_traceback = False # Used for Python 3.4 and later
+ _tb_logger = None # Used for Python 3.3 only
def __init__(self, *, loop=None):
"""Initialize the future.
@@ -168,9 +168,13 @@ class Future:
if _PY34:
def __del__(self):
- if self._traceback is not None:
- logger.error('Future/Task exception was never retrieved:\n%s',
- ''.join(self._traceback))
+ if not self._log_traceback:
+ # set_exception() was not called, or result() or exception()
+ # has consumed the exception
+ return
+ exc = self._exception
+ logger.error('Future/Task exception was never retrieved:',
+ exc_info=(exc.__class__, exc, exc.__traceback__))
def cancel(self):
"""Cancel the future and schedule callbacks.
@@ -224,10 +228,10 @@ class Future:
raise CancelledError
if self._state != _FINISHED:
raise InvalidStateError('Result is not ready.')
- self._traceback = None
+ self._log_traceback = False
if self._tb_logger is not None:
self._tb_logger.clear()
- self._tb_logger = None
+ self._tb_logger = None
if self._exception is not None:
raise self._exception
return self._result
@@ -244,10 +248,10 @@ class Future:
raise CancelledError
if self._state != _FINISHED:
raise InvalidStateError('Exception is not set.')
- self._traceback = None
+ self._log_traceback = False
if self._tb_logger is not None:
self._tb_logger.clear()
- self._tb_logger = None
+ self._tb_logger = None
return self._exception
def add_done_callback(self, fn):
@@ -301,8 +305,7 @@ class Future:
self._state = _FINISHED
self._schedule_callbacks()
if _PY34:
- self._traceback = traceback.format_exception(
- exception.__class__, exception, exception.__traceback__)
+ self._log_traceback = True
else:
self._tb_logger = _TracebackLogger(exception)
# Arrange for the logger to be activated after all callbacks