docs: def advise(self, name, f, *a, **kw):
          """
          Add an advice that will be handled later by the handle method.
  
          Arguments:
  
          name
              The name of the advice group
          f
              A callable method or function.
  
          The rest of the arguments will be passed as arguments and
          keyword arguments to f when it's invoked.
          """
  
          if name is None:
              return
  
          advice = (f, a, kw)
          debug = self.get(DEBUG)
  
          frame = currentframe()
          if frame is None:
              logger.debug('currentframe() failed to return frame')
          else:
              if name in self._called:
                  self.__advice_stack_frame_protection(frame)
              if debug:
                  logger.debug(
                      "advise '%s' invoked by %s:%d",
                      name,
                      frame.f_back.f_code.co_filename, frame.f_back.f_lineno,
                  )
                  if debug > 1:
                      # use the memory address of the tuple which should
                      # be stable
                      self._frames[id(advice)] = ''.join(
                          format_stack(frame.f_back))
  
          self._advices[name] = self._advices.get(name, [])
          self._advices[name].append(advice)