code: def add_timeout(
          self,
          deadline: Union[float, datetime.timedelta],
          callback: Callable[..., None],
          *args: Any,
          **kwargs: Any
      ) -> object:
          
          if isinstance(deadline, numbers.Real):
              return self.call_at(deadline, callback, *args, **kwargs)
          elif isinstance(deadline, datetime.timedelta):
              return self.call_at(
                  self.time() + deadline.total_seconds(), callback, *args, **kwargs
              )
          else:
              raise TypeError("Unsupported deadline %r" % deadline)
docs: Runs the ``callback`` at the time ``deadline`` from the I/O loop.
  
          Returns an opaque handle that may be passed to
          `remove_timeout` to cancel.
  
          ``deadline`` may be a number denoting a time (on the same
          scale as `IOLoop.time`, normally `time.time`), or a
          `datetime.timedelta` object for a deadline relative to the
          current time.  Since Tornado 4.0, `call_later` is a more
          convenient alternative for the relative case since it does not
          require a timedelta object.
  
          Note that it is not safe to call `add_timeout` from other threads.
          Instead, you must use `add_callback` to transfer control to the
          `IOLoop`'s thread, and then call `add_timeout` from there.
  
          Subclasses of IOLoop must implement either `add_timeout` or
          `call_at`; the default implementations of each will call
          the other.  `call_at` is usually easier to implement, but
          subclasses that wish to maintain compatibility with Tornado
          versions prior to 4.0 must use `add_timeout` instead.
  
          .. versionchanged:: 4.0
             Now passes through ``*args`` and ``**kwargs`` to the callback.