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.

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
        """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.
        """
        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())