docs: def _get_val_list(obj, path_list, reverse=False):
      """Extract values from nested objects by attribute names.
  
      Objects contain attributes which are named references to objects. This will descend
      down a tree of nested objects, starting at the given object, following the given
      path.
  
      Args:
        obj: object
          Any type of object
  
        path_list: list
          Attribute names
  
        reverse: bool
          Reverse the list of values before concatenation.
  
      Returns:
        list of objects
  
      """
      try:
          y = getattr(obj, path_list[0])
      except AttributeError:
          return []
      if len(path_list) == 1:
          return [y]
      else:
          val_list = [x for a in y for x in _get_val_list(a, path_list[1:], reverse)]
          if reverse:
              val_list.reverse()
          return val_list