code: def decorate(func, caller, extras=()):
      """
      decorate(func, caller) decorates a function using a caller.
      If the caller is a generator function, the resulting function
      will be a generator function.
      """
      evaldict = dict(_call_=caller, _func_=func)
      es = ""
      for i, extra in enumerate(extras):
          ex = "_e%d_" % i
          evaldict[ex] = extra
          es += ex + ", "
  
      if "3.5" <= sys.version < "3.6":
          # with Python 3.5 isgeneratorfunction returns True for all coroutines
          # however we know that it is NOT possible to have a generator
          # coroutine in python 3.5: PEP525 was not there yet
          generatorcaller = isgeneratorfunction(
              caller
          ) and not iscoroutinefunction(caller)
      else:
          generatorcaller = isgeneratorfunction(caller)
      if generatorcaller:
          fun = FunctionMaker.create(
              func,
              "for res in _call_(_func_, %s%%(shortsignature)s):\n"
              "    yield res" % es,
              evaldict,
              __wrapped__=func,
          )
      else:
          fun = FunctionMaker.create(
              func,
              "return _call_(_func_, %s%%(shortsignature)s)" % es,
              evaldict,
              __wrapped__=func,
          )
      if hasattr(func, "__qualname__"):
          fun.__qualname__ = func.__qualname__
      return fun
  
imports: from __future__ import print_function
  import re
  import sys
  import inspect
  import operator
  import itertools
  import collections
label_desc: Use image node_id 1 for calling a global function with example usage: decorate(func, caller, extras) and returns: fun