Skip to content

Commit

Permalink
concurrent: Introduce future_set_exc_info function
Browse files Browse the repository at this point in the history
This function is equivalent to future.set_exc_info for TracebackFuture
but also falls back to set_exception for other Futures.
  • Loading branch information
bdarnell committed Nov 5, 2017
1 parent a42b028 commit 694a5a9
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 24 deletions.
4 changes: 2 additions & 2 deletions tornado/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def get(self):
import time
import uuid

from tornado.concurrent import TracebackFuture, return_future, chain_future
from tornado.concurrent import TracebackFuture, return_future, chain_future, future_set_exc_info
from tornado import gen
from tornado import httpclient
from tornado import escape
Expand Down Expand Up @@ -127,7 +127,7 @@ def handle_exception(typ, value, tb):
if future.done():
return False
else:
future.set_exc_info((typ, value, tb))
future_set_exc_info(future, (typ, value, tb))
return True
with ExceptionStackContext(handle_exception):
f(*args, **kwargs)
Expand Down
25 changes: 20 additions & 5 deletions tornado/concurrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def submit(self, fn, *args, **kwargs):
try:
future.set_result(fn(*args, **kwargs))
except Exception:
future.set_exc_info(sys.exc_info())
future_set_exc_info(future, sys.exc_info())
return future

def shutdown(self, wait=True):
Expand Down Expand Up @@ -466,7 +466,7 @@ def wrapper(*args, **kwargs):
args, kwargs)

def handle_error(typ, value, tb):
future.set_exc_info((typ, value, tb))
future_set_exc_info(future, (typ, value, tb))
return True
exc_info = None
with ExceptionStackContext(handle_error):
Expand Down Expand Up @@ -513,12 +513,27 @@ def copy(future):
assert future is a
if b.done():
return
if (isinstance(a, TracebackFuture) and
isinstance(b, TracebackFuture) and
if (hasattr(a, 'exc_info') and
a.exc_info() is not None):
b.set_exc_info(a.exc_info())
future_set_exc_info(b, a.exc_info())
elif a.exception() is not None:
b.set_exception(a.exception())
else:
b.set_result(a.result())
a.add_done_callback(copy)


def future_set_exc_info(future, exc_info):
"""Set the given ``exc_info`` as the `Future`'s exception.
Understands both `asyncio.Future` and Tornado's extensions to
enable better tracebacks on Python 2.
.. versionadded:: 5.0
"""
if hasattr(future, 'set_exc_info'):
# Tornado's Future
future.set_exc_info(exc_info)
else:
# asyncio.Future
future.set_exception(exc_info[1])
26 changes: 13 additions & 13 deletions tornado/gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def get(self):
import types
import weakref

from tornado.concurrent import Future, TracebackFuture, is_future, chain_future
from tornado.concurrent import Future, TracebackFuture, is_future, chain_future, future_set_exc_info
from tornado.ioloop import IOLoop
from tornado.log import app_log
from tornado import stack_context
Expand Down Expand Up @@ -289,7 +289,7 @@ def wrapper(*args, **kwargs):
except (Return, StopIteration) as e:
result = _value_from_stopiteration(e)
except Exception:
future.set_exc_info(sys.exc_info())
future_set_exc_info(future, sys.exc_info())
return future
else:
if isinstance(result, GeneratorType):
Expand All @@ -310,7 +310,7 @@ def wrapper(*args, **kwargs):
except (StopIteration, Return) as e:
future.set_result(_value_from_stopiteration(e))
except Exception:
future.set_exc_info(sys.exc_info())
future_set_exc_info(future, sys.exc_info())
else:
_futures_to_runners[future] = Runner(result, future, yielded)
yielded = None
Expand Down Expand Up @@ -606,7 +606,7 @@ def Task(func, *args, **kwargs):
def handle_exception(typ, value, tb):
if future.done():
return False
future.set_exc_info((typ, value, tb))
future_set_exc_info(future, (typ, value, tb))
return True

def set_result(result):
Expand Down Expand Up @@ -827,7 +827,7 @@ def callback(f):
app_log.error("Multiple exceptions in yield list",
exc_info=True)
else:
future.set_exc_info(sys.exc_info())
future_set_exc_info(future, sys.exc_info())
if not future.done():
if keys is not None:
future.set_result(dict(zip(keys, result_list)))
Expand Down Expand Up @@ -1019,7 +1019,7 @@ def set_result(self, key, result):
try:
self.future.set_result(self.yield_point.get_result())
except:
self.future.set_exc_info(sys.exc_info())
future_set_exc_info(self.future, sys.exc_info())
self.yield_point = None
self.run()

Expand Down Expand Up @@ -1085,7 +1085,7 @@ def run(self):
except Exception:
self.finished = True
self.future = _null_future
self.result_future.set_exc_info(sys.exc_info())
future_set_exc_info(self.result_future, sys.exc_info())
self.result_future = None
self._deactivate_stack_context()
return
Expand Down Expand Up @@ -1115,8 +1115,8 @@ def start_yield_point():
else:
self.yield_point = yielded
except Exception:
self.future = TracebackFuture()
self.future.set_exc_info(sys.exc_info())
self.future = Future()
future_set_exc_info(self.future, sys.exc_info())

if self.stack_context_deactivate is None:
# Start a stack context if this is the first
Expand All @@ -1136,8 +1136,8 @@ def cb():
try:
self.future = convert_yielded(yielded)
except BadYieldError:
self.future = TracebackFuture()
self.future.set_exc_info(sys.exc_info())
self.future = Future()
future_set_exc_info(self.future, sys.exc_info())

if not self.future.done() or self.future is moment:
def inner(f):
Expand All @@ -1155,8 +1155,8 @@ def result_callback(self, key):

def handle_exception(self, typ, value, tb):
if not self.running and not self.finished:
self.future = TracebackFuture()
self.future.set_exc_info((typ, value, tb))
self.future = Future()
future_set_exc_info(self.future, (typ, value, tb))
self.run()
return True
else:
Expand Down
4 changes: 2 additions & 2 deletions tornado/ioloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
import traceback
import math

from tornado.concurrent import TracebackFuture, is_future, chain_future
from tornado.concurrent import TracebackFuture, is_future, chain_future, future_set_exc_info
from tornado.log import app_log, gen_log
from tornado.platform.auto import set_close_exec, Waker
from tornado import stack_context
Expand Down Expand Up @@ -482,7 +482,7 @@ def run():
result = convert_yielded(result)
except Exception:
future_cell[0] = TracebackFuture()
future_cell[0].set_exc_info(sys.exc_info())
future_set_exc_info(future_cell[0], sys.exc_info())
else:
if is_future(result):
future_cell[0] = result
Expand Down
4 changes: 2 additions & 2 deletions tornado/platform/twisted.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

from zope.interface import implementer # type: ignore

from tornado.concurrent import Future
from tornado.concurrent import Future, future_set_exc_info
from tornado.escape import utf8
from tornado import gen
import tornado.ioloop
Expand Down Expand Up @@ -585,6 +585,6 @@ def errback(failure):
# Should never happen, but just in case
raise Exception("errback called without error")
except:
f.set_exc_info(sys.exc_info())
future_set_exc_info(f, sys.exc_info())
d.addCallbacks(f.set_result, errback)
return f

0 comments on commit 694a5a9

Please sign in to comment.