docs: def base_elts(elt, cls=None, depth=None):
      """Get bases elements of the input elt.
  
      - If elt is an instance, get class and all base classes.
      - If elt is a method, get all base methods.
      - If elt is a class, get all base classes.
      - In other case, get an empty list.
  
      :param elt: supposed inherited elt.
      :param cls: cls from where find attributes equal to elt. If None,
          it is found as much as possible. Required in python3 for function
          classes.
      :type cls: type or list
      :param int depth: search depth. If None (default), depth is maximal.
      :return: elt bases elements. if elt has not base elements, result is empty.
      :rtype: list
      """
  
      result = []
  
      elt_name = getattr(elt, '__name__', None)
  
      if elt_name is not None:
  
          cls = [] if cls is None else ensureiterable(cls)
  
          elt_is_class = False
  
          # if cls is None and elt is routine, it is possible to find the cls
          if not cls and isroutine(elt):
  
              if hasattr(elt, '__self__'):  # from the instance
  
                  instance = get_method_self(elt)  # get instance
  
                  if instance is None and PY2:  # get base im_class if PY2
                      cls = list(elt.im_class.__bases__)
  
                  else:  # use instance class
                      cls = [instance.__class__]
  
          # cls is elt if elt is a class
          elif isclass(elt):
              elt_is_class = True
              cls = list(elt.__bases__)
  
          if cls:  # if cls is not empty, find all base classes
  
              index_of_found_classes = 0  # get last visited class index
              visited_classes = set(cls)  # cache for visited classes
              len_classes = len(cls)
  
              if depth is None:  # if depth is None, get maximal value
                  depth = -1  # set negative value
  
              while depth != 0 and index_of_found_classes != len_classes:
                  len_classes = len(cls)
  
                  for index in range(index_of_found_classes, len_classes):
                      _cls = cls[index]
  
                      for base_cls in _cls.__bases__:
                          if base_cls in visited_classes:
                              continue
  
                          else:
                              visited_classes.add(base_cls)
                              cls.append(base_cls)
                  index_of_found_classes = len_classes
                  depth -= 1
  
              if elt_is_class:
                  # if cls is elt, result is classes minus first class
                  result = cls
  
              elif isroutine(elt):
  
                  # get an elt to compare with found element
                  if ismethod(elt):
                      elt_to_compare = get_method_function(elt)
                  else:
                      elt_to_compare = elt
  
                  for _cls in cls:  # for all classes
                      # get possible base elt
                      b_elt = getattr(_cls, elt_name, None)
  
                      if b_elt is not None:
                          # compare funcs
                          if ismethod(b_elt):
                              bec = get_method_function(b_elt)
                          else:
                              bec = b_elt
                          # if matching, add to result
                          if bec is elt_to_compare:
                              result.append(b_elt)
  
      return result