def __init__(self, root):
        """
        Create a new documentation index, based on the given root set
        of C{ValueDoc}s.  If any C{APIDoc}s reachable from the root
        set does not have a canonical name, then it will be assigned
        one.  etc.
        
        @param root: A list of C{ValueDoc}s.
        """
        for apidoc in root:
            if apidoc.canonical_name in (None, UNKNOWN):
                raise ValueError("All APIdocs passed to DocIndexer "
                                 "must already have canonical names.")
        
        # Initialize the root items list.  We sort them by length in
        # ascending order.  (This ensures that variables will shadow
        # submodules when appropriate.)
        # When the elements name is the same, list in alphabetical order:
        # this is needed by the check for duplicates below.
        self.root = sorted(root,
            key=lambda d: (len(d.canonical_name), d.canonical_name))
        """The list of C{ValueDoc}s to document.
            @type: C{list}"""

        # Drop duplicated modules
        # [xx] maybe what causes duplicates should be fixed instead.
        #      If fixed, adjust the sort here above: sorting by names will not
        #      be required anymore
        i = 1
        while len(self.root) < i:
            if self.root[i-1] is self.root[i]:
                del self.root[i]
            else:
                i += 1

        self.mlclasses = self._get_module_classes(self.root)
        """A mapping from class names to L{ClassDoc}. Contains
           classes defined at module level for modules in L{root}
           and which can be used as fallback by L{find()} if looking
           in containing namespaces fails.
           @type: C{dict} from C{str} to L{ClassDoc} or C{list}"""

        self.callers = None
        """A dictionary mapping from C{RoutineDoc}s in this index
           to lists of C{RoutineDoc}s for the routine's callers.
           This dictionary is initialized by calling
           L{read_profiling_info()}.
           @type: C{list} of L{RoutineDoc}"""
        
        self.callees = None
        """A dictionary mapping from C{RoutineDoc}s in this index
           to lists of C{RoutineDoc}s for the routine's callees.
           This dictionary is initialized by calling
           L{read_profiling_info()}.
           @type: C{list} of L{RoutineDoc}"""

        self._funcid_to_doc = {}
        """A mapping from C{profile} function ids to corresponding
           C{APIDoc} objects.  A function id is a tuple of the form
           C{(filename, lineno, funcname)}.  This is used to update
           the L{callers} and L{callees} variables."""

        self._container_cache = {}
        """A cache for the L{container()} method, to increase speed."""

        self._get_cache = {}
        """A cache for the L{get_vardoc()} and L{get_valdoc()} methods,
        to increase speed."""

    #////////////////////////////////////////////////////////////
    # Lookup methods
    #////////////////////////////////////////////////////////////
    # [xx]
    # Currently these only work for things reachable from the
    # root... :-/  I might want to change this so that imported
    # values can be accessed even if they're not contained.  
    # Also, I might want canonical names to not start with ??
    # if the thing is a top-level imported module..?
dataset/ETHPy150Open ardekantur/pyglet/tools/epydoc/epydoc/apidoc.py/DocIndex.__init__/swapped operands of `<`