code: def backoff(
          max_tries=constants.BACKOFF_DEFAULT_MAXTRIES,
          delay=constants.BACKOFF_DEFAULT_DELAY,
          factor=constants.BACKOFF_DEFAULT_FACTOR,
          exceptions=None):
      
      if max_tries <= 0:
          raise ValueError('Max tries must be greater than 0; got {!r}'.format(max_tries))
  
      if delay <= 0:
          raise ValueError('Delay must be greater than 0; got {!r}'.format(delay))
  
      if factor <= 1:
          raise ValueError('Backoff factor must be greater than 1; got {!r}'.format(factor))
  
      def outter(f):
          def inner(*args, **kwargs):
              m_max_tries, m_delay = max_tries, delay # make mutable
              while m_max_tries > 0:
                  try:
                      retval = f(*args, **kwargs)
                  except exceptions:
                      logger.exception('backoff retry for: %r (max_tries=%r, delay=%r, '
                              'factor=%r, exceptions=%r)', f, max_tries, delay, factor, exceptions)
                      m_max_tries -= 1 # consume an attempt
                      if m_max_tries <= 0:
                          raise # run out of tries
                      time.sleep(m_delay) # wait...
                      m_delay *= factor # make future wait longer
                  else:
                      # we're done without errors
                      return retval
          return inner
      return outter
docs: Implements an exponential backoff decorator which will retry decorated
      function upon given exceptions. This implementation is based on
      `Retry <https://wiki.python.org/moin/PythonDecoratorLibrary#Retry>`_ from
      the *Python Decorator Library*.
  
      :param int max_tries: Number of tries before give up. Defaults to
          :const:`~escpos.constants.BACKOFF_DEFAULT_MAXTRIES`.
  
      :param int delay: Delay between retries (in seconds). Defaults to
          :const:`~escpos.constants.BACKOFF_DEFAULT_DELAY`.
  
      :param int factor: Multiply factor in which delay will be increased for the
          next retry. Defaults to :const:`~escpos.constants.BACKOFF_DEFAULT_FACTOR`.
  
      :param exceptions: Tuple of exception types to catch that triggers retry.
          Any exception not listed will break the decorator and retry routines
          will not run.
  
      :type exceptions: tuple[Exception]