def return_future(f):
 replacer = ArgReplacer(f, 'callback')
 @functools.wraps(f)
 def wrapper(*args, **kwargs):
  future = TracebackFuture()
  (callback, args, kwargs) = replacer.replace((lambda value=_NO_RESULT: future.set_result(value)), args, kwargs)
  def handle_error(typ, value, tb):
   future.set_exc_info((typ, value, tb))
   return True
  exc_info = None
  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
  if (exc_info is not None):
   future.result()
  if (callback is not None):
   def run_callback(future):
    result = future.result()
    if (result is _NO_RESULT):
     callback()
    else:
     callback(future.result())
   future.add_done_callback(wrap(run_callback))
  return future
 return wrapper

def return_future ( f ) : replacer = ArgReplacer ( f , 'callback' ) @ functools . wraps ( f ) def wrapper ( * args , ** kwargs ) : future = TracebackFuture ( ) ( callback , args , kwargs ) = replacer . replace ( ( lambda value = _NO_RESULT : future . set_result ( value ) ) , args , kwargs ) def handle_error ( typ , value , tb ) : future . set_exc_info ( ( typ , value , tb ) ) return True exc_info = None 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 if ( exc_info is not None ) : future . result ( ) if ( callback is not None ) : def run_callback ( future ) : result = future . result ( ) if ( result is _NO_RESULT ) : callback ( ) else : callback ( future . result ( ) ) future . add_done_callback ( wrap ( run_callback ) ) return future return wrapper
decorator to make a function that returns via callback return a future .