diff -r c1a7ba57b4ff Lib/asyncio/futures.py --- a/Lib/asyncio/futures.py Thu Dec 12 23:07:40 2013 +0100 +++ b/Lib/asyncio/futures.py Fri Dec 13 01:12:15 2013 +0100 @@ -7,6 +7,7 @@ import concurrent.futures._base import logging +import sys import traceback from . import events @@ -17,6 +18,8 @@ from .log import logger _CANCELLED = 'CANCELLED' _FINISHED = 'FINISHED' +PY34 = sys.version_info >= (3, 4) + # TODO: Do we really want to depend on concurrent.futures internals? Error = concurrent.futures._base.Error CancelledError = concurrent.futures.CancelledError @@ -162,6 +165,12 @@ class Future: res += '<{}>'.format(self._state) return res + if PY34: + def __del__(self): + if self._tb_logger is not None: + logger.error('Future/Task exception was never retrieved:\n%s', + ''.join(self._tb_logger)) + def cancel(self): """Cancel the future and schedule callbacks. @@ -214,9 +223,9 @@ class Future: raise CancelledError if self._state != _FINISHED: raise InvalidStateError('Result is not ready.') - if self._tb_logger is not None: + if not PY34 and 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 @@ -233,9 +242,9 @@ class Future: raise CancelledError if self._state != _FINISHED: raise InvalidStateError('Exception is not set.') - if self._tb_logger is not None: + if not PY34 and 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): @@ -286,12 +295,17 @@ class Future: if self._state != _PENDING: raise InvalidStateError('{}: {!r}'.format(self._state, self)) self._exception = exception - self._tb_logger = _TracebackLogger(exception) self._state = _FINISHED self._schedule_callbacks() - # Arrange for the logger to be activated after all callbacks - # have had a chance to call result() or exception(). - self._loop.call_soon(self._tb_logger.activate) + if PY34: + self._tb_logger = traceback.format_exception(exception.__class__, + exception, + exception.__traceback__) + else: + self._tb_logger = _TracebackLogger(exception) + # Arrange for the logger to be activated after all callbacks + # have had a chance to call result() or exception(). + self._loop.call_soon(self._tb_logger.activate) # Truly internal methods.