[Epydoc-commits] SF.net SVN: epydoc: [1448] trunk/epydoc/src/epydoc/apidoc.py
Brought to you by:
edloper
From: <dva...@us...> - 2007-02-11 00:05:36
|
Revision: 1448 http://svn.sourceforge.net/epydoc/?rev=1448&view=rev Author: dvarrazzo Date: 2007-02-10 16:05:34 -0800 (Sat, 10 Feb 2007) Log Message: ----------- - if find() fails, also look for classes name defined in each module and return them if not ambiguous. Modified Paths: -------------- trunk/epydoc/src/epydoc/apidoc.py Modified: trunk/epydoc/src/epydoc/apidoc.py =================================================================== --- trunk/epydoc/src/epydoc/apidoc.py 2007-02-10 22:19:35 UTC (rev 1447) +++ trunk/epydoc/src/epydoc/apidoc.py 2007-02-11 00:05:34 UTC (rev 1448) @@ -1669,8 +1669,31 @@ # Initialize the root items list. We sort them by length in # ascending order. (This ensures that variables will shadow # submodules when appropriate.) - self.root = sorted(root, key=lambda d:len(d.canonical_name)) + # 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 i < len(self.root): + 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. @@ -1789,6 +1812,7 @@ look for the remaining part of the name using C{find} - Builtins - Parameter attributes + - Classes at module level (if the name is not ambiguous) @type name: C{str} or L{DottedName} @type context: L{APIDoc} @@ -1837,6 +1861,57 @@ if all_args is not UNKNOWN and name[0] in all_args: return None + # Is this an object directly contained by any module? + doc = self.mlclasses.get(name[-1]) + if isinstance(doc, APIDoc): + return doc + elif isinstance(doc, list): + log.warning("%s is an ambiguous name: it may be %s" % ( + name[-1], + ", ".join([ "'%s'" % d.canonical_name for d in doc ]))) + + # Drop this item so that the warning is reported only once. + # fail() will fail anyway. + del self.mlclasses[name[-1]] + + def _get_module_classes(self, docs): + """ + Gather all the classes defined in a list of modules. + + Very often people refers to classes only by class name, + even if they are not imported in the namespace. Linking + to such classes will fail if we look for them only in nested + namespaces. Allow them to retrieve only by name. + + @param docs: containers of the objects to collect + @type docs: C{list} of C{APIDoc} + @return: mapping from objects name to the object(s) with that name + @rtype: C{dict} from C{str} to L{ClassDoc} or C{list} + """ + classes = {} + for doc in docs: + if not isinstance(doc, ModuleDoc): + continue + + for var in doc.variables.values(): + if not isinstance(var.value, ClassDoc): + continue + + val = var.value + if val in (None, UNKNOWN) or val.defining_module is not doc: + continue + + name = val.canonical_name[-1] + vals = classes.get(name) + if vals is None: + classes[name] = val + elif not isinstance(vals, list): + classes[name] = [ vals, val ] + else: + vals.append(val) + + return classes + #//////////////////////////////////////////////////////////// # etc #//////////////////////////////////////////////////////////// This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |