def coroutine(func):
 @functools.wraps(func)
 def wrapper(*args, **kwargs):
  runner = None
  future = TracebackFuture()
  if ('callback' in kwargs):
   callback = kwargs.pop('callback')
   IOLoop.current().add_future(future, (lambda future: callback(future.result())))
  def handle_exception(typ, value, tb):
   try:
    if ((runner is not None) and runner.handle_exception(typ, value, tb)):
     return True
   except Exception:
    (typ, value, tb) = sys.exc_info()
   future.set_exc_info((typ, value, tb))
   return True
  with ExceptionStackContext(handle_exception) as deactivate:
   try:
    result = func(*args, **kwargs)
   except (Return, StopIteration) as e:
    result = getattr(e, 'value', None)
   except Exception:
    deactivate()
    future.set_exc_info(sys.exc_info())
    return future
   else:
    if isinstance(result, types.GeneratorType):
     def final_callback(value):
      deactivate()
      future.set_result(value)
     runner = Runner(result, final_callback)
     runner.run()
     return future
   deactivate()
   future.set_result(result)
  return future
 return wrapper

def coroutine ( func ) : @ functools . wraps ( func ) def wrapper ( * args , ** kwargs ) : runner = None future = TracebackFuture ( ) if ( 'callback' in kwargs ) : callback = kwargs . pop ( 'callback' ) IOLoop . current ( ) . add_future ( future , ( lambda future : callback ( future . result ( ) ) ) ) def handle_exception ( typ , value , tb ) : try : if ( ( runner is not None ) and runner . handle_exception ( typ , value , tb ) ) : return True except Exception : ( typ , value , tb ) = sys . exc_info ( ) future . set_exc_info ( ( typ , value , tb ) ) return True with ExceptionStackContext ( handle_exception ) as deactivate : try : result = func ( * args , ** kwargs ) except ( Return , StopIteration ) as e : result = getattr ( e , 'value' , None ) except Exception : deactivate ( ) future . set_exc_info ( sys . exc_info ( ) ) return future else : if isinstance ( result , types . GeneratorType ) : def final_callback ( value ) : deactivate ( ) future . set_result ( value ) runner = Runner ( result , final_callback ) runner . run ( ) return future deactivate ( ) future . set_result ( result ) return future return wrapper
decorator for asynchronous generators .