docs: def list_objects(self, path='', relative=False, first_level=False,
                       max_request_entries=None):
          """
          List objects.
  
          Args:
              path (str): Path or URL.
              relative (bool): Path is relative to current root.
              first_level (bool): It True, returns only first level objects.
                  Else, returns full tree.
              max_request_entries (int): If specified, maximum entries returned
                  by request.
  
          Returns:
              generator of tuple: object name str, object header dict
          """
          entries = 0
          max_request_entries_arg = None
  
          if not relative:
              path = self.relpath(path)
  
          # From root
          if not path:
              locators = self._list_locators()
  
              # Yields locators
              if first_level:
                  for locator in locators:
  
                      entries += 1
                      yield locator
                      if entries == max_request_entries:
                          return
                  return
  
              # Yields each locator objects
              for loc_path, loc_header in locators:
  
                  # Yields locator itself
                  loc_path = loc_path.strip('/')
  
                  entries += 1
                  yield loc_path, loc_header
                  if entries == max_request_entries:
                      return
  
                  # Yields locator content is read access to it
                  if max_request_entries is not None:
                      max_request_entries_arg = max_request_entries - entries
                  try:
                      for obj_path, obj_header in self._list_objects(
                              self.get_client_kwargs(loc_path), '',
                              max_request_entries_arg):
  
                          entries += 1
                          yield ('/'.join((loc_path, obj_path.lstrip('/'))),
                                 obj_header)
                          if entries == max_request_entries:
                              return
  
                  except ObjectPermissionError:
                      # No read access to locator
                      continue
              return
  
          # From locator or sub directory
          locator, path = self.split_locator(path)
  
          if first_level:
              seen = set()
  
          if max_request_entries is not None:
              max_request_entries_arg = max_request_entries - entries
  
          for obj_path, header in self._list_objects(
                  self.get_client_kwargs(locator), path, max_request_entries_arg):
  
              if path:
                  try:
                      obj_path = obj_path.split(path, 1)[1]
                  except IndexError:
                      # Not sub path of path
                      continue
              obj_path = obj_path.lstrip('/')
  
              # Skips parent directory
              if not obj_path:
                  continue
  
              # Yields first level locator objects only
              if first_level:
                  # Directory
                  try:
                      obj_path, _ = obj_path.strip('/').split('/', 1)
                      obj_path += '/'
  
                      # Avoids to use the header of the object instead of the
                      # non existing header of the directory that only exists
                      # virtually in object path.
                      header = dict()
  
                  # File
                  except ValueError:
                      pass
  
                  if obj_path not in seen:
                      entries += 1
                      yield obj_path, header
                      if entries == max_request_entries:
                          return
                      seen.add(obj_path)
  
              # Yields locator objects
              else:
                  entries += 1
                  yield obj_path, header
                  if entries == max_request_entries:
                      return