return wrapper
+_NO_RESULT = object()
+
def return_future(f):
"""Decorator to make a function that returns via callback return a `Future`.
def wrapper(*args, **kwargs):
future = Future()
callback, args, kwargs = replacer.replace(
- lambda value=None: future.set_result(value),
+ lambda value=_NO_RESULT: future.set_result(value),
args, kwargs)
def handle_error(typ, value, tb):
# the callback triggers its exception by calling future.result()).
if callback is not None:
def run_callback(future):
- callback(future.result())
+ result = future.result()
+ if result is _NO_RESULT:
+ callback()
+ else:
+ callback(future.result())
future.add_done_callback(wrap(run_callback))
return future
return wrapper
self.assertRaises(ZeroDivisionError, self.wait)
def test_no_result_future(self):
- self.no_result_future(self.stop)
+ future = self.no_result_future(self.stop)
result = self.wait()
self.assertIs(result, None)
+ # result of this future is undefined, but not an error
+ future.result()
+
+ def test_no_result_future_callback(self):
+ future = self.no_result_future(callback=lambda: self.stop())
+ result = self.wait()
+ self.assertIs(result, None)
+ future.result()
# The following series of classes demonstrate and test various styles
# of use, with and without generators and futures.