class Future(object):
+ """Placeholder for an asynchronous result.
+
+ Similar to `concurrent.futures.Future`, but not thread-safe (and
+ therefore faster for use with single-threaded event loops.
+
+ In addition to ``exception`` and ``set_exception``, methods ``exc_info``
+ and ``set_exc_info`` are supported to capture tracebacks in Python 2.
+ The traceback is automatically available in Python 3, but in the
+ Python 2 futures backport this information is discarded.
+ This functionality was previously available in a separate class
+ ``TracebackFuture``, which is now a deprecated alias for this class.
+ """
def __init__(self):
self._done = False
self._result = None
self._exception = None
+ self._exc_info = None
self._callbacks = []
def cancel(self):
return self._done
def result(self, timeout=None):
- self._check_done()
- if self._exception:
+ if self._result is not None:
+ return self._result
+ if self._exc_info is not None:
+ raise_exc_info(self._exc_info)
+ elif self._exception is not None:
raise self._exception
+ self._check_done()
return self._result
def exception(self, timeout=None):
- self._check_done()
- if self._exception:
+ if self._exception is not None:
return self._exception
else:
+ self._check_done()
return None
def add_done_callback(self, fn):
self._exception = exception
self._set_done()
+ def exc_info(self):
+ return self._exc_info
+
+ def set_exc_info(self, exc_info):
+ """Traceback-aware replacement for
+ `~concurrent.futures.Future.set_exception`.
+ """
+ self._exc_info = exc_info
+ self.set_exception(exc_info[1])
+
def _check_done(self):
if not self._done:
raise Exception("DummyFuture does not support blocking for results")
cb(self)
self._callbacks = None
+TracebackFuture = Future
if futures is None:
FUTURES = Future
def is_future(x):
return isinstance(x, FUTURES)
-class TracebackFuture(Future):
- """Subclass of `Future` which can store a traceback with
- exceptions.
-
- The traceback is automatically available in Python 3, but in the
- Python 2 futures backport this information is discarded.
- """
- def __init__(self):
- super(TracebackFuture, self).__init__()
- self.__exc_info = None
-
- def exc_info(self):
- return self.__exc_info
-
- def set_exc_info(self, exc_info):
- """Traceback-aware replacement for
- `~concurrent.futures.Future.set_exception`.
- """
- self.__exc_info = exc_info
- self.set_exception(exc_info[1])
-
- def result(self, timeout=None):
- if self.__exc_info is not None:
- raise_exc_info(self.__exc_info)
- else:
- return super(TracebackFuture, self).result(timeout=timeout)
-
class DummyExecutor(object):
def submit(self, fn, *args, **kwargs):