except ImportError:
futures = None
+class ReturnValueIgnoredError(Exception):
+ pass
class DummyFuture(object):
def __init__(self):
with ExceptionStackContext(handle_error):
try:
result = f(*args, **kwargs)
+ if result is not None:
+ raise ReturnValueIgnoredError(
+ "@return_future should not be used with functions "
+ "that return values")
except:
exc_info = sys.exc_info()
raise
- assert result is None, ("@return_future should not be used with "
- "functions that return values")
if exc_info is not None:
# If the initial synchronous part of f() raised an exception,
# go ahead and raise it to the caller directly without waiting
import re
import socket
-from tornado.concurrent import Future, return_future
+from tornado.concurrent import Future, return_future, ReturnValueIgnoredError
from tornado.escape import utf8, to_unicode
from tornado import gen
from tornado.iostream import IOStream
def delayed_failure(self, callback):
self.io_loop.add_callback(lambda: 1 / 0)
+ @return_future
+ def return_value(self, callback):
+ # Note that the result of both running the callback and returning
+ # a value (or raising an exception) is unspecified; with current
+ # implementations the last event prior to callback resolution wins.
+ return 42
+
def test_immediate_failure(self):
with self.assertRaises(ZeroDivisionError):
# The caller sees the error just like a normal function.
with self.assertRaises(ZeroDivisionError):
future.result()
+ def test_return_value(self):
+ with self.assertRaises(ReturnValueIgnoredError):
+ self.return_value(callback=self.stop)
+ future = self.wait()
+ with self.assertRaises(ReturnValueIgnoredError):
+ future.result()
+
def test_callback_kw(self):
future = self.sync_future(callback=self.stop)
future2 = self.wait()