code: def return_future(f):
      """Decorator to make a function that returns via callback return a
      `Future`.
  
      The wrapped function should take a ``callback`` keyword argument
      and invoke it with one argument when it has finished.  To signal failure,
      the function can simply raise an exception (which will be
      captured by the `.StackContext` and passed along to the ``Future``).
  
      From the caller's perspective, the callback argument is optional.
      If one is given, it will be invoked when the function is complete
      with `Future.result()` as an argument.  If the function fails, the
      callback will not be run and an exception will be raised into the
      surrounding `.StackContext`.
  
      If no callback is given, the caller should use the ``Future`` to
      wait for the function to complete (perhaps by yielding it in a
      `.gen.engine` function, or passing it to `.IOLoop.add_future`).
  
      Usage:
  
      .. testcode::
  
          @return_future
          def future_func(arg1, arg2, callback):
              # Do stuff (possibly asynchronous)
              callback(result)
  
          @gen.engine
          def caller(callback):
              yield future_func(arg1, arg2)
              callback()
  
      ..
  
      Note that ``@return_future`` and ``@gen.engine`` can be applied to the
      same function, provided ``@return_future`` appears first.  However,
      consider using ``@gen.coroutine`` instead of this combination.
      """
      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:
              # If the initial synchronous part of f() raised an exception,
              # go ahead and raise it to the caller directly without waiting
              # for them to inspect the Future.
              future.result()
  
          # If the caller passed in a callback, schedule it to be called
          # when the future resolves.  It is important that this happens
          # just before we return the future, or else we risk confusing
          # stack contexts with multiple exceptions (one here with the
          # immediate exception, and again when the future resolves and
          # the callback triggers its exception by calling 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
  
imports: from __future__ import absolute_import, division, print_function
  import functools
  import platform
  import textwrap
  import traceback
  import sys
  from tornado.log import app_log
  from tornado.stack_context import ExceptionStackContext, wrap
  from tornado.util import raise_exc_info, ArgReplacer, is_finalizing
label_desc: Use image node_id 3 for calling a global function with example usage: return_future(f) and returns: wrapper, future, True