The inner workings of ``@gen.coroutine`` and ``@gen.engine``.

    The two decorators differ in their treatment of the ``callback``
    argument, so we cannot simply implement ``@engine`` in terms of
    ``@coroutine``.
545790
def _make_coroutine_wrapper(func, replace_callback):
    
    # On Python 3.5, set the coroutine flag on our generator, to allow it
    # to be used with 'await'.
    wrapped = func
    if hasattr(types, 'coroutine'):
        func = types.coroutine(func)

    @functools.wraps(wrapped)
    def wrapper(*args, **kwargs):
        future = TracebackFuture()

        if replace_callback and 'callback' in kwargs:
            callback = kwargs.pop('callback')
            IOLoop.current().add_future(
                future, lambda future: callback(future.result()))

        try:
            result = func(*args, **kwargs)
        except (Return, StopIteration) as e:
            result = _value_from_stopiteration(e)
        except Exception:
            future.set_exc_info(sys.exc_info())
            return future
        else:
            if isinstance(result, GeneratorType):
                # Inline the first iteration of Runner.run.  This lets us
                # avoid the cost of creating a Runner when the coroutine
                # never actually yields, which in turn allows us to
                # use "optional" coroutines in critical path code without
                # performance penalty for the synchronous case.
                try:
                    orig_stack_contexts = stack_context._state.contexts
                    yielded = next(result)
                    if stack_context._state.contexts is not orig_stack_contexts:
                        yielded = TracebackFuture()
                        yielded.set_exception(
                            stack_context.StackContextInconsistentError(
                                'stack_context inconsistency (probably caused '
                                'by yield within a "with StackContext" block)'))
                except (StopIteration, Return) as e:
                    future.set_result(_value_from_stopiteration(e))
                except Exception:
                    future.set_exc_info(sys.exc_info())
                else:
                    _futures_to_runners[future] = Runner(result, future, yielded)
                yielded = None
                try:
                    return future
                finally:
                    # Subtle memory optimization: if next() raised an exception,
                    # the future's exc_info contains a traceback which
                    # includes this stack frame.  This creates a cycle,
                    # which will be collected at the next full GC but has
                    # been shown to greatly increase memory usage of
                    # benchmarks (relative to the refcount-based scheme
                    # used in the absence of cycles).  We can avoid the
                    # cycle by clearing the local variable after we return it.
                    future = None
        future.set_result(result)
        return future

    wrapper.__wrapped__ = wrapped
    wrapper.__tornado_coroutine__ = True
    return wrapper
932835
def coroutine(func):
    
    @wraps(func)
    def start(*args, **kwargs):
        g = func(*args, **kwargs)
        next(g)
        return g

    return start
1322122
function genIterator (obj) {
    if (obj) {
        var gen = obj[_.Promise.Symbol.iterator];
        if (_.isFunction(gen)) {
            return gen.call(obj);
        }

        if (obj instanceof Array) {
            return new ArrIter(obj);
        }

        if (_.isFunction(obj.next)) {
            return obj;
        }
    }
    throw new TypeError('invalid_argument');
}
28577
function flow(fn) {
  if (!isGenerator(fn)) {
    throw new Error(NOT_GENERATOR);
  }
  var gen = fn();
  next();
  function next(e, v) {
    var r = e ? gen.throw(e) : gen.next(v);
    if (!r.done) {
      if (isThunk(r.value)) {
        r.value(function(e, v){next(e, v);});
      } else if (isThunkArray(r.value)) {
        parallel(r.value, next);
      } else {
        next(new Error(NOT_THUNK));
      }
    }
  }
}
717551
def _initialize_generator(self,gen,obj=None):
        
        # CEBALERT: use a dictionary to hold these things.
        if hasattr(obj,"_Dynamic_time_fn"):
            gen._Dynamic_time_fn = obj._Dynamic_time_fn

        gen._Dynamic_last = None
        # CEB: I'd use None for this, except can't compare a fixedpoint
        # number with None (e.g. 1>None but FixedPoint(1)>None can't be done)
        gen._Dynamic_time = -1

        gen._saved_Dynamic_last = []
        gen._saved_Dynamic_time = []
364763
def coroutine(f):
    
    @wraps(f)
    def g(*args, **kwargs):
        sink = f(*args, **kwargs)
        sink.send(None)
        return sink

    return g
721957
function async(makeGenerator, callback) {
  return function() {
    const generator = makeGenerator.apply(this, arguments);
    const handle = getHandle(generator, callback);
    try {
      return handle(generator.next());
    } catch(err) {
      return Promise.reject(err);
    }
  };
}
99166
function Engine() {
      var _this;

      var ua = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      var cssFlagsPrefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'engine';

      _classCallCheck(this, Engine);

      _this = _possibleConstructorReturn(this, _getPrototypeOf(Engine).call(this, ua, flags, cssFlagsPrefix));
      _this.version = 'n/a';
      return _this;
    }
1258757
def combine_action_handlers(*handlers):
    
    # make sure each of the given handlers is callable
    for handler in handlers:
        # if the handler is not a function
        if not (iscoroutinefunction(handler) or iscoroutine(handler)):
            # yell loudly
            raise ValueError("Provided handler is not a coroutine: %s" % handler)

    # the combined action handler
    async def combined_handler(*args, **kwds):
        # goes over every given handler
        for handler in handlers:
            # call the handler
            await handler(*args, **kwds)

    # return the combined action handler
    return combined_handler
502257
function co(gen) {
  var ctx = this;
  var args = slice.call(arguments, 1)

  // we wrap everything in a promise to avoid promise chaining,
  // which leads to memory leak errors.
  // see https://github.com/tj/co/issues/180
  return new Promise(function(resolve, reject) {
    if (typeof gen === 'function') gen = gen.apply(ctx, args);
    if (!gen || typeof gen.next !== 'function') return resolve(gen);

    onFulfilled();

    /**
     * @param {Mixed} res
     * @return {Promise}
     * @api private
     */

    function onFulfilled(res) {
      var ret;
      try {
        ret = gen.next(res);
      } catch (e) {
        return reject(e);
      }
      next(ret);
    }

    /**
     * @param {Error} err
     * @return {Promise}
     * @api private
     */

    function onRejected(err) {
      var ret;
      try {
        ret = gen.throw(err);
      } catch (e) {
        return reject(e);
      }
      next(ret);
    }

    /**
     * Get the next value in the generator,
     * return a promise.
     *
     * @param {Object} ret
     * @return {Promise}
     * @api private
     */

    function next(ret) {
      if (ret.done) return resolve(ret.value);
      var value = toPromise.call(ctx, ret.value);
      if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
      return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
        + 'but the following object was passed: "' + String(ret.value) + '"'));
    }
  });
}
789692
def wrap_generator(func):
    

    async def _wrapped(*a, **k):
        r, ret = None, []
        gen = func(*a, **k)
        while True:
            try:
                item = gen.send(r)
            except StopIteration:
                break
            if inspect.isawaitable(item):
                r = await item
            else:
                r = item
            ret.append(r)

        if len(ret) == 1:
            return ret.pop()
        return ret

    return _wrapped
31387
def handle
      return unless engine?
      return if decorators.empty?

      validate_decorators!
      validate_pattern_matching!

      engine.add_method_decorator(method_type, method_name, decorator)
      mark_pattern_matching_decorators
      method_reference.make_alias(target)
      redefine_method
    end
180003
function Engine(options) {
  Options.call(this, options);
  this.views = {};
  this.defaultTemplates();
  this.defaultOptions();

  if (this.enabled('debug')) {
    this.debug();
  }
}
1263146
function createWrapper(fn, ctx) {
  return function() {
    return new Promise(function(resolve, reject) {
      var start = Date.now();

      var cb = function(err) {
        if (err) return reject(err);
        resolve(Date.now() - start);
      };

      // Wrap generator functions
      if (fn && fn.constructor.name === 'GeneratorFunction') {
        fn = Promise.coroutine(fn);
      }

      var res = fn.call(ctx || this, cb);

      // Synchronous spec, or using promises rather than callbacks
      if (!fn.length || (res && res.then)) {
        Promise.resolve(res).then(function() {
          resolve(Date.now() - start);
        }, reject);
      }
    });
  };
}
970334
def _ha_gen_method(func):
        '''  '''
        def wrapped(self, *args, **kw):
            self._reset_retries()
            while(True): # switch between all namenodes
                try:
                    results = func(self, *args, **kw)
                    while(True): # yield all results
                        yield results.next()
                except RequestError as e:
                    self.__handle_request_error(e)
                except socket.error as e:
                    self.__handle_socket_error(e)
        return wrapped
1152546
function shouldRegenerate(node, state) {
  if (node.generator) {
    if (node.async) {
      // Async generator
      return state.opts.asyncGenerators !== false;
    } else {
      // Plain generator
      return state.opts.generators !== false;
    }
  } else if (node.async) {
    // Async function
    return state.opts.async !== false;
  } else {
    // Not a generator or async function.
    return false;
  }
}
622004
def log(fn=None, logger=logging.getLogger(), debug_level=logging.DEBUG):
    
    if fn is None:
        return partial(log, logger=logger, debug_level=debug_level)

    @wraps(fn)
    def func(*args, **kwargs):
        arg_string = ""
        for i in range(0, len(args)):
            var_name = fn.__code__.co_varnames[i]
            if var_name not in ['self', 'cls']:
                arg_string += var_name + ":" + str(args[i]) + ","
        arg_string = arg_string[0:len(arg_string) - 1]
        string = (RED + BOLD + '>> ' + END + 'Calling {0}({1})'.format(fn.__name__, arg_string))
        if len(kwargs):
            string = (
                RED + BOLD + '>> ' + END + 'Calling {0} with args {1} and kwargs {2}'.format(fn.__name__, arg_string,
                                                                                             kwargs))
        logger.log(debug_level, string)
        wrapped_fn = fn
        if not asyncio.iscoroutine(fn):
            wrapped_fn = asyncio.coroutine(fn)
        try:
            result = yield from wrapped_fn(*args, **kwargs)
            string = BLUE + BOLD + '<< ' + END + 'Return {0} with result :{1}'.format(fn.__name__, result)
            logger.log(debug_level, string)
            return result
        except Exception as e:
            string = (RED + BOLD + '>> ' + END + '{0} raised exception :{1}'.format(fn.__name__, str(e)))
            logger.log(debug_level, string)
            raise e

    return func