Thread: [Epydoc-commits] SF.net SVN: epydoc: [1180] trunk/epydoc/src/epydoc/checker.py
Brought to you by:
edloper
From: <ed...@us...> - 2006-04-07 01:02:12
|
Revision: 1180 Author: edloper Date: 2006-04-06 18:02:08 -0700 (Thu, 06 Apr 2006) ViewCVS: http://svn.sourceforge.net/epydoc/?rev=1180&view=rev Log Message: ----------- - Updated to work with epydoc 3.0 Modified Paths: -------------- trunk/epydoc/src/epydoc/checker.py Modified: trunk/epydoc/src/epydoc/checker.py =================================================================== --- trunk/epydoc/src/epydoc/checker.py 2006-04-06 04:35:12 UTC (rev 1179) +++ trunk/epydoc/src/epydoc/checker.py 2006-04-07 01:02:08 UTC (rev 1180) @@ -28,26 +28,12 @@ # versions: _NO_BASIC = ['__hash__', '__repr__', '__str__', '__cmp__'] -# The following methods never need return values: -_NO_RETURN = ['__init__', '__hash__', '__repr__', '__str__', - '__cmp__'] +# The following methods never need return value descriptions. +_NO_RETURN = ['__init__', '__hash__', '__repr__', '__str__', '__cmp__'] # The following methods don't need parameters documented: _NO_PARAM = ['__cmp__'] -def _is_private(str): - """ - @return: True if C{str} is the name of a public object. - @rtype: C{boolean} - @param str: The name to check. - @type str: C{string} - """ - if str == '...': return 0 - for piece in str.split('.'): - if piece[0] == '_' and piece[-1] != '_': - return 1 - return 0 - class DocChecker: """ Documentation completeness checker. C{DocChecker} can be used to @@ -65,7 +51,7 @@ checked: L{MODULE}; L{CLASS}; L{FUNC}; L{VAR}; L{IVAR}; L{CVAR}; L{PARAM}; and L{RETURN}. - Public/private specifiers indicate whether public or private - objects should be checked: L{PUBLIC} and L{PRIVATE}. + objects should be checked: L{PRIVATE}. - Check specifiers indicate what checks should be run on the objects: L{TYPE}; L{DESCR}; L{DESCR_LAZY}; L{AUTHOR}; and L{VERSION}. @@ -74,15 +60,13 @@ documentation. Its parameter is formed by or-ing together at least one value from each specifier group: - >>> checker.check(DocChecker.MODULE | DocChecker.PUBLIC | - ... DocChecker.DESCR) + >>> checker.check(DocChecker.MODULE | DocChecker.DESCR) To specify multiple values from a single group, simply or their values together: >>> checker.check(DocChecker.MODULE | DocChecker.CLASS | - ... DocChecker.FUNC | DocChecker.DESCR_LAZY | - ... DocChecker.PUBLIC) + ... DocChecker.FUNC | DocChecker.DESCR_LAZY) @group Types: MODULE, CLASS, FUNC, VAR, IVAR, CVAR, PARAM, RETURN, ALL_T @@ -124,12 +108,6 @@ @type VERSION: C{int} @cvar VERSION: Check specifier that indicates that every object should have a C{version} field. - @type DESCR_LAZY: C{int} - @cvar DESCR_LAZY: Check specifier that indicates that every object - should have a description. However, it is permissible for - functions and methods that have a C{@return} field to not have - a description, since a description may be generated from the - C{@return} field. @type DESCR: C{int} @cvar DESCR: Check specifier that indicates that every object should have a description. @@ -137,24 +115,18 @@ @cvar ALL_C: Check specifier that indicates that all checks should be run. - @group Publicity: PUBLIC, PRIVATE, ALL_P - @type PUBLIC: C{int} - @cvar PUBLIC: Specifier that indicates that public objects should - be checked. + @group Publicity: PRIVATE @type PRIVATE: C{int} @cvar PRIVATE: Specifier that indicates that private objects should be checked. - @type ALL_P: C{int} - @cvar ALL_P: Specifier that indicates that both public and private - objects should be checked. """ # Types MODULE = 1 CLASS = 2 FUNC = 4 VAR = 8 - IVAR = 16 - CVAR = 32 + #IVAR = 16 + #CVAR = 32 PARAM = 64 RETURN = 128 PROPERTY = 256 @@ -164,17 +136,13 @@ TYPE = 256 AUTHOR = 1024 VERSION = 2048 - DESCR_LAZY = 4096 - _DESCR_STRICT = 8192 - DESCR = DESCR_LAZY + _DESCR_STRICT - ALL_C = 256+512+1024+2048+4096+8192 + DESCR = 4096 + ALL_C = 256+512+1024+2048+4096 # Private/public PRIVATE = 16384 - PUBLIC = 32768 - ALL_P = PRIVATE + PUBLIC - ALL = ALL_T + ALL_C + ALL_P + ALL = ALL_T + ALL_C + PRIVATE def __init__(self, docindex): """ @@ -186,12 +154,6 @@ @type docindex: L{Docindex<apidoc.DocIndex>} """ self._docindex = docindex - - # Sort & filter the documentation from the docindex. - docs = docindex.items() - docs.sort() - self._docs = [d for (u,d) in docs if u.is_module() or - docindex.has_key(u.module())] # Initialize instance variables self._checks = 0 @@ -199,7 +161,7 @@ self._out = sys.stdout self._num_warnings = 0 - def check(self, checks = None): + def check(self, *check_sets): """ Run the specified checks on the documentation of the objects contained by this C{DocChecker}'s C{DocIndex}. Any errors found @@ -216,18 +178,38 @@ @return: True if no problems were found. @rtype: C{boolean} """ - if checks == None: - return (self.check(DocChecker.MODULE | DocChecker.CLASS | - DocChecker.FUNC | DocChecker.DESCR_LAZY | - DocChecker.PUBLIC) and - self.check(DocChecker.PARAM | DocChecker.VAR | - DocChecker.IVAR | DocChecker.CVAR | - DocChecker.RETURN | DocChecker.DESCR | - DocChecker.TYPE | DocChecker.PUBLIC)) + if not check_sets: + check_sets = (DocChecker.MODULE | DocChecker.CLASS | + DocChecker.FUNC | DocChecker.VAR | + DocChecker.DESCR,) + + self._warnings = {} + log.start_progress('Checking docs') + for j, checks in enumerate(check_sets): + self._check(checks) + log.end_progress() + for (warning, docs) in self._warnings.items(): + docs = sorted(docs) + docnames = '\n'.join([' - %s' % self._name(d) for d in docs]) + log.warning('%s:\n%s' % (warning, docnames)) + + def _check(self, checks): self._checks = checks - self._last_warn = None - for doc in self._docs: + + # Get the list of objects to check. + valdocs = sorted(self._docindex.reachable_valdocs( + imports=False, packages=False, bases=False, submodules=False, + subclasses=False, private = (checks & DocChecker.PRIVATE))) + docs = set() + for d in valdocs: + if not isinstance(d, GenericValueDoc): docs.add(d) + for doc in valdocs: + if isinstance(doc, NamespaceDoc): + for d in doc.variables.values(): + if isinstance(d.value, GenericValueDoc): docs.add(d) + + for i, doc in enumerate(sorted(docs)): if isinstance(doc, ModuleDoc): self._check_module(doc) elif isinstance(doc, ClassDoc): @@ -236,45 +218,16 @@ self._check_func(doc) elif isinstance(doc, PropertyDoc): self._check_property(doc) + elif isinstance(doc, VariableDoc): + self._check_var(doc) else: - raise AssertionError("Don't know how to check%r" % doc) - if self._last_warn is not None: print - return (self._last_warn is None) + log.error("Don't know how to check %r" % doc) - def _warn(self, error, name): - """ - Print a warning about the object named C{name}. + def _name(self, doc): + name = str(doc.canonical_name) + if isinstance(doc, RoutineDoc): name += '()' + return name - @param error: The error message to print. - @type error: C{string} - @param name: The name of the object that generated the - warning. - @type name: C{string} - @rtype: C{None} - """ - name = str(name) - if name != self._last_warn: - self._num_warnings += 1 - if self._last_warn is not None: self._out.write('\n') - self._out.write(name + '.'*max(1,60-len(name)) + error) - self._last_warn = name - else: - self._out.write(', %s' % error) - - def _check_name_publicity(self, name): - """ - @return: True if an object named C{name} should be checked, - given the public/private specifiers. - @rtype: C{boolean} - @param name: The name of the object to check. - @type name: C{string} - """ - if (_is_private(name) and - not (self._checks & DocChecker.PRIVATE)): return 0 - if (not _is_private(name) and - not (self._checks & DocChecker.PUBLIC)): return 0 - return 1 - def _check_basic(self, doc): """ Check the description, author, version, and see-also fields of @@ -285,117 +238,115 @@ @type doc: L{ObjDoc} @rtype: C{None} """ - if (self._checks & DocChecker.DESCR) and (not doc.descr): - if ((self._checks & DocChecker._DESCR_STRICT) or - (not isinstance(doc, RoutineDoc)) or - (not doc.returns().descr)): - self._warn('No descr', doc.canonical_name) + if ((self._checks & DocChecker.DESCR) and + (doc.descr in (None, UNKNOWN))): + if doc.docstring in (None, UNKNOWN): + self.warning('Undocumented', doc) + else: + self.warning('No description', doc) if self._checks & DocChecker.AUTHOR: - for field in doc.fields(): - if 'author' in field.tags: break + for tag, arg, descr in doc.metadata: + if 'author' == tag: break else: - self._warn('No authors', doc.canonical_name) + self.warning('No authors', doc) if self._checks & DocChecker.VERSION: - for field in doc.fields(): - if 'version' in field.tags: break + for tag, arg, descr in doc.metadata: + if 'version' == tag: break else: - self._warn('No version', doc.canonical_name) + self.warning('No version', doc) def _check_module(self, doc): """ - Run checks on the module whose UID is C{doc}. + Run checks on the module whose APIDoc is C{doc}. - @param doc: The UID of the module to check. - @type doc: L{UID} + @param doc: The APIDoc of the module to check. + @type doc: L{APIDoc} @rtype: C{None} """ - if not self._check_name_publicity(doc.canonical_name): return if self._checks & DocChecker.MODULE: self._check_basic(doc) - if self._checks & DocChecker.VAR: - for v in doc.variables(): - self._check_var(v, doc.canonical_name) def _check_class(self, doc): """ - Run checks on the class whose UID is C{doc}. + Run checks on the class whose APIDoc is C{doc}. - @param doc: The UID of the class to check. - @type doc: L{UID} + @param doc: The APIDoc of the class to check. + @type doc: L{APIDoc} @rtype: C{None} """ - if not self._check_name_publicity(doc.canonical_name): return if self._checks & DocChecker.CLASS: self._check_basic(doc) - if self._checks & DocChecker.IVAR: - for v in doc.ivariables(): - self._check_var(v, doc.canonical_name) - if self._checks & DocChecker.CVAR: - for v in doc.cvariables(): - self._check_var(v, doc.canonical_name) def _check_property(self, doc): - if not self._check_name_publicity(doc.canonical_name): return if self._checks & DocChecker.PROPERTY: self._check_basic(doc) - def _check_var(self, var, name, check_type=1): + def _check_var(self, doc): """ Run checks on the variable whose documentation is C{var} and whose name is C{name}. - @param var: The documentation for the variable to check. - @type var: L{Var} - @param name: The name of the variable to check. - @type name: C{string} + @param doc: The documentation for the variable to check. + @type doc: L{Doc} @param check_type: Whether or not the variable's type should be checked. This is used to allow varargs and keyword parameters to have no type specified. @rtype: C{None} """ - if not self._check_name_publicity(name): return - if var == None: return - if not self._check_name_publicity(var.name()): return - if var.name() == 'return': - if (var.type() and - var.type().to_plaintext(None).strip().lower() == 'none'): - return - if (self._checks & DocChecker.DESCR) and (not var.descr()): - self._warn('No descr', name+'.'+var.name()) - if ((self._checks & DocChecker.TYPE) and (not var.type()) and - check_type): - self._warn('No type', name+'.'+var.name()) + if self._checks & DocChecker.VAR: + if (self._checks & (DocChecker.DESCR|DocChecker.TYPE) and + doc.descr in (None, UNKNOWN) and + doc.type_descr in (None, UNKNOWN) and + doc.docstring in (None, UNKNOWN)): + self.warning('Undocumented', doc) + else: + if (self._checks & DocChecker.DESCR and + doc.descr in (None, UNKNOWN)): + self.warning('No description', doc) + if (self._checks & DocChecker.TYPE and + doc.type_descr in (None, UNKNOWN)): + self.warning('No type information', doc) def _check_func(self, doc): """ - Run checks on the function whose UID is C{doc}. + Run checks on the function whose APIDoc is C{doc}. - @param doc: The UID of the function to check. - @type doc: L{UID} + @param doc: The APIDoc of the function to check. + @type doc: L{APIDoc} @rtype: C{None} """ name = doc.canonical_name - if not self._check_name_publicity(name): return - if (doc.uid().is_any_method() and - doc != self._docindex.documented_ancestor(doc.uid())): return if (self._checks & DocChecker.FUNC and - not doc.has_docstring() and - doc.uid().shortname() not in _NO_DOCS): - self._warn('No docs', name) + doc.docstring in (None, UNKNOWN) and + doc.canonical_name[-1] not in _NO_DOCS): + self.warning('Undocumented', doc) return if (self._checks & DocChecker.FUNC and - doc.uid().shortname() not in _NO_BASIC): + doc.canonical_name[-1] not in _NO_BASIC): self._check_basic(doc) if (self._checks & DocChecker.RETURN and - doc.uid().shortname() not in _NO_RETURN): - self._check_var(doc.returns(), name) + doc.canonical_name[-1] not in _NO_RETURN): + if (doc.return_type in (None, UNKNOWN) and + doc.return_descr in (None, UNKNOWN)): + self.warning('No return descr', doc) if (self._checks & DocChecker.PARAM and - doc.uid().shortname() not in _NO_PARAM): - if doc.uid().is_method(): - for v in doc.parameters()[1:]: - self._check_var(v, name) + doc.canonical_name[-1] not in _NO_PARAM): + if doc.arg_descrs in (None, UNKNOWN): + self.warning('No argument info', doc) else: - for v in doc.parameters(): - self._check_var(v, name) - self._check_var(doc.vararg(), name, 0) - self._check_var(doc.kwarg(), name, 0) + args_with_descr = [] + for arg, descr in doc.arg_descrs: + if isinstance(arg, basestring): + args_with_descr.append(arg) + else: + args_with_descr += arg + for posarg in doc.posargs: + if (self._checks & DocChecker.DESCR and + posarg not in args_with_descr): + self.warning('Argument(s) not described', doc) + if (self._checks & DocChecker.TYPE and + posarg not in doc.arg_types): + self.warning('Argument type(s) not described', doc) + + def warning(self, msg, doc): + self._warnings.setdefault(msg,set()).add(doc) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2006-09-07 15:55:04
|
Revision: 1366 http://svn.sourceforge.net/epydoc/?rev=1366&view=rev Author: edloper Date: 2006-09-07 08:54:59 -0700 (Thu, 07 Sep 2006) Log Message: ----------- - Docstring fixes Modified Paths: -------------- trunk/epydoc/src/epydoc/checker.py Modified: trunk/epydoc/src/epydoc/checker.py =================================================================== --- trunk/epydoc/src/epydoc/checker.py 2006-09-07 15:54:31 UTC (rev 1365) +++ trunk/epydoc/src/epydoc/checker.py 2006-09-07 15:54:59 UTC (rev 1366) @@ -167,14 +167,14 @@ contained by this C{DocChecker}'s C{DocIndex}. Any errors found are printed to standard out. - @param checks: The checks that should be run on the + @param check_sets: The checks that should be run on the documentation. This value is constructed by or-ing together the specifiers that indicate which objects should be checked, and which checks should be run. See the L{module description<checker>} for more information. If no checks are specified, then a default set of checks will be run. - @type checks: C{int} + @type check_sets: C{int} @return: True if no problems were found. @rtype: C{boolean} """ @@ -288,9 +288,6 @@ @param doc: The documentation for the variable to check. @type doc: L{APIDoc} - @param check_type: Whether or not the variable's type should - be checked. This is used to allow varargs and keyword - parameters to have no type specified. @rtype: C{None} """ if self._checks & DocChecker.VAR: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |