[Epydoc-commits] SF.net SVN: epydoc: [1373] branches/exp-args_in_class/epydoc/src/epydoc
Brought to you by:
edloper
From: <dva...@us...> - 2006-09-08 10:39:07
|
Revision: 1373 http://svn.sourceforge.net/epydoc/?rev=1373&view=rev Author: dvarrazzo Date: 2006-09-08 03:38:55 -0700 (Fri, 08 Sep 2006) Log Message: ----------- - Allow parameter-related fields in a class docstring: use them to extend the matching __init__ docstring. - Enforce docstring parsing in dotted name order to ensure class docstring have already been parsed at __init__ docstring parsing time. - "type" fields are used to specify both class/instance variables types and constructor arguments types. In case a type is expressed in both class and __init__ docstring, the latter wins (e.g. the __init__ may receive an arg, parse it and store it in the instance state with the same name but different type) Modified Paths: -------------- branches/exp-args_in_class/epydoc/src/epydoc/apidoc.py branches/exp-args_in_class/epydoc/src/epydoc/docbuilder.py branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py Modified: branches/exp-args_in_class/epydoc/src/epydoc/apidoc.py =================================================================== --- branches/exp-args_in_class/epydoc/src/epydoc/apidoc.py 2006-09-08 10:28:10 UTC (rev 1372) +++ branches/exp-args_in_class/epydoc/src/epydoc/apidoc.py 2006-09-08 10:38:55 UTC (rev 1373) @@ -1118,6 +1118,10 @@ """@ivar: API documentation for the class's known subclasses. @type: C{list} of L{ClassDoc}""" #} + init_args = UNKNOWN + """@ivar: Tags to be used as constructor documentation. + @type: C{list} of C{(tag, arg, descr)} tuples""" + #} def apidoc_links(self, **filters): val_docs = NamespaceDoc.apidoc_links(self, **filters) Modified: branches/exp-args_in_class/epydoc/src/epydoc/docbuilder.py =================================================================== --- branches/exp-args_in_class/epydoc/src/epydoc/docbuilder.py 2006-09-08 10:28:10 UTC (rev 1372) +++ branches/exp-args_in_class/epydoc/src/epydoc/docbuilder.py 2006-09-08 10:38:55 UTC (rev 1373) @@ -182,7 +182,10 @@ valdocs = docindex.reachable_valdocs(sort_by_name=True, imports=False, submodules=False, packages=False, subclasses=False) - for i, val_doc in enumerate(valdocs): + # Sort according to dotted name, so __init__ docstrings are parsed after + # class docstrings, allowing constructor parameters to be specified in the + # latters + for i, val_doc in enumerate(sorted(valdocs)): _report_valdoc_progress(i, val_doc, valdocs) # the value's docstring parse_docstring(val_doc, docindex) Modified: branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py =================================================================== --- branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-08 10:28:10 UTC (rev 1372) +++ branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-08 10:38:55 UTC (rev 1373) @@ -197,6 +197,37 @@ descr, fields = parsed_docstring.split_fields(parse_errors) api_doc.descr = descr + # Handle the constructor fields that have been defined in the class + # docstring. This code assumes that a class docstring is parsed before + # the same class __init__ docstring. + if isinstance(api_doc, ClassDoc): + # Put aside param-related fields, which are to be considered as + # __init__ fields. "type" fields are to be used in both contexts. + param_tags = ('arg', 'argument', 'parameter', 'param', + 'kwarg', 'keyword', 'kwparam') + i = 0 + while i < len(fields): + field = fields[i] + if field.tag() in param_tags: + api_doc.init_args.append(fields.pop(i)) + continue + elif field.tag() == 'type': + api_doc.init_args.append(field) + i += 1 + + elif (isinstance(api_doc, RoutineDoc) + and api_doc.canonical_name[-1] == '__init__'): + # __init__ can receive arguments descriptions from the class docstring + # if a type is specified in both docstring, __init__ wins. + class_doc = docindex.get_valdoc(api_doc.canonical_name[:-1]) + if class_doc is not None and class_doc.init_args is not UNKNOWN: + init_types = [ field.arg() for field in fields + if field.tag() == 'type' ] + for field in class_doc.init_args: + if field.tag() == 'type' and field.arg() in init_types: + continue + fields.append(field) + # Process fields field_warnings = [] for field in fields: @@ -234,6 +265,9 @@ api_doc.summary = None if api_doc.metadata is UNKNOWN: api_doc.metadata = [] + if isinstance(api_doc, ClassDoc): + if api_doc.init_args is UNKNOWN: + api_doc.init_args = [] if isinstance(api_doc, RoutineDoc): if api_doc.arg_descrs is UNKNOWN: api_doc.arg_descrs = [] @@ -586,15 +620,24 @@ api_doc.return_type = descr def process_arg_field(api_doc, docindex, tag, arg, descr): - _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=True) + _check(api_doc, tag, arg, context=(ClassDoc, RoutineDoc), expect_arg=True) idents = re.split('[:;, ] *', arg) - api_doc.arg_descrs.append( (idents, descr) ) - # Check to make sure that the documented parameter(s) are - # actually part of the function signature. - bad_params = ['"%s"' % i for i in idents if i not in api_doc.all_args()] - if bad_params: - raise ValueError(BAD_PARAM % (tag, ', '.join(bad_params))) + if isinstance(api_doc, RoutineDoc): + api_doc.arg_descrs.append( (idents, descr) ) + + # Check to make sure that the documented parameter(s) are + # actually part of the function signature. + bad_params = ['"%s"' % i for i in idents if i not in api_doc.all_args()] + if bad_params: + raise ValueError(BAD_PARAM % (tag, ', '.join(bad_params))) + + elif isinstance(api_doc, ClassDoc): + api_doc.init_args.append( (tag, arg, descr) ) + + else: + assert False, "unexpected context" + def process_kwarg_field(api_doc, docindex, tag, arg, descr): # [xx] these should -not- be checked if they exist.. # and listed separately or not?? This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |