code: def retry_loop(self, context, step_method):
          
          logger.debug("starting")
  
          context['retryCounter'] = 0
  
          sleep = context.get_formatted_as_type(self.sleep, out_type=float)
          if self.max:
              max = context.get_formatted_as_type(self.max, out_type=int)
  
              logger.info(f"retry decorator will try {max} times at {sleep}s "
                          "intervals.")
          else:
              max = None
              logger.info(f"retry decorator will try indefinitely at {sleep}s "
                          "intervals.")
  
          # this will never be false. because on counter == max,
          # exec_iteration raises an exception, breaking out of the loop.
          # pragma because cov doesn't know the implied else is impossible.
          # unit test cov is 100%, though.
          if poll.while_until_true(interval=sleep,
                                   max_attempts=max)(
                  self.exec_iteration)(context=context,
                                       step_method=step_method
                                       ):  # pragma: no cover
              logger.debug("retry loop complete, reporting success.")
  
          logger.debug("retry loop done")
  
          logger.debug("done")
docs: Run step inside a retry loop.
  
          Args:
              context: (pypyr.context.Context) The pypyr context. This arg will
                       mutate - after method execution will contain the new
                       updated context.
              step_method: (method/function) This is the method/function that
                           will execute on every loop iteration. Signature is:
                           function(context)