code: def _class_info(self, classes, show_builtins, private_bases, parts, aliases, top_classes):
          # type: (List[Any], bool, bool, int, Optional[Dict[unicode, unicode]], List[Any]) -> List[Tuple[unicode, unicode, List[unicode], unicode]]  # NOQA
          
          all_classes = {}
          py_builtins = vars(builtins).values()
  
          def recurse(cls):
              # type: (Any) -> None
              if not show_builtins and cls in py_builtins:
                  return
              if not private_bases and cls.__name__.startswith('_'):
                  return
  
              nodename = self.class_name(cls, parts, aliases)
              fullname = self.class_name(cls, 0, aliases)
  
              # Use first line of docstring as tooltip, if available
              tooltip = None
              try:
                  if cls.__doc__:
                      enc = ModuleAnalyzer.for_module(cls.__module__).encoding
                      doc = cls.__doc__.strip().split("\n")[0]
                      if not isinstance(doc, text_type):
                          doc = force_decode(doc, enc)
                      if doc:
                          tooltip = '"%s"' % doc.replace('"', '\\"')
              except Exception:  # might raise AttributeError for strange classes
                  pass
  
              baselist = []  # type: List[unicode]
              all_classes[cls] = (nodename, fullname, baselist, tooltip)
  
              if fullname in top_classes:
                  return
  
              for base in cls.__bases__:
                  if not show_builtins and base in py_builtins:
                      continue
                  if not private_bases and base.__name__.startswith('_'):
                      continue
                  baselist.append(self.class_name(base, parts, aliases))
                  if base not in all_classes:
                      recurse(base)
  
          for cls in classes:
              recurse(cls)
  
          return list(all_classes.values())
docs: Return name and bases for all classes that are ancestors of
          *classes*.
  
          *parts* gives the number of dotted name parts that is removed from the
          displayed node names.
  
          *top_classes* gives the name(s) of the top most ancestor class to traverse
          to. Multiple names can be specified separated by comma.