code: def coroutine(
      func: Union[
          Callable[..., "Generator[Any, Any, _T]"], Callable[..., _T]
      ]
  ) -> Callable[..., "Future[_T]"]:
      """Decorator for asynchronous generators.
  
      For compatibility with older versions of Python, coroutines may
      also "return" by raising the special exception `Return(value)
      <Return>`.
  
      Functions with this decorator return a `.Future`.
  
      .. warning::
  
         When exceptions occur inside a coroutine, the exception
         information will be stored in the `.Future` object. You must
         examine the result of the `.Future` object, or the exception
         may go unnoticed by your code. This means yielding the function
         if called from another coroutine, using something like
         `.IOLoop.run_sync` for top-level calls, or passing the `.Future`
         to `.IOLoop.add_future`.
  
      .. versionchanged:: 6.0
  
         The ``callback`` argument was removed. Use the returned
         awaitable object instead.
  
      """
  
      @functools.wraps(func)
      def wrapper(*args, **kwargs):
          # type: (*Any, **Any) -> Future[_T]
          # This function is type-annotated with a comment to work around
          # https://bitbucket.org/pypy/pypy/issues/2868/segfault-with-args-type-annotation-in
          future = _create_future()
          if contextvars is not None:
              ctx_run = contextvars.copy_context().run  # type: Callable
          else:
              ctx_run = _fake_ctx_run
          try:
              result = ctx_run(func, *args, **kwargs)
          except (Return, StopIteration) as e:
              result = _value_from_stopiteration(e)
          except Exception:
              future_set_exc_info(future, sys.exc_info())
              try:
                  return future
              finally:
                  # Avoid circular references
                  future = None  # type: ignore
          else:
              if isinstance(result, Generator):
                  # 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:
                      yielded = ctx_run(next, result)
                  except (StopIteration, Return) as e:
                      future_set_result_unless_cancelled(
                          future, _value_from_stopiteration(e)
                      )
                  except Exception:
                      future_set_exc_info(future, sys.exc_info())
                  else:
                      # Provide strong references to Runner objects as long
                      # as their result future objects also have strong
                      # references (typically from the parent coroutine's
                      # Runner). This keeps the coroutine's Runner alive.
                      # We do this by exploiting the public API
                      # add_done_callback() instead of putting a private
                      # attribute on the Future.
                      # (GitHub issues #1769, #2229).
                      runner = Runner(ctx_run, result, future, yielded)
                      future.add_done_callback(lambda _: runner)
                  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  # type: ignore
          future_set_result_unless_cancelled(future, result)
          return future
  
      wrapper.__wrapped__ = func  # type: ignore
      wrapper.__tornado_coroutine__ = True  # type: ignore
      return wrapper
  
imports: import asyncio
  import builtins
  import collections
  from collections.abc import Generator
  import concurrent.futures
  import datetime
  import functools
  from functools import singledispatch
  from inspect import isawaitable
  import sys
  import types
  from tornado.concurrent import Future, is_future, chain_future, future_set_exc_info, future_add_done_callback, future_set_result_unless_cancelled
  from tornado.ioloop import IOLoop
  from tornado.log import app_log
  from tornado.util import TimeoutError
  import typing
  from typing import Union, Any, Callable, List, Type, Tuple, Awaitable, Dict, overload
label_desc: Use image node_id 6 for calling a global function with example usage: coroutine(func) and returns: wrapper, future, future, future