code: def timecall(fn=None, immediate=True, timer=time.time):
      
      if fn is None: # @timecall() syntax -- we are a decorator maker
          def decorator(fn):
              return timecall(fn, immediate=immediate, timer=timer)
          return decorator
      # @timecall syntax -- we are a decorator.
      fp = FuncTimer(fn, immediate=immediate, timer=timer)
      # We cannot return fp or fp.__call__ directly as that would break method
      # definitions, instead we need to return a plain function.
      def new_fn(*args, **kw):
          return fp(*args, **kw)
      new_fn.__doc__ = fn.__doc__
      new_fn.__name__ = fn.__name__
      new_fn.__dict__ = fn.__dict__
      new_fn.__module__ = fn.__module__
      return new_fn
docs: Wrap `fn` and print its execution time.
  
      Example::
  
          @timecall
          def somefunc(x, y):
              time.sleep(x * y)
  
          somefunc(2, 3)
  
      will print the time taken by somefunc on every call.  If you want just
      a summary at program termination, use
  
          @timecall(immediate=False)
  
      You can also choose a timing method other than the default ``time.time()``,
      e.g.:
  
          @timecall(timer=time.clock)