epydoc-commits Mailing List for Python API documentation generation tool (Page 17)
Brought to you by:
edloper
You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
(77) |
May
|
Jun
(6) |
Jul
(8) |
Aug
(91) |
Sep
(67) |
Oct
(4) |
Nov
|
Dec
(1) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(17) |
Feb
(135) |
Mar
(25) |
Apr
|
May
(1) |
Jun
(1) |
Jul
(7) |
Aug
|
Sep
(62) |
Oct
(1) |
Nov
(3) |
Dec
|
| 2008 |
Jan
(40) |
Feb
(102) |
Mar
(5) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2009 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <ed...@us...> - 2007-01-17 20:43:14
|
Revision: 1412
http://svn.sourceforge.net/epydoc/?rev=1412&view=rev
Author: edloper
Date: 2007-01-17 12:43:08 -0800 (Wed, 17 Jan 2007)
Log Message:
-----------
Fixed sourceforge bug #1636352: <ol> start attribute wasn't getting rendered
correctly.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/markup/epytext.py
Modified: trunk/epydoc/src/epydoc/markup/epytext.py
===================================================================
--- trunk/epydoc/src/epydoc/markup/epytext.py 2006-12-02 22:26:09 UTC (rev 1411)
+++ trunk/epydoc/src/epydoc/markup/epytext.py 2007-01-17 20:43:08 UTC (rev 1412)
@@ -1797,7 +1797,7 @@
return '%s<ul>\n%s%s</ul>\n' % (indent*' ', childstr, indent*' ')
elif tree.tag == 'olist':
start = tree.attribs.get('start') or ''
- return ('%s<ol%s>\n%s%s</ol>\n' %
+ return ('%s<ol start="%s">\n%s%s</ol>\n' %
(indent*' ', start, childstr, indent*' '))
elif tree.tag == 'li':
return indent*' '+'<li>\n%s%s</li>\n' % (childstr, indent*' ')
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-12-02 22:26:12
|
Revision: 1411
http://svn.sourceforge.net/epydoc/?rev=1411&view=rev
Author: dvarrazzo
Date: 2006-12-02 14:26:09 -0800 (Sat, 02 Dec 2006)
Log Message:
-----------
- Don't report references to builtins as missing.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docwriter/html.py
Modified: trunk/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- trunk/epydoc/src/epydoc/docwriter/html.py 2006-10-13 00:35:28 UTC (rev 1410)
+++ trunk/epydoc/src/epydoc/docwriter/html.py 2006-12-02 22:26:09 UTC (rev 1411)
@@ -16,6 +16,7 @@
import re, os, sys, codecs, sre_constants, pprint, base64
import urllib
+import __builtin__
from epydoc.apidoc import *
import epydoc.docstringparser
import time, epydoc, epydoc.markup
@@ -624,6 +625,11 @@
log.progress(self._files_written/self._num_files, 'index.html')
self.write_homepage(directory)
+ # Don't report references to builtins as missing
+ for k in self._failed_xrefs.keys(): # have a copy of keys
+ if hasattr(__builtin__, k):
+ del self._failed_xrefs[k]
+
# Report any failed crossreferences
if self._failed_xrefs:
estr = 'Failed identifier crossreference targets:\n'
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-10-13 00:35:40
|
Revision: 1410
http://svn.sourceforge.net/epydoc/?rev=1410&view=rev
Author: dvarrazzo
Date: 2006-10-12 17:35:28 -0700 (Thu, 12 Oct 2006)
Log Message:
-----------
- html and css allow more compact output.
- dropped many empty definition lists, using css margins instead.
Modified Paths:
--------------
tags/exp-compact-html/epydoc/src/epydoc/docwriter/html.py
tags/exp-compact-html/epydoc/src/epydoc/docwriter/html_css.py
Modified: tags/exp-compact-html/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- tags/exp-compact-html/epydoc/src/epydoc/docwriter/html.py 2006-10-13 00:33:22 UTC (rev 1409)
+++ tags/exp-compact-html/epydoc/src/epydoc/docwriter/html.py 2006-10-13 00:35:28 UTC (rev 1410)
@@ -1815,7 +1815,6 @@
# Write a footer for the table.
out(self.TABLE_FOOTER)
- out('\n<br />\n')
def write_summary_group(self, out, doc, name, var_docs, grouped_inh_vars):
# Split up the var_docs list, according to the way each var
@@ -1964,18 +1963,15 @@
if not var_docs: return
# Write a header
- self.write_table_header(out, "summary", heading)
- out(self.TABLE_FOOTER)
+ self.write_table_header(out, "details", heading)
for var_doc in var_docs:
self.write_details_entry(out, var_doc)
- out('<br />\n')
+ out(self.TABLE_FOOTER)
def write_details_entry(self, out, var_doc):
- descr = self.descr(var_doc, indent=2)
- if descr: descr = '<br />'+descr
- else: descr = ''
+ descr = self.descr(var_doc, indent=2) or ''
if var_doc.is_public: div_class = ''
else: div_class = ' class="private"'
@@ -2039,8 +2035,8 @@
return self.function_signature(val_doc, True, True)
elif isinstance(val_doc, GenericValueDoc):
return ('<table><tr><td><pre class="variable">\n' +
- self.pprint_value(val_doc) +
- '\n</pre></td></tr></table>\n')
+ self.pprint_value(val_doc).rstrip() +
+ '</pre></td></tr></table>\n')
else:
return self.href(val_doc)
else:
@@ -2069,21 +2065,19 @@
# /------------------------- Template -------------------------\
'''
>>> func_doc = var_doc.value
- <a name="$var_doc.name$"></a>
- <div$div_class$>
- >>> self.write_table_header(out, "details")
- <tr><td>
+ <tr$div_class$><td class="details">
+ <a name="$var_doc.name$"></a>
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr valign="top"><td>
<h3 class="epydoc">$self.function_signature(var_doc)$
>>> if var_doc.name in self.SPECIAL_METHODS:
- <br /><em class="fname">($self.SPECIAL_METHODS[var_doc.name]$)</em>
+ <em class="fname">($self.SPECIAL_METHODS[var_doc.name]$)</em>
>>> #endif
>>> if isinstance(func_doc, ClassMethodDoc):
- <br /><em class="fname">Class Method</em>
+ <em class="fname"> - Class Method</em>
>>> #endif
>>> if isinstance(func_doc, StaticMethodDoc):
- <br /><em class="fname">Static Method</em>
+ <em class="fname"> - Static Method</em>
>>> #endif
</h3>
</td><td align="right" valign="top"
@@ -2092,10 +2086,10 @@
</table>
$self.render_callgraph(callgraph)$
$descr$
- <dl><dt></dt><dd>
+ <div class="fields">
>>> # === parameters ===
>>> if arg_descrs:
- <dl><dt>Parameters:</dt></dl>
+ <p><strong class="field_name">Parameters:</strong></p>
<ul class="nomargin">
>>> for lhs, rhs in arg_descrs:
$self.labelled_list_item(lhs, rhs)$
@@ -2104,13 +2098,14 @@
>>> #endif
>>> # === return type ===
>>> if rdescr and rtype:
- <dl><dt>Returns: $rtype$</dt>
- <dd>$rdescr$</dd></dl>
+ <p><strong class="field_name">Returns:</strong>
+ ($rtype$) $rdescr$</p>
>>> elif rdescr:
- <dl><dt>Returns:</dt>
- <dd>$rdescr$</dd></dl>
+ <p><strong class="field_name">Returns:</strong>
+ $rdescr$</p>
>>> elif rtype:
- <dl><dt>Returns: $rtype$</dt></dl>
+ <p><strong class="field_name">Returns:</strong>
+ $rtype$</p>
>>> #endif
>>> # === decorators ===
>>> if func_doc.decorators not in (None, UNKNOWN):
@@ -2125,7 +2120,7 @@
>>> decos = None
>>> #endif
>>> if decos:
- <dl><dt>Decorators:</dt></dl>
+ <p><strong class="field_name">Decorators:</strong></p>
<ul class="nomargin">
>>> for deco in decos:
<li><code>@$deco$</code></li>
@@ -2134,7 +2129,7 @@
>>> #endif
>>> # === exceptions ===
>>> if func_doc.exception_descrs not in (None, UNKNOWN, (), []):
- <dl><dt>Raises:</dt></dl>
+ <p><strong class="field_name">Raises:</strong></p>
<ul class="nomargin">
>>> for name, descr in func_doc.exception_descrs:
>>> exc_name = self.docindex.find(name, func_doc)
@@ -2150,19 +2145,18 @@
>>> #endif
>>> # === overrides ===
>>> if var_doc.overrides not in (None, UNKNOWN):
- <dl><dt>Overrides:
+ <p><strong class="field_name">Overrides:
$self.href(var_doc.overrides.value, context=var_doc)$
>>> if (func_doc.docstring in (None, UNKNOWN) and
>>> var_doc.overrides.value.docstring not in (None, UNKNOWN)):
- <dd><em class="note">(inherited documentation)</em></dd>
+ <em class="note">(inherited documentation)</em>
>>> #endif
- </dt></dl>
+ </strong></p>
>>> #endif
>>> # === metadata ===
>>> self.write_standard_fields(out, func_doc)
- </dd></dl>
- </td></tr></table>
- </div>
+ </div>
+ </td></tr>
''')
# \------------------------------------------------------------/
@@ -2206,29 +2200,26 @@
# /------------------------- Template -------------------------\
'''
>>> prop_doc = var_doc.value
- <a name="$var_doc.name$"></a>
- <div$div_class$>
- >>> self.write_table_header(out, "details")
- <tr><td>
+ <tr$div_class$><td class="details">
+ <a name="$var_doc.name$"></a>
<h3 class="epydoc">$var_doc.name$</h3>
$descr$
- <dl><dt></dt><dd>
+ <div class="fields">
+ >>> if prop_doc.type_descr not in (None, UNKNOWN):
+ <p><strong class="field_name">Type:</strong>
+ $self.type_descr(var_doc, indent=6)$</p>
+ >>> #endif
>>> for (name, val, summary) in accessors:
- <dl><dt>$name$ Method:</dt>
- <dd>$val$
+ <p><strong class="field_name">$name$ Method:</strong>
+ $val$
>>> if summary:
- $summary$
>>> #endif
- </dd></dl>
+ </p>
>>> #endfor
- >>> if prop_doc.type_descr not in (None, UNKNOWN):
- <dl><dt>Type:</dt>
- <dd>$self.type_descr(var_doc, indent=6)$</dd></dl>
- >>> #endif
>>> self.write_standard_fields(out, prop_doc)
- </dd></dl>
- </td></tr></table>
- </div>
+ </div>
+ </td></tr>
''')
# \------------------------------------------------------------/
@@ -2238,28 +2229,23 @@
''',
# /------------------------- Template -------------------------\
'''
- <a name="$var_doc.name$"></a>
- <div$div_class$>
- >>> self.write_table_header(out, "details")
- <tr><td>
+ <tr$div_class$><td class="details">
+ <a name="$var_doc.name$"></a>
<h3 class="epydoc">$var_doc.name$</h3>
$descr$
- <dl><dt></dt><dd>
+ <div class="fields">
>>> if var_doc.type_descr not in (None, UNKNOWN):
- <dl><dt>Type:</dt>
- <dd>$self.type_descr(var_doc, indent=6)$</dd></dl>
+ <p><strong class="field_name">Type:</strong>
+ $self.type_descr(var_doc, indent=6)$</p>
>>> #endif
>>> self.write_standard_fields(out, var_doc)
>>> if var_doc.value is not UNKNOWN:
- <dl><dt>Value:</dt>
- <dd><table><tr><td><pre class="variable">
- $self.pprint_value(var_doc.value)$
- </pre></td></tr></table></dd>
- </dl>
+ <p><strong class="field_name">Value:</strong>
+ <code class="variable">$self.pprint_value(var_doc.value).rstrip()$</code>
+ </p>
>>> #endif
- </dd></dl>
- </td></tr></table>
- </div>
+ </div>
+ </td></tr>
''')
# \------------------------------------------------------------/
@@ -2862,8 +2848,7 @@
<!-- ==================== $heading.upper()$ ==================== -->
<a name="$anchor$"></a>
>>> #endif
- <table class="$css_class$" border="1" cellpadding="3"
- cellspacing="0" width="100%" bgcolor="white">
+ <table class="$css_class$">
>>> if heading is not None:
<tr bgcolor="#70b0f0" class="table-header">
>>> if private_link:
Modified: tags/exp-compact-html/epydoc/src/epydoc/docwriter/html_css.py
===================================================================
--- tags/exp-compact-html/epydoc/src/epydoc/docwriter/html_css.py 2006-10-13 00:33:22 UTC (rev 1409)
+++ tags/exp-compact-html/epydoc/src/epydoc/docwriter/html_css.py 2006-10-13 00:35:28 UTC (rev 1410)
@@ -85,7 +85,7 @@
h2.epydoc { font-size: +130%; font-weight: bold; }
h3.epydoc { font-size: +115%; font-weight: bold; }
td h3.epydoc { font-size: +115%; font-weight: bold;
- margin-bottom: 0; }
+ margin: 0; }
table.navbar { background: #a0c0ff; color: #000000;
border: 2px groove #c0d0d0; }
table.navbar table { color: #000000; }
@@ -128,8 +128,11 @@
*/
table.summary { border-collapse: collapse;
background: #e8f0f8; color: #000000;
- border: 1px solid #608090; }
-td.summary { border: 1px solid #608090; }
+ border: 1px solid #608090;
+ margin: 0.25em 0 0.25em 0;
+ width: 100%; }
+td.summary { border: 1px solid #608090;
+ padding: 0.1em 0.3em 0.1em 0.3em; }
code.summary-type { font-size: 85%; }
table.summary a:link { color: #0000ff; }
table.summary a:visited { color: #204080; }
@@ -144,10 +147,14 @@
table.details { border-collapse: collapse;
background: #e8f0f8; color: #000000;
border: 1px solid #608090;
- margin: .2em 0 0 0; }
-table.details table { color: #000000; }
+ margin: 0.25em 0 0.25em 0;
+ width: 100%; }
table.details a:link { color: #0000ff; }
table.details a:visited { color: #204080; }
+table.details p { margin: 0.2em ; }
+table.details div.fields { margin-left: 2em; }
+table.details td.details { border: 1px solid #608090;
+ padding: 0.2em 0.3em 0.2em 0.3em; }
/* Index tables (identifier index, term index, etc)
* - link-index is used for indices containing lists of links
@@ -167,7 +174,8 @@
table.metadata-index { border-collapse: collapse;
background: #e8f0f8; color: #000000;
border: 1px solid #608090;
- margin: .2em 0 0 0; }
+ margin: .2em 0 0 0;
+ width: 100%; }
td.metadata-index { border-width: 1px; border-style: solid; }
table.metadata-index a:link { color: #0000ff; }
table.metadata-index a:visited { color: #204080; }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-10-13 00:33:30
|
Revision: 1409
http://svn.sourceforge.net/epydoc/?rev=1409&view=rev
Author: dvarrazzo
Date: 2006-10-12 17:33:22 -0700 (Thu, 12 Oct 2006)
Log Message:
-----------
Initialized merge tracking via "svnmerge" with revisions "1-1408" from
https://svn.sourceforge.net/svnroot/epydoc/trunk/epydoc
Property Changed:
----------------
tags/exp-compact-html/epydoc/
Property changes on: tags/exp-compact-html/epydoc
___________________________________________________________________
Name: svnmerge-integrated
+ /trunk/epydoc:1-1408
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-10-13 00:23:50
|
Revision: 1408
http://svn.sourceforge.net/epydoc/?rev=1408&view=rev
Author: dvarrazzo
Date: 2006-10-12 17:23:35 -0700 (Thu, 12 Oct 2006)
Log Message:
-----------
- Starting branch to study a more compact html output.
Added Paths:
-----------
tags/exp-compact-html/
Copied: tags/exp-compact-html (from rev 1407, trunk)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ed...@us...> - 2006-10-07 01:24:38
|
Revision: 1407
http://svn.sourceforge.net/epydoc/?rev=1407&view=rev
Author: edloper
Date: 2006-10-06 18:24:33 -0700 (Fri, 06 Oct 2006)
Log Message:
-----------
- Fixed bug where an indentation error in the source could cause the
epydoc parser to crash.
- Fixed a bug where using grouping comments ("#{","#}") for instance
variables could cause the epydoc parser to crash.
- Fixed a bug where using grouping comments ("#{","#}") for functions
with decorators could cause the epydoc parser to crash.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docparser.py
Modified: trunk/epydoc/src/epydoc/docparser.py
===================================================================
--- trunk/epydoc/src/epydoc/docparser.py 2006-09-27 23:42:45 UTC (rev 1406)
+++ trunk/epydoc/src/epydoc/docparser.py 2006-10-07 01:24:33 UTC (rev 1407)
@@ -281,6 +281,9 @@
raise ParseError('Error during parsing: %s '
'(%s, line %d, char %d)' %
(msg, module_doc.filename, srow, scol))
+ except IndentationError, e:
+ raise ParseError('Error during parsing: %s (%s)' %
+ (e, module_doc.filename))
# Handle any special variables (__path__, __docformat__, etc.)
handle_special_module_vars(module_doc)
@@ -639,11 +642,18 @@
# grouping...
if groups[-1] and prev_line_doc not in (None, 'skip_block'):
if isinstance(prev_line_doc, VariableDoc):
- # This special case is needed for inst vars, where
- # parent_docs[-1] is the __init__ function, not the
- # containing class:
- add_to_group(prev_line_doc.container,
- prev_line_doc, groups[-1])
+ # prev_line_doc's container will only be
+ # UNKNOWN if it's an instance variable that
+ # didn't have a doc-comment, but might still
+ # be followed by a docstring. Since we
+ # tokenize in order, we can't do lookahead to
+ # see if the variable will have a comment; but
+ # it should only be added to the container if
+ # it does. So we defer the grouping of that
+ # to be handled by process_docstring instead.
+ if prev_line_doc.container is not UNKNOWN:
+ add_to_group(prev_line_doc.container,
+ prev_line_doc, groups[-1])
elif isinstance(parent_docs[-1], NamespaceDoc):
add_to_group(parent_docs[-1], prev_line_doc,
groups[-1])
@@ -663,6 +673,7 @@
if isinstance(api_doc, VariableDoc):
var_name = api_doc.name
else:
+ if api_doc.canonical_name is UNKNOWN: log.debug('ouch', `api_doc`)
var_name = api_doc.canonical_name[-1]
for (name, group_vars) in container.group_specs:
@@ -1326,12 +1337,14 @@
# we only want to add instance variables if they have an
# associated docstring. (For more info, see the comment above
# the set_variable() call in process_assignment().)
+ added_instvar = False
if (isinstance(prev_line_doc, VariableDoc) and
- prev_line_doc.is_instvar and
- prev_line_doc.docstring in (None, UNKNOWN)):
+ prev_line_doc.is_instvar and
+ prev_line_doc.docstring in (None, UNKNOWN)):
for i in range(len(parent_docs)-1, -1, -1):
if isinstance(parent_docs[i], ClassDoc):
set_variable(parent_docs[i], prev_line_doc, True)
+ added_instvar = True
break
if prev_line_doc.docstring not in (None, UNKNOWN):
@@ -1342,6 +1355,12 @@
prev_line_doc.docstring = docstring
prev_line_doc.docstring_lineno = lineno
+ # If the modified APIDoc is an instance variable, and we added it
+ # to the class's variables list here, then it still needs to be
+ # grouped too; so return it for use as the new "prev_line_doc."
+ if added_instvar:
+ return prev_line_doc
+
#/////////////////////////////////////////////////////////////////
# Line handler: function declarations
@@ -1400,8 +1419,12 @@
else:
deco_repr = UNKNOWN
func_doc = apply_decorator(deco_name, func_doc)
- func_doc.canonical_name = UNKNOWN
func_doc.parse_repr = deco_repr
+ # [XX] Is there a reson the following should be done? It
+ # causes the grouping code to break. Presumably the canonical
+ # name should remain valid if we're just applying a standard
+ # decorator.
+ #func_doc.canonical_name = UNKNOWN
# Add a variable to the containing namespace.
var_doc = VariableDoc(name=func_name, value=func_doc,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-17 23:50:41
|
Revision: 1404
http://svn.sourceforge.net/epydoc/?rev=1404&view=rev
Author: dvarrazzo
Date: 2006-09-17 16:50:35 -0700 (Sun, 17 Sep 2006)
Log Message:
-----------
- Types in HTML output are treated consistently: not always in monotype font,
but respecting user markup.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docwriter/html.py
Modified: trunk/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 20:02:33 UTC (rev 1403)
+++ trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 23:50:35 UTC (rev 1404)
@@ -1939,7 +1939,7 @@
'''
<tr$tr_class$>
<td width="15%" align="right" valign="top" class="summary">
- <code class="summary-type">$typ or " "$</code>
+ <span class="summary-type">$typ or " "$</span>
</td><td class="summary">
$description$
</td>
@@ -2058,7 +2058,7 @@
if arg_name in func_doc.arg_types:
typ = func_doc.arg_types[arg_name]
typ_html = self.docstring_to_html(typ, func_doc, 10)
- s += " (<code>%s</code>)" % typ_html
+ s += " (%s)" % typ_html
return s
write_function_details_entry = compile_template(
@@ -2104,13 +2104,13 @@
>>> #endif
>>> # === return type ===
>>> if rdescr and rtype:
- <dl><dt>Returns: <code>$rtype$</code></dt>
+ <dl><dt>Returns: $rtype$</dt>
<dd>$rdescr$</dd></dl>
>>> elif rdescr:
<dl><dt>Returns:</dt>
<dd>$rdescr$</dd></dl>
>>> elif rtype:
- <dl><dt>Returns: <code>$rtype$</code></dt></dl>
+ <dl><dt>Returns: $rtype$</dt></dl>
>>> #endif
>>> # === decorators ===
>>> if func_doc.decorators not in (None, UNKNOWN):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-17 20:02:39
|
Revision: 1403
http://svn.sourceforge.net/epydoc/?rev=1403&view=rev
Author: dvarrazzo
Date: 2006-09-17 13:02:33 -0700 (Sun, 17 Sep 2006)
Log Message:
-----------
- Dropped check not required anymore after r1401
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docwriter/html.py
Modified: trunk/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 18:21:05 UTC (rev 1402)
+++ trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 20:02:33 UTC (rev 1403)
@@ -2128,10 +2128,6 @@
<dl><dt>Decorators:</dt></dl>
<ul class="nomargin">
>>> for deco in decos:
- >>> if not ((deco=="staticmethod" and
- >>> isinstance(func_doc, StaticMethodDoc)) or
- >>> (deco=="classmethod" and
- >>> isinstance(func_doc, ClassMethodDoc))):
<li><code>@$deco$</code></li>
>>> #endfor
</ul>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-17 18:21:11
|
Revision: 1402
http://svn.sourceforge.net/epydoc/?rev=1402&view=rev
Author: dvarrazzo
Date: 2006-09-17 11:21:05 -0700 (Sun, 17 Sep 2006)
Log Message:
-----------
- Property access functions are not shown (as ``None``) when they are None.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docwriter/html.py
Modified: trunk/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 17:54:47 UTC (rev 1401)
+++ trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 18:21:05 UTC (rev 1402)
@@ -2012,7 +2012,9 @@
self.summary(val_doc)) for (name, val_doc) in
[('Get', prop_doc.fget), ('Set', prop_doc.fset),
('Delete', prop_doc.fdel)]
- if val_doc is not UNKNOWN ]
+ if val_doc not in (None, UNKNOWN)
+ and val_doc.pyval is not None ]
+
self.write_property_details_entry(out, var_doc, descr,
accessors, div_class)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-17 17:54:52
|
Revision: 1401
http://svn.sourceforge.net/epydoc/?rev=1401&view=rev
Author: dvarrazzo
Date: 2006-09-17 10:54:47 -0700 (Sun, 17 Sep 2006)
Log Message:
-----------
- An empty "Decorators:" fields group is not shown if ``classmethod``
and ``staticmethod`` are the only decorators of a method.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docwriter/html.py
Modified: trunk/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 15:04:40 UTC (rev 1400)
+++ trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 17:54:47 UTC (rev 1401)
@@ -2111,11 +2111,21 @@
<dl><dt>Returns: <code>$rtype$</code></dt></dl>
>>> #endif
>>> # === decorators ===
- >>> if func_doc.decorators not in (None, UNKNOWN, (), []):
+ >>> if func_doc.decorators not in (None, UNKNOWN):
+ >>> # (staticmethod & classmethod are already shown, above)
+ >>> decos = filter(lambda deco:
+ >>> not ((deco=="staticmethod" and
+ >>> isinstance(func_doc, StaticMethodDoc)) or
+ >>> (deco=="classmethod" and
+ >>> isinstance(func_doc, ClassMethodDoc))),
+ >>> func_doc.decorators)
+ >>> else:
+ >>> decos = None
+ >>> #endif
+ >>> if decos:
<dl><dt>Decorators:</dt></dl>
<ul class="nomargin">
- >>> for deco in func_doc.decorators:
- >>> # (staticmethod & classmethod are already shown, above)
+ >>> for deco in decos:
>>> if not ((deco=="staticmethod" and
>>> isinstance(func_doc, StaticMethodDoc)) or
>>> (deco=="classmethod" and
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-17 15:04:47
|
Revision: 1400
http://svn.sourceforge.net/epydoc/?rev=1400&view=rev
Author: dvarrazzo
Date: 2006-09-17 08:04:40 -0700 (Sun, 17 Sep 2006)
Log Message:
-----------
- Fixed URLs reported malformed by HTML Tidy
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docwriter/html.py
Modified: trunk/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-16 13:59:05 UTC (rev 1399)
+++ trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-17 15:04:40 UTC (rev 1400)
@@ -1499,7 +1499,7 @@
def callgraph_link(self, callgraph):
# Use class=codelink, to match style w/ the source code link.
if callgraph is None: return ''
- return ('<br /><span class="codelink"><a href="javascript: void(0);" '
+ return ('<br /><span class="codelink"><a href="javascript:void(0);" '
'onclick="toggleCallGraph(\'%s-div\');return false;">'
'call graph</a></span> ' % callgraph.uid)
@@ -2882,7 +2882,7 @@
TABLE_FOOTER = '</table>\n'
PRIVATE_LINK = '''
- <span class="options">[<a href="javascript: void(0);" class="privatelink"
+ <span class="options">[<a href="javascript:void(0);" class="privatelink"
onclick="toggle_private();">hide private</a>]</span>
'''.strip()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-16 13:59:14
|
Revision: 1399
http://svn.sourceforge.net/epydoc/?rev=1399&view=rev
Author: dvarrazzo
Date: 2006-09-16 06:59:05 -0700 (Sat, 16 Sep 2006)
Log Message:
-----------
- Dropped unmatched </span>
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docwriter/html.py
Modified: trunk/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-16 13:53:17 UTC (rev 1398)
+++ trunk/epydoc/src/epydoc/docwriter/html.py 2006-09-16 13:59:05 UTC (rev 1399)
@@ -2085,8 +2085,8 @@
>>> #endif
</h3>
</td><td align="right" valign="top"
- >$self.pysrc_link(func_doc)$ </span
- >$self.callgraph_link(callgraph)$</td>
+ >$self.pysrc_link(func_doc)$
+ $self.callgraph_link(callgraph)$</td>
</table>
$self.render_callgraph(callgraph)$
$descr$
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-16 13:53:24
|
Revision: 1398
http://svn.sourceforge.net/epydoc/?rev=1398&view=rev
Author: dvarrazzo
Date: 2006-09-16 06:53:17 -0700 (Sat, 16 Sep 2006)
Log Message:
-----------
- Closing (old\!) experimental branch
Removed Paths:
-------------
branches/exp-all-is-interface/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-16 13:51:01
|
Revision: 1397
http://svn.sourceforge.net/epydoc/?rev=1397&view=rev
Author: dvarrazzo
Date: 2006-09-16 06:50:56 -0700 (Sat, 16 Sep 2006)
Log Message:
-----------
- Closing experimental branch
Removed Paths:
-------------
branches/exp-args_in_class/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-16 13:48:40
|
Revision: 1396
http://svn.sourceforge.net/epydoc/?rev=1396&view=rev
Author: dvarrazzo
Date: 2006-09-16 06:48:32 -0700 (Sat, 16 Sep 2006)
Log Message:
-----------
- Class docstrings can describe the constructor signature, parameters and
raised exceptions.
Merged revisions 1373-1375,1377-1388,1390-1395 via svnmerge from
https://svn.sourceforge.net/svnroot/epydoc/branches/exp-args_in_class
........
r1373 | dvarrazzo | 2006-09-08 12:38:55 +0200 (Fri, 08 Sep 2006) | 10 lines
- 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)
........
r1374 | dvarrazzo | 2006-09-08 17:40:13 +0200 (Fri, 08 Sep 2006) | 8 lines
- __init__ signature can be described in the class docstring also when there
is no __init__.__doc__ at all.
- parse_function_signature() can receive two arguments: one whose docstring is
to be parsed and one to be populated. So the constructor signature can be
parsed from the class docstring.
- Dropped generation of variables when there is a type w/o matching var.
The issue is still to be defined consistently anyway.
........
r1390 | dvarrazzo | 2006-09-15 03:47:53 +0200 (Fri, 15 Sep 2006) | 5 lines
- Checked in a new algorithm to split fields in the class docstring between
class documentation and constructor documentation. The algorithm requires
the `type` fields to appear after the related fields.
- Added more test.
........
r1391 | dvarrazzo | 2006-09-15 04:24:11 +0200 (Fri, 15 Sep 2006) | 2 lines
- Splitting argument refactored into a single distinct function.
........
r1392 | dvarrazzo | 2006-09-16 01:36:23 +0200 (Sat, 16 Sep 2006) | 1 line
- Be more lenient about types specified before matching objects.
........
r1393 | dvarrazzo | 2006-09-16 02:02:10 +0200 (Sat, 16 Sep 2006) | 5 lines
- Reverted updates to `process_arg_field()` handler: is context is always a
function, not the class docstring.
- Exceptions are handled in the class docstring as well.
- More explicit name of some variables.
........
r1394 | dvarrazzo | 2006-09-16 02:20:06 +0200 (Sat, 16 Sep 2006) | 1 line
- Reverting type fields handling to trunk behavior.
........
r1395 | dvarrazzo | 2006-09-16 14:57:14 +0200 (Sat, 16 Sep 2006) | 4 lines
- Class docstring fields are passed to __init__ without using an extra ClassDoc
attribute.
- Some docstring fixed.
........
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docstringparser.py
trunk/epydoc/src/epydoc/test/docbuilder.doctest
Modified: trunk/epydoc/src/epydoc/docstringparser.py
===================================================================
--- trunk/epydoc/src/epydoc/docstringparser.py 2006-09-16 12:57:14 UTC (rev 1395)
+++ trunk/epydoc/src/epydoc/docstringparser.py 2006-09-16 13:48:32 UTC (rev 1396)
@@ -168,7 +168,9 @@
user docfields defined by containing objects.
"""
if api_doc.metadata is not UNKNOWN:
- log.debug("%s's docstring processed twice" % api_doc.canonical_name)
+ if not (isinstance(api_doc, RoutineDoc)
+ and api_doc.canonical_name[-1] == '__init__'):
+ log.debug("%s's docstring processed twice" % api_doc.canonical_name)
return
initialize_api_doc(api_doc)
@@ -197,8 +199,30 @@
descr, fields = parsed_docstring.split_fields(parse_errors)
api_doc.descr = descr
+ field_warnings = []
+
+ # 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):
+
+ # Parse ahead the __init__ docstring for this class
+ initvar = api_doc.variables.get('__init__')
+ if initvar and initvar.value not in (None, UNKNOWN):
+ init_api_doc = initvar.value
+ parse_docstring(init_api_doc, docindex)
+
+ parse_function_signature(init_api_doc, api_doc)
+ init_fields = split_init_fields(fields, field_warnings)
+
+ # Process fields
+ for field in init_fields:
+ try:
+ process_field(init_api_doc, docindex, field.tag(),
+ field.arg(), field.body())
+ except ValueError, e: field_warnings.append(str(e))
+
# Process fields
- field_warnings = []
for field in fields:
try:
process_field(api_doc, docindex, field.tag(),
@@ -254,6 +278,91 @@
if api_doc.sort_spec is UNKNOWN:
api_doc.sort_spec = []
+def split_init_fields(fields, warnings):
+ """
+ Remove the fields related to the constructor from a class docstring
+ fields list.
+
+ @param fields: The fields to process. The list will be modified in place
+ @type fields: C{list} of L{markup.Field}
+ @param warnings: A list to emit processing warnings
+ @type warnings: C{list}
+ @return: The C{fields} items to be applied to the C{__init__} method
+ @rtype: C{list} of L{markup.Field}
+ """
+ init_fields = []
+
+ # Split fields in lists according to their argument, keeping order.
+ arg_fields = {}
+ args_order = []
+ i = 0
+ while i < len(fields):
+ field = fields[i]
+
+ # gather together all the fields with the same arg
+ if field.arg() is not None:
+ arg_fields.setdefault(field.arg(), []).append(fields.pop(i))
+ args_order.append(field.arg())
+ else:
+ i += 1
+
+ # Now check that for each argument there is at most a single variable
+ # and a single parameter, and at most a single type for each of them.
+ for arg in args_order:
+ ff = arg_fields.pop(arg, None)
+ if ff is None:
+ continue
+
+ var = tvar = par = tpar = None
+ for field in ff:
+ if field.tag() in VARIABLE_TAGS:
+ if var is None:
+ var = field
+ fields.append(field)
+ else:
+ warnings.append(
+ "There is more than one variable named '%s'"
+ % arg)
+ elif field.tag() in PARAMETER_TAGS:
+ if par is None:
+ par = field
+ init_fields.append(field)
+ else:
+ warnings.append(
+ "There is more than one parameter named '%s'"
+ % arg)
+
+ elif field.tag() == 'type':
+ if var is None and par is None:
+ # type before obj
+ tvar = tpar = field
+ else:
+ if var is not None and tvar is None:
+ tvar = field
+ if par is not None and tpar is None:
+ tpar = field
+
+ elif field.tag() in EXCEPTION_TAGS:
+ init_fields.append(field)
+
+ else: # Unespected field
+ fields.append(field)
+
+ # Put selected types into the proper output lists
+ if tvar is not None:
+ if var is not None:
+ fields.append(tvar)
+ else:
+ pass # [xx] warn about type w/o object?
+
+ if tpar is not None:
+ if par is not None:
+ init_fields.append(tpar)
+ else:
+ pass # [xx] warn about type w/o object?
+
+ return init_fields
+
def report_errors(api_doc, docindex, parse_errors, field_warnings):
"""A helper function for L{parse_docstring()} that reports any
markup warnings and field warnings that we encountered while
@@ -620,6 +729,16 @@
register_field_handler(process_raise_field, 'raise', 'raises',
'except', 'exception')
+# Tags related to function parameters
+PARAMETER_TAGS = ('arg', 'argument', 'parameter', 'param',
+ 'kwarg', 'keyword', 'kwparam')
+
+# Tags related to variables in a class
+VARIABLE_TAGS = ('cvar', 'cvariable', 'ivar', 'ivariable')
+
+# Tags related to exceptions
+EXCEPTION_TAGS = ('raise', 'raises', 'except', 'exception')
+
######################################################################
#{ Helper Functions
######################################################################
@@ -697,7 +816,7 @@
# [xx] copied from inspect.getdoc(); we can't use inspect.getdoc()
# itself, since it expects an object, not a string.
- if docstring == '': return ''
+ if not docstring: return ''
lines = docstring.expandtabs().split('\n')
# Find minimum indentation of any non-blank lines after first line.
@@ -780,7 +899,7 @@
"""A regular expression that is used to extract signatures from
docstrings."""
-def parse_function_signature(func_doc):
+def parse_function_signature(func_doc, doc_source=None):
"""
Construct the signature for a builtin function or method from
its docstring. If the docstring uses the standard convention
@@ -790,15 +909,26 @@
Otherwise, the signature will be set to a single varargs
variable named C{"..."}.
+ @param func_doc: The target object where to store parsed signature. Also
+ container of the docstring to parse if doc_source is C{None}
+ @type func_doc: L{RoutineDoc}
+ @param doc_source: Contains the docstring to parse. If C{None}, parse
+ L{func_doc} docstring instead
+ @type doc_source: L{APIDoc}
@rtype: C{None}
"""
+ if doc_source is None:
+ doc_source = func_doc
+
# If there's no docstring, then don't do anything.
- if not func_doc.docstring: return False
+ if not doc_source.docstring: return False
- m = _SIGNATURE_RE.match(func_doc.docstring)
+ m = _SIGNATURE_RE.match(doc_source.docstring)
if m is None: return False
# Do I want to be this strict?
+ # Notice that __init__ must match the class name instead, if the signature
+ # comes from the class docstring
# if not (m.group('func') == func_doc.canonical_name[-1] or
# '_'+m.group('func') == func_doc.canonical_name[-1]):
# log.warning("Not extracting function signature from %s's "
@@ -857,7 +987,7 @@
func_doc.posarg_defaults.insert(0, None)
# Remove the signature from the docstring.
- func_doc.docstring = func_doc.docstring[m.end():]
+ doc_source.docstring = doc_source.docstring[m.end():]
# We found a signature.
return True
Modified: trunk/epydoc/src/epydoc/test/docbuilder.doctest
===================================================================
--- trunk/epydoc/src/epydoc/test/docbuilder.doctest 2006-09-16 12:57:14 UTC (rev 1395)
+++ trunk/epydoc/src/epydoc/test/docbuilder.doctest 2006-09-16 13:48:32 UTC (rev 1396)
@@ -1,5 +1,5 @@
Regression Testing for epydoc.docbuilder
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Test Function
=============
@@ -14,6 +14,22 @@
>>> import tempfile, re, os, os.path, textwrap, sys
>>> from epydoc.docbuilder import build_doc
+ >>> from epydoc.apidoc import ClassDoc, RoutineDoc
+ >>> from epydoc.markup import ParsedDocstring
+
+ >>> def to_plain(docstring):
+ ... """Conver a parsed docstring into plain text"""
+ ... if isinstance(docstring, ParsedDocstring):
+ ... docstring = docstring.to_plaintext(None)
+ ... return docstring.rsplit()
+
+ >>> def fun_to_plain(val_doc):
+ ... """Convert parsed docstrings in text from a RoutineDoc"""
+ ... for k, v in val_doc.arg_types.items():
+ ... val_doc.arg_types[k] = to_plain(v)
+ ... for i, (k, v) in enumerate(val_doc.arg_descrs):
+ ... val_doc.arg_descrs[i] = (k, to_plain(v))
+
>>> def runbuilder(s, attribs='', build=None, exclude=''):
... # Write it to a temp file.
... tmp_dir = tempfile.mkdtemp()
@@ -24,6 +40,10 @@
... val_doc = build_doc(os.path.join(tmp_dir, 'epydoc_test.py'))
... if build: val_doc = val_doc.variables[build].value
... # Display it.
+ ... if isinstance(val_doc, ClassDoc):
+ ... for val in val_doc.variables.values():
+ ... if isinstance(val.value, RoutineDoc):
+ ... fun_to_plain(val.value)
... s = val_doc.pp(include=attribs.split(),exclude=exclude.split())
... s = re.sub(r"(filename = ).*", r"\1...", s)
... s = re.sub(r"(<module 'epydoc_test' from ).*", r'\1...', s)
@@ -115,3 +135,291 @@
+- PropertyDoc for epydoc_test.Foo.y [9]
+- descr = u'A property has no defining module'
+- type_descr = u'int'
+
+Stuff from future doesn't appear as variable.
+
+ >>> runbuilder(s="""
+ ... from __future__ import division
+ ... from re import match
+ ... """,
+ ... attribs='variables value')
+ ModuleDoc for epydoc_test [0]
+ +- variables
+ +- match => VariableDoc for epydoc_test.match [1]
+ +- value
+ +- ValueDoc for sre.match [2]
+
+
+Specifying constructor signature in class docstring
+===================================================
+
+The class signature can be specified in the class docstring instead of __init__
+
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... @param a: init param.
+ ... @ivar a: instance var.
+ ... @type a: date
+ ... """
+ ... def __init__(self, a):
+ ... """The ctor docstring.
+ ...
+ ... @type a: str
+ ... """
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ | +- name = '__init__'
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ | +- arg_descrs = [([u'a'], ...
+ | +- arg_types = {u'a': ...
+ | +- kwarg = None
+ | +- posargs = ['self', 'a']
+ | +- vararg = None
+ +- a => VariableDoc for epydoc_test.Foo.a [3]
+ +- name = u'a'
+ +- value = <UNKNOWN>
+
+Also keywords arguments can be put in the constructor
+
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... @keyword a: a kwarg.
+ ... @type a: str
+ ... """
+ ... def __init__(self, **kwargs):
+ ... """The ctor docstring.
+ ...
+ ... @type a: str
+ ... """
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ +- name = '__init__'
+ +- value
+ +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ +- arg_descrs = [([u'a'], ...
+ +- arg_types = {u'a': ...
+ +- kwarg = 'kwargs'
+ +- posargs = ['self']
+ +- vararg = None
+
+A missing docstring on the __init__ is not an issue.
+
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... @param a: a param.
+ ... @type a: str
+ ... """
+ ... def __init__(self):
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ +- name = '__init__'
+ +- value
+ +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ +- arg_descrs = [([u'a'], ...
+ +- arg_types = {u'a': ...
+ +- kwarg = None
+ +- posargs = ['self']
+ +- vararg = None
+
+Exceptions can be put in the docstring class, and they are assigned to the
+constructor too.
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """Foo(x, y)
+ ...
+ ... A class to ship rockets in outer space.
+ ...
+ ... @param x: first param
+ ... @param y: second param
+ ... @except ValueError: frobnication error
+ ... """
+ ... def __init__(self, a, b):
+ ... """__init__ doc"""
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value exception_descrs "
+ ... "posargs vararg kwarg type arg_types arg_descrs docstring")
+ ClassDoc for epydoc_test.Foo [0]
+ +- docstring = u'A class to ship rockets in outer sp...
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ +- docstring = <UNKNOWN>
+ +- name = '__init__'
+ +- value
+ +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ +- arg_descrs = [([u'x'], [u'first', u'param']), ...
+ +- arg_types = {}
+ +- docstring = u'__init__ doc'
+ +- exception_descrs = [(DottedName(u'ValueError'), ...
+ +- kwarg = None
+ +- posargs = [u'x', u'y']
+ +- vararg = None
+
+
+Epydoc can also grok the constructor signature from the class docstring
+
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """Foo(x, y)
+ ...
+ ... A class to ship rockets in outer space.
+ ...
+ ... @param x: first param
+ ... @param y: second param
+ ... """
+ ... def __init__(self, a, b):
+ ... """__init__ doc"""
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type arg_types arg_descrs docstring")
+ ClassDoc for epydoc_test.Foo [0]
+ +- docstring = u'A class to ship rockets ...
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ +- docstring = <UNKNOWN>
+ +- name = '__init__'
+ +- value
+ +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ +- arg_descrs = [([u'x'], ...
+ +- arg_types = {}
+ +- docstring = u'__init__ doc'
+ +- kwarg = None
+ +- posargs = [u'x', u'y']
+ +- vararg = None
+
+A type can apply to both a param and a variable
+
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... @param a: init param.
+ ... @ivar a: instance var.
+ ... @type a: date
+ ... """
+ ... def __init__(self, a):
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type_descr arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ | +- name = '__init__'
+ | +- type_descr = None
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ | +- arg_descrs = [([u'a'], [u'init', u'param.'])]
+ | +- arg_types = {u'a': [u'date']}
+ | +- kwarg = None
+ | +- posargs = ['self', 'a']
+ | +- vararg = None
+ +- a => VariableDoc for epydoc_test.Foo.a [3]
+ +- name = u'a'
+ +- type_descr = u'date\n\n'
+ +- value = <UNKNOWN>
+
+But there can also be two different types
+
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... @param a: init param.
+ ... @type a: string
+ ... @ivar a: instance var.
+ ... @type a: date
+ ... """
+ ... def __init__(self, a):
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type_descr arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ | +- name = '__init__'
+ | +- type_descr = None
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ | +- arg_descrs = [([u'a'], [u'init', u'param.'])]
+ | +- arg_types = {u'a': [u'string']}
+ | +- kwarg = None
+ | +- posargs = ['self', 'a']
+ | +- vararg = None
+ +- a => VariableDoc for epydoc_test.Foo.a [3]
+ +- name = u'a'
+ +- type_descr = u'date\n\n'
+ +- value = <UNKNOWN>
+
+Also reST consolidated fields are not a problem.
+
+ >>> runbuilder(s='''
+ ... __docformat__ = 'restructuredtext'
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... :Parameters:
+ ... `a` : string
+ ... init param.
+ ...
+ ... :Exceptions:
+ ... * `ValueError`: frobnication error
+ ... init param.
+ ...
+ ... :IVariables:
+ ... `a` : date
+ ... instance var.
+ ... """
+ ... def __init__(self, a):
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value exception_descrs "
+ ... "posargs vararg kwarg type_descr arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ | +- name = '__init__'
+ | +- type_descr = None
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ | +- arg_descrs = [([u'a'], [u'init', u'param.'])]
+ | +- arg_types = {u'a': [u'string']}
+ | +- exception_descrs = [(DottedName(u'ValueError'), ...
+ | +- kwarg = None
+ | +- posargs = ['self', 'a']
+ | +- vararg = None
+ +- a => VariableDoc for epydoc_test.Foo.a [3]
+ +- name = u'a'
+ +- type_descr = u'date'
+ +- value = <UNKNOWN>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-16 12:57:21
|
Revision: 1395
http://svn.sourceforge.net/epydoc/?rev=1395&view=rev
Author: dvarrazzo
Date: 2006-09-16 05:57:14 -0700 (Sat, 16 Sep 2006)
Log Message:
-----------
- Class docstring fields are passed to __init__ without using an extra ClassDoc
attribute.
- Some docstring fixed.
Modified Paths:
--------------
branches/exp-args_in_class/epydoc/src/epydoc/apidoc.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-16 00:20:06 UTC (rev 1394)
+++ branches/exp-args_in_class/epydoc/src/epydoc/apidoc.py 2006-09-16 12:57:14 UTC (rev 1395)
@@ -1118,10 +1118,6 @@
"""@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/docstringparser.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-16 00:20:06 UTC (rev 1394)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-16 12:57:14 UTC (rev 1395)
@@ -168,18 +168,16 @@
user docfields defined by containing objects.
"""
if api_doc.metadata is not UNKNOWN:
- log.debug("%s's docstring processed twice" % api_doc.canonical_name)
+ if not (isinstance(api_doc, RoutineDoc)
+ and api_doc.canonical_name[-1] == '__init__'):
+ log.debug("%s's docstring processed twice" % api_doc.canonical_name)
return
initialize_api_doc(api_doc)
# If there's no docstring, then there's nothing more to do.
- # ...except in a case: an __init__ function that is to receive some
- # documentation from the class docstring
if (api_doc.docstring in (None, UNKNOWN)):
- if not (isinstance(api_doc, RoutineDoc)
- and api_doc.canonical_name[-1] == '__init__'):
- return
+ return
# Remove leading indentation from the docstring.
api_doc.docstring = unindent_docstring(api_doc.docstring)
@@ -188,10 +186,6 @@
# overrides any signature we got via introspection/parsing.
if isinstance(api_doc, RoutineDoc):
parse_function_signature(api_doc)
- elif isinstance(api_doc, ClassDoc):
- initvar = api_doc.variables.get('__init__')
- if initvar:
- parse_function_signature(initvar.value, api_doc)
# Parse the docstring. Any errors encountered are stored as
# `ParseError` objects in the errors list.
@@ -211,14 +205,23 @@
# docstring. This code assumes that a class docstring is parsed before
# the same class __init__ docstring.
if isinstance(api_doc, ClassDoc):
- split_init_fields(fields, api_doc.init_args, field_warnings)
- elif (isinstance(api_doc, RoutineDoc)
- and api_doc.canonical_name[-1] == '__init__'):
- class_doc = docindex.get_valdoc(api_doc.canonical_name[:-1])
- if class_doc is not None and class_doc.init_args is not UNKNOWN:
- fields.extend(class_doc.init_args)
+ # Parse ahead the __init__ docstring for this class
+ initvar = api_doc.variables.get('__init__')
+ if initvar and initvar.value not in (None, UNKNOWN):
+ init_api_doc = initvar.value
+ parse_docstring(init_api_doc, docindex)
+ parse_function_signature(init_api_doc, api_doc)
+ init_fields = split_init_fields(fields, field_warnings)
+
+ # Process fields
+ for field in init_fields:
+ try:
+ process_field(init_api_doc, docindex, field.tag(),
+ field.arg(), field.body())
+ except ValueError, e: field_warnings.append(str(e))
+
# Process fields
for field in fields:
try:
@@ -255,9 +258,6 @@
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 = []
@@ -278,13 +278,20 @@
if api_doc.sort_spec is UNKNOWN:
api_doc.sort_spec = []
-def split_init_fields(fields, init_fields, warnings):
+def split_init_fields(fields, warnings):
"""
- Move the fields related to init into a different list.
- C{fields} is supposed obtained from a class docstring. Remove
- fields not related to the class from it and add them to C{init_fields},
- which is a list of constructor fields.
+ Remove the fields related to the constructor from a class docstring
+ fields list.
+
+ @param fields: The fields to process. The list will be modified in place
+ @type fields: C{list} of L{markup.Field}
+ @param warnings: A list to emit processing warnings
+ @type warnings: C{list}
+ @return: The C{fields} items to be applied to the C{__init__} method
+ @rtype: C{list} of L{markup.Field}
"""
+ init_fields = []
+
# Split fields in lists according to their argument, keeping order.
arg_fields = {}
args_order = []
@@ -354,6 +361,8 @@
else:
pass # [xx] warn about type w/o object?
+ return init_fields
+
def report_errors(api_doc, docindex, parse_errors, field_warnings):
"""A helper function for L{parse_docstring()} that reports any
markup warnings and field warnings that we encountered while
@@ -902,10 +911,10 @@
@param func_doc: The target object where to store parsed signature. Also
container of the docstring to parse if doc_source is C{None}
- @type L{RoutineDoc}
+ @type func_doc: L{RoutineDoc}
@param doc_source: Contains the docstring to parse. If C{None}, parse
L{func_doc} docstring instead
- @type L{APIDoc}
+ @type doc_source: L{APIDoc}
@rtype: C{None}
"""
if doc_source is None:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-16 00:20:11
|
Revision: 1394
http://svn.sourceforge.net/epydoc/?rev=1394&view=rev
Author: dvarrazzo
Date: 2006-09-15 17:20:06 -0700 (Fri, 15 Sep 2006)
Log Message:
-----------
- Reverting type fields handling to trunk behavior.
Modified Paths:
--------------
branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-16 00:02:10 UTC (rev 1393)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-16 00:20:06 UTC (rev 1394)
@@ -764,7 +764,6 @@
api_doc.variables[ident] = VariableDoc(
container=api_doc, name=ident,
canonical_name=api_doc.canonical_name+ident)
- return
var_doc = api_doc.variables[ident]
if var_doc.type_descr not in (None, UNKNOWN):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-16 00:02:18
|
Revision: 1393
http://svn.sourceforge.net/epydoc/?rev=1393&view=rev
Author: dvarrazzo
Date: 2006-09-15 17:02:10 -0700 (Fri, 15 Sep 2006)
Log Message:
-----------
- Reverted updates to `process_arg_field()` handler: is context is always a
function, not the class docstring.
- Exceptions are handled in the class docstring as well.
- More explicit name of some variables.
Modified Paths:
--------------
branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-15 23:36:23 UTC (rev 1392)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-16 00:02:10 UTC (rev 1393)
@@ -308,7 +308,7 @@
var = tvar = par = tpar = None
for field in ff:
- if field.tag() in VAR_TAGS:
+ if field.tag() in VARIABLE_TAGS:
if var is None:
var = field
fields.append(field)
@@ -316,7 +316,7 @@
warnings.append(
"There is more than one variable named '%s'"
% arg)
- elif field.tag() in PARAM_TAGS:
+ elif field.tag() in PARAMETER_TAGS:
if par is None:
par = field
init_fields.append(field)
@@ -335,6 +335,9 @@
if par is not None and tpar is None:
tpar = field
+ elif field.tag() in EXCEPTION_TAGS:
+ init_fields.append(field)
+
else: # Unespected field
fields.append(field)
@@ -683,24 +686,15 @@
api_doc.return_type = descr
def process_arg_field(api_doc, docindex, tag, arg, descr):
- _check(api_doc, tag, arg, context=(ClassDoc, RoutineDoc), expect_arg=True)
+ _check(api_doc, tag, arg, context=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??
@@ -727,13 +721,15 @@
'except', 'exception')
# Tags related to function parameters
-PARAM_TAGS = ('arg', 'argument', 'parameter', 'param',
- 'kwarg', 'keyword', 'kwparam')
+PARAMETER_TAGS = ('arg', 'argument', 'parameter', 'param',
+ 'kwarg', 'keyword', 'kwparam')
# Tags related to variables in a class
-VAR_TAGS = ('cvar', 'cvariable',
- 'ivar', 'ivariable')
+VARIABLE_TAGS = ('cvar', 'cvariable', 'ivar', 'ivariable')
+# Tags related to exceptions
+EXCEPTION_TAGS = ('raise', 'raises', 'except', 'exception')
+
######################################################################
#{ Helper Functions
######################################################################
Modified: branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest 2006-09-15 23:36:23 UTC (rev 1392)
+++ branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest 2006-09-16 00:02:10 UTC (rev 1393)
@@ -245,6 +245,42 @@
+- posargs = ['self']
+- vararg = None
+Exceptions can be put in the docstring class, and they are assigned to the
+constructor too.
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """Foo(x, y)
+ ...
+ ... A class to ship rockets in outer space.
+ ...
+ ... @param x: first param
+ ... @param y: second param
+ ... @except ValueError: frobnication error
+ ... """
+ ... def __init__(self, a, b):
+ ... """__init__ doc"""
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value exception_descrs "
+ ... "posargs vararg kwarg type arg_types arg_descrs docstring")
+ ClassDoc for epydoc_test.Foo [0]
+ +- docstring = u'A class to ship rockets in outer sp...
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ +- docstring = <UNKNOWN>
+ +- name = '__init__'
+ +- value
+ +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ +- arg_descrs = [([u'x'], [u'first', u'param']), ...
+ +- arg_types = {}
+ +- docstring = u'__init__ doc'
+ +- exception_descrs = [(DottedName(u'ValueError'), ...
+ +- kwarg = None
+ +- posargs = [u'x', u'y']
+ +- vararg = None
+
+
Epydoc can also grok the constructor signature from the class docstring
>>> runbuilder(s='''
@@ -356,6 +392,10 @@
... `a` : string
... init param.
...
+ ... :Exceptions:
+ ... * `ValueError`: frobnication error
+ ... init param.
+ ...
... :IVariables:
... `a` : date
... instance var.
@@ -364,7 +404,7 @@
... pass
... ''',
... build="Foo",
- ... attribs="variables name value "
+ ... attribs="variables name value exception_descrs "
... "posargs vararg kwarg type_descr arg_types arg_descrs")
ClassDoc for epydoc_test.Foo [0]
+- variables
@@ -375,6 +415,7 @@
| +- RoutineDoc for epydoc_test.Foo.__init__ [2]
| +- arg_descrs = [([u'a'], [u'init', u'param.'])]
| +- arg_types = {u'a': [u'string']}
+ | +- exception_descrs = [(DottedName(u'ValueError'), ...
| +- kwarg = None
| +- posargs = ['self', 'a']
| +- vararg = None
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-15 23:36:31
|
Revision: 1392
http://svn.sourceforge.net/epydoc/?rev=1392&view=rev
Author: dvarrazzo
Date: 2006-09-15 16:36:23 -0700 (Fri, 15 Sep 2006)
Log Message:
-----------
- Be more lenient about types specified before matching objects.
Modified Paths:
--------------
branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-15 02:24:11 UTC (rev 1391)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-15 23:36:23 UTC (rev 1392)
@@ -313,33 +313,44 @@
var = field
fields.append(field)
else:
- warnings.append("there are more variables "
- "named '%s'" % arg)
+ warnings.append(
+ "There is more than one variable named '%s'"
+ % arg)
elif field.tag() in PARAM_TAGS:
if par is None:
par = field
init_fields.append(field)
else:
- warnings.append("there are more parameters "
- "named '%s'" % arg)
+ warnings.append(
+ "There is more than one parameter named '%s'"
+ % arg)
elif field.tag() == 'type':
- gone = False
- if var is not None and tvar is None:
- tvar = field
- fields.append(field)
- gone = True
- if par is not None and tpar is None:
- tpar = field
- init_fields.append(field)
- gone = True
- if not gone:
- warnings.append("type for '%s' doesn't apply "
- "to any variable or argument" % arg)
+ if var is None and par is None:
+ # type before obj
+ tvar = tpar = field
+ else:
+ if var is not None and tvar is None:
+ tvar = field
+ if par is not None and tpar is None:
+ tpar = field
else: # Unespected field
fields.append(field)
+ # Put selected types into the proper output lists
+ if tvar is not None:
+ if var is not None:
+ fields.append(tvar)
+ else:
+ pass # [xx] warn about type w/o object?
+
+ if tpar is not None:
+ if par is not None:
+ init_fields.append(tpar)
+ else:
+ pass # [xx] warn about type w/o object?
+
def report_errors(api_doc, docindex, parse_errors, field_warnings):
"""A helper function for L{parse_docstring()} that reports any
markup warnings and field warnings that we encountered while
@@ -754,15 +765,9 @@
def set_var_type(api_doc, ident, descr):
if ident not in api_doc.variables:
- # [xx] If there is a type w/o matching var, this would create
- # a new var. The behavior is to be decied consistently also in other
- # places in this sources (grep for [xx]).
- # Currently disable the creation or else each "type" used in the
- # class docstring to describe an __init__ parameter also generates
- # an extra class variable.
- #api_doc.variables[ident] = VariableDoc(
- #container=api_doc, name=ident,
- #canonical_name=api_doc.canonical_name+ident)
+ api_doc.variables[ident] = VariableDoc(
+ container=api_doc, name=ident,
+ canonical_name=api_doc.canonical_name+ident)
return
var_doc = api_doc.variables[ident]
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-15 02:24:16
|
Revision: 1391
http://svn.sourceforge.net/epydoc/?rev=1391&view=rev
Author: dvarrazzo
Date: 2006-09-14 19:24:11 -0700 (Thu, 14 Sep 2006)
Log Message:
-----------
- Splitting argument refactored into a single distinct function.
Modified Paths:
--------------
branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-15 01:47:53 UTC (rev 1390)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-15 02:24:11 UTC (rev 1391)
@@ -211,62 +211,8 @@
# docstring. This code assumes that a class docstring is parsed before
# the same class __init__ docstring.
if isinstance(api_doc, ClassDoc):
+ split_init_fields(fields, api_doc.init_args, field_warnings)
- # Split fields in lists according to their argument
- arg_fields = {}
- args_order = []
- i = 0
- while i < len(fields):
- field = fields[i]
-
- # gather together all the fields with the same arg
- if field.arg() is not None:
- arg_fields.setdefault(field.arg(), []).append(fields.pop(i))
- args_order.append(field.arg())
- else:
- i += 1
-
- # Now check that for each argument there is at most a single variable
- # and a single argument, and a single type for them.
- for arg in args_order:
- ff = arg_fields.pop(arg, None)
- if ff is None:
- continue
-
- var = tvar = par = tpar = None
- for field in ff:
- if field.tag() in VAR_TAGS:
- if var is None:
- var = field
- fields.append(field)
- else:
- field_warnings.append("there are more variables "
- "named '%s'" % arg)
- elif field.tag() in PARAM_TAGS:
- if par is None:
- par = field
- api_doc.init_args.append(field)
- else:
- field_warnings.append("there are more parameters "
- "named '%s'" % arg)
-
- elif field.tag() == 'type':
- gone = False
- if var is not None and tvar is None:
- tvar = field
- fields.append(field)
- gone = True
- if par is not None and tpar is None:
- tpar = field
- api_doc.init_args.append(field)
- gone = True
- if not gone:
- field_warnings.append("type for '%s' doesn't apply "
- "to any variable or argument" % arg)
-
- else: # Unespected field
- fields.append(field)
-
elif (isinstance(api_doc, RoutineDoc)
and api_doc.canonical_name[-1] == '__init__'):
class_doc = docindex.get_valdoc(api_doc.canonical_name[:-1])
@@ -332,6 +278,68 @@
if api_doc.sort_spec is UNKNOWN:
api_doc.sort_spec = []
+def split_init_fields(fields, init_fields, warnings):
+ """
+ Move the fields related to init into a different list.
+ C{fields} is supposed obtained from a class docstring. Remove
+ fields not related to the class from it and add them to C{init_fields},
+ which is a list of constructor fields.
+ """
+ # Split fields in lists according to their argument, keeping order.
+ arg_fields = {}
+ args_order = []
+ i = 0
+ while i < len(fields):
+ field = fields[i]
+
+ # gather together all the fields with the same arg
+ if field.arg() is not None:
+ arg_fields.setdefault(field.arg(), []).append(fields.pop(i))
+ args_order.append(field.arg())
+ else:
+ i += 1
+
+ # Now check that for each argument there is at most a single variable
+ # and a single parameter, and at most a single type for each of them.
+ for arg in args_order:
+ ff = arg_fields.pop(arg, None)
+ if ff is None:
+ continue
+
+ var = tvar = par = tpar = None
+ for field in ff:
+ if field.tag() in VAR_TAGS:
+ if var is None:
+ var = field
+ fields.append(field)
+ else:
+ warnings.append("there are more variables "
+ "named '%s'" % arg)
+ elif field.tag() in PARAM_TAGS:
+ if par is None:
+ par = field
+ init_fields.append(field)
+ else:
+ warnings.append("there are more parameters "
+ "named '%s'" % arg)
+
+ elif field.tag() == 'type':
+ gone = False
+ if var is not None and tvar is None:
+ tvar = field
+ fields.append(field)
+ gone = True
+ if par is not None and tpar is None:
+ tpar = field
+ init_fields.append(field)
+ gone = True
+ if not gone:
+ warnings.append("type for '%s' doesn't apply "
+ "to any variable or argument" % arg)
+
+ else: # Unespected field
+ fields.append(field)
+
def report_errors(api_doc, docindex, parse_errors, field_warnings):
"""A helper function for L{parse_docstring()} that reports any
markup warnings and field warnings that we encountered while
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-15 01:48:02
|
Revision: 1390
http://svn.sourceforge.net/epydoc/?rev=1390&view=rev
Author: dvarrazzo
Date: 2006-09-14 18:47:53 -0700 (Thu, 14 Sep 2006)
Log Message:
-----------
- Checked in a new algorithm to split fields in the class docstring between
class documentation and constructor documentation. The algorithm requires
the `type` fields to appear after the related fields.
- Added more test.
Modified Paths:
--------------
branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-14 21:37:38 UTC (rev 1389)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docstringparser.py 2006-09-15 01:47:53 UTC (rev 1390)
@@ -205,39 +205,75 @@
descr, fields = parsed_docstring.split_fields(parse_errors)
api_doc.descr = descr
+ field_warnings = []
+
# 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')
+
+ # Split fields in lists according to their argument
+ arg_fields = {}
+ args_order = []
i = 0
while i < len(fields):
field = fields[i]
- if field.tag() in param_tags:
- api_doc.init_args.append(fields.pop(i))
+
+ # gather together all the fields with the same arg
+ if field.arg() is not None:
+ arg_fields.setdefault(field.arg(), []).append(fields.pop(i))
+ args_order.append(field.arg())
+ else:
+ i += 1
+
+ # Now check that for each argument there is at most a single variable
+ # and a single argument, and a single type for them.
+ for arg in args_order:
+ ff = arg_fields.pop(arg, None)
+ if ff is None:
continue
- elif field.tag() == 'type':
- api_doc.init_args.append(field)
- i += 1
+ var = tvar = par = tpar = None
+ for field in ff:
+ if field.tag() in VAR_TAGS:
+ if var is None:
+ var = field
+ fields.append(field)
+ else:
+ field_warnings.append("there are more variables "
+ "named '%s'" % arg)
+ elif field.tag() in PARAM_TAGS:
+ if par is None:
+ par = field
+ api_doc.init_args.append(field)
+ else:
+ field_warnings.append("there are more parameters "
+ "named '%s'" % arg)
+
+ elif field.tag() == 'type':
+ gone = False
+ if var is not None and tvar is None:
+ tvar = field
+ fields.append(field)
+ gone = True
+ if par is not None and tpar is None:
+ tpar = field
+ api_doc.init_args.append(field)
+ gone = True
+ if not gone:
+ field_warnings.append("type for '%s' doesn't apply "
+ "to any variable or argument" % arg)
+
+ else: # Unespected field
+ fields.append(field)
+
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.
+ and api_doc.canonical_name[-1] == '__init__'):
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)
+ fields.extend(class_doc.init_args)
# Process fields
- field_warnings = []
for field in fields:
try:
process_field(api_doc, docindex, field.tag(),
@@ -671,6 +707,14 @@
register_field_handler(process_raise_field, 'raise', 'raises',
'except', 'exception')
+# Tags related to function parameters
+PARAM_TAGS = ('arg', 'argument', 'parameter', 'param',
+ 'kwarg', 'keyword', 'kwparam')
+
+# Tags related to variables in a class
+VAR_TAGS = ('cvar', 'cvariable',
+ 'ivar', 'ivariable')
+
######################################################################
#{ Helper Functions
######################################################################
Modified: branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest 2006-09-14 21:37:38 UTC (rev 1389)
+++ branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest 2006-09-15 01:47:53 UTC (rev 1390)
@@ -14,6 +14,22 @@
>>> import tempfile, re, os, os.path, textwrap, sys
>>> from epydoc.docbuilder import build_doc
+ >>> from epydoc.apidoc import ClassDoc, RoutineDoc
+ >>> from epydoc.markup import ParsedDocstring
+
+ >>> def to_plain(docstring):
+ ... """Conver a parsed docstring into plain text"""
+ ... if isinstance(docstring, ParsedDocstring):
+ ... docstring = docstring.to_plaintext(None)
+ ... return docstring.rsplit()
+
+ >>> def fun_to_plain(val_doc):
+ ... """Convert parsed docstrings in text from a RoutineDoc"""
+ ... for k, v in val_doc.arg_types.items():
+ ... val_doc.arg_types[k] = to_plain(v)
+ ... for i, (k, v) in enumerate(val_doc.arg_descrs):
+ ... val_doc.arg_descrs[i] = (k, to_plain(v))
+
>>> def runbuilder(s, attribs='', build=None, exclude=''):
... # Write it to a temp file.
... tmp_dir = tempfile.mkdtemp()
@@ -24,6 +40,10 @@
... val_doc = build_doc(os.path.join(tmp_dir, 'epydoc_test.py'))
... if build: val_doc = val_doc.variables[build].value
... # Display it.
+ ... if isinstance(val_doc, ClassDoc):
+ ... for val in val_doc.variables.values():
+ ... if isinstance(val.value, RoutineDoc):
+ ... fun_to_plain(val.value)
... s = val_doc.pp(include=attribs.split(),exclude=exclude.split())
... s = re.sub(r"(filename = ).*", r"\1...", s)
... s = re.sub(r"(<module 'epydoc_test' from ).*", r'\1...', s)
@@ -116,11 +136,18 @@
+- descr = u'A property has no defining module'
+- type_descr = u'int'
+Stuff from future doesn't appear as variable.
+
>>> runbuilder(s="""
... from __future__ import division
... from re import match
... """,
... attribs='variables value')
+ ModuleDoc for epydoc_test [0]
+ +- variables
+ +- match => VariableDoc for epydoc_test.match [1]
+ +- value
+ +- ValueDoc for sre.match [2]
Specifying constructor signature in class docstring
@@ -143,7 +170,7 @@
... """
... pass
... ''',
- ... introspect="Foo",
+ ... build="Foo",
... attribs="variables name value "
... "posargs vararg kwarg type arg_types arg_descrs")
ClassDoc for epydoc_test.Foo [0]
@@ -176,7 +203,7 @@
... @type a: str
... """
... ''',
- ... introspect="Foo",
+ ... build="Foo",
... attribs="variables name value "
... "posargs vararg kwarg type arg_types arg_descrs")
ClassDoc for epydoc_test.Foo [0]
@@ -192,6 +219,7 @@
+- vararg = None
A missing docstring on the __init__ is not an issue.
+
>>> runbuilder(s='''
... class Foo:
... """This is the object docstring
@@ -202,7 +230,7 @@
... def __init__(self):
... pass
... ''',
- ... introspect="Foo",
+ ... build="Foo",
... attribs="variables name value "
... "posargs vararg kwarg type arg_types arg_descrs")
ClassDoc for epydoc_test.Foo [0]
@@ -232,7 +260,7 @@
... """__init__ doc"""
... pass
... ''',
- ... introspect="Foo",
+ ... build="Foo",
... attribs="variables name value "
... "posargs vararg kwarg type arg_types arg_descrs docstring")
ClassDoc for epydoc_test.Foo [0]
@@ -249,3 +277,108 @@
+- kwarg = None
+- posargs = [u'x', u'y']
+- vararg = None
+
+A type can apply to both a param and a variable
+
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... @param a: init param.
+ ... @ivar a: instance var.
+ ... @type a: date
+ ... """
+ ... def __init__(self, a):
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type_descr arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ | +- name = '__init__'
+ | +- type_descr = None
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ | +- arg_descrs = [([u'a'], [u'init', u'param.'])]
+ | +- arg_types = {u'a': [u'date']}
+ | +- kwarg = None
+ | +- posargs = ['self', 'a']
+ | +- vararg = None
+ +- a => VariableDoc for epydoc_test.Foo.a [3]
+ +- name = u'a'
+ +- type_descr = u'date\n\n'
+ +- value = <UNKNOWN>
+
+But there can also be two different types
+
+ >>> runbuilder(s='''
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... @param a: init param.
+ ... @type a: string
+ ... @ivar a: instance var.
+ ... @type a: date
+ ... """
+ ... def __init__(self, a):
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type_descr arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ | +- name = '__init__'
+ | +- type_descr = None
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ | +- arg_descrs = [([u'a'], [u'init', u'param.'])]
+ | +- arg_types = {u'a': [u'string']}
+ | +- kwarg = None
+ | +- posargs = ['self', 'a']
+ | +- vararg = None
+ +- a => VariableDoc for epydoc_test.Foo.a [3]
+ +- name = u'a'
+ +- type_descr = u'date\n\n'
+ +- value = <UNKNOWN>
+
+Also reST consolidated fields are not a problem.
+
+ >>> runbuilder(s='''
+ ... __docformat__ = 'restructuredtext'
+ ... class Foo:
+ ... """This is the object docstring
+ ...
+ ... :Parameters:
+ ... `a` : string
+ ... init param.
+ ...
+ ... :IVariables:
+ ... `a` : date
+ ... instance var.
+ ... """
+ ... def __init__(self, a):
+ ... pass
+ ... ''',
+ ... build="Foo",
+ ... attribs="variables name value "
+ ... "posargs vararg kwarg type_descr arg_types arg_descrs")
+ ClassDoc for epydoc_test.Foo [0]
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ | +- name = '__init__'
+ | +- type_descr = None
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ | +- arg_descrs = [([u'a'], [u'init', u'param.'])]
+ | +- arg_types = {u'a': [u'string']}
+ | +- kwarg = None
+ | +- posargs = ['self', 'a']
+ | +- vararg = None
+ +- a => VariableDoc for epydoc_test.Foo.a [3]
+ +- name = u'a'
+ +- type_descr = u'date'
+ +- value = <UNKNOWN>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-14 21:37:55
|
Revision: 1389
http://svn.sourceforge.net/epydoc/?rev=1389&view=rev
Author: dvarrazzo
Date: 2006-09-14 14:37:38 -0700 (Thu, 14 Sep 2006)
Log Message:
-----------
Merged revisions 1376-1388 via svnmerge from
https://svn.sourceforge.net/svnroot/epydoc/trunk
........
r1377 | edloper | 2006-09-10 16:29:31 +0200 (Sun, 10 Sep 2006) | 4 lines
- Fixed bug where base tree generation would fail if the context
was UNKNOWN (e.g., if we can't determine what the containing
module is.)
........
r1378 | dvarrazzo | 2006-09-10 17:16:41 +0200 (Sun, 10 Sep 2006) | 2 lines
Fixed typo.
........
r1379 | dvarrazzo | 2006-09-10 18:23:49 +0200 (Sun, 10 Sep 2006) | 15 lines
- Don't strip empty lines from documentation comment blocks.
Without the patch, a block such::
#: frobnication factor
#:
#: :type: ``int``
is transformed in the string::
frobnication factor
:type: ``int``
that is a docstring error (the field is not recognized).
........
r1380 | dvarrazzo | 2006-09-10 18:31:38 +0200 (Sun, 10 Sep 2006) | 6 lines
- defining_module is propagated to object which don't have other means
to detect it, such as properties. So docformat can be correctly detected
for such objects too.
- Added a test suite to verify docbuilder behavior.
........
r1381 | edloper | 2006-09-11 00:43:02 +0200 (Mon, 11 Sep 2006) | 4 lines
- When checking keyword args to APIDoc constructor, don't complain
about args that begin with '_'.
- Minor docstring changes
........
r1382 | edloper | 2006-09-11 00:43:51 +0200 (Mon, 11 Sep 2006) | 3 lines
- When building stdlib docs, don't include any graphs or source code --
the quota on sourceforge won't allow enough space for them. :(
........
r1383 | dvarrazzo | 2006-09-11 14:34:31 +0200 (Mon, 11 Sep 2006) | 6 lines
- Fixed docutils version check.
E.g. when docutils.__version__ == '0.4'
=> [ 0, 4 ] < [ 0, 4, 0 ] == True
=> Deprecation warnings are raised.
........
r1384 | dvarrazzo | 2006-09-11 15:42:10 +0200 (Mon, 11 Sep 2006) | 9 lines
- Introspecter doesn't document the object resulting from a "from __future__"
statement.
Because the check deals with the implementation of a quasi-magic module,
guard from unexpected implementation changes. In such case, issue a single
warning and don't barf.
The current implementation is tested with Python 2.4.3.
........
r1385 | dvarrazzo | 2006-09-11 15:45:12 +0200 (Mon, 11 Sep 2006) | 2 lines
- Replaced a "!= None" test with an "is not None"
........
r1386 | dvarrazzo | 2006-09-11 18:12:51 +0200 (Mon, 11 Sep 2006) | 4 lines
- Fixed parsing of import statements in the form::
from mod import a as b
........
r1387 | dvarrazzo | 2006-09-13 05:04:00 +0200 (Wed, 13 Sep 2006) | 3 lines
- Added a filter to remove the class vtable generated by Pyrex for
extension modules.
........
r1388 | dvarrazzo | 2006-09-13 05:24:38 +0200 (Wed, 13 Sep 2006) | 2 lines
- member_descriptor attributes are recognized as property.
........
Modified Paths:
--------------
branches/exp-args_in_class/epydoc/Makefile
branches/exp-args_in_class/epydoc/doc/doctest/index.html
branches/exp-args_in_class/epydoc/doc/fields.html
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/docintrospecter.py
branches/exp-args_in_class/epydoc/src/epydoc/docparser.py
branches/exp-args_in_class/epydoc/src/epydoc/docwriter/html.py
branches/exp-args_in_class/epydoc/src/epydoc/markup/restructuredtext.py
branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest
branches/exp-args_in_class/epydoc/src/epydoc/test/docintrospecter.doctest
branches/exp-args_in_class/epydoc/src/epydoc/test/docparser.doctest
Property Changed:
----------------
branches/exp-args_in_class/
Property changes on: branches/exp-args_in_class
___________________________________________________________________
Name: svnmerge-integrated
- /trunk:1-1375
+ /trunk:1-1388
Modified: branches/exp-args_in_class/epydoc/Makefile
===================================================================
--- branches/exp-args_in_class/epydoc/Makefile 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/Makefile 2006-09-14 21:37:38 UTC (rev 1389)
@@ -235,7 +235,7 @@
mkdir -p $(HTML_STDLIB)
@echo "Building stdlib html docs..."
@$(EPYDOC) -o $(HTML_STDLIB) --css white --name $(SLNAME) \
- --url $(SLURL) --debug --graph classtree --debug \
+ --url $(SLURL) --debug --no-sourcecode --debug \
--show-imports $(SLBUILTINS) $(SLFILES)
touch .stdlib-html.up2date
Modified: branches/exp-args_in_class/epydoc/doc/doctest/index.html
===================================================================
--- branches/exp-args_in_class/epydoc/doc/doctest/index.html 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/doc/doctest/index.html 2006-09-14 21:37:38 UTC (rev 1389)
@@ -27,6 +27,9 @@
<li> <a href="docparser.html">Source Code Parsing</a> --
Extracting API information about Python objects by parsing
their source code.</li>
+ <li> <a href="docbuilder.html">Documentation building</a> --
+ Merging different information sources into a single API
+ hypertext.
<li> <a href="encoding.html">Unicode & Encodings</a> --
Tests for the processing of Python files that use non-ascii
encodings. </li>
Modified: branches/exp-args_in_class/epydoc/doc/fields.html
===================================================================
--- branches/exp-args_in_class/epydoc/doc/fields.html 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/doc/fields.html 2006-09-14 21:37:38 UTC (rev 1389)
@@ -262,7 +262,7 @@
fields may be used if an object has multiple authors.</td></tr>
<tr><td width="10%" align="left" valign="top">
- <code>@<b>organiation</b>:</code> ... </td><td> The
+ <code>@<b>organization</b>:</code> ... </td><td> The
organization that created or maintains an
object. </td></tr>
Modified: branches/exp-args_in_class/epydoc/src/epydoc/apidoc.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/apidoc.py 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/apidoc.py 2006-09-14 21:37:38 UTC (rev 1389)
@@ -374,7 +374,7 @@
"""
if epydoc.DEBUG:
for key in kwargs:
- if not hasattr(self.__class__, key):
+ if key[0] != '_' and not hasattr(self.__class__, key):
raise TypeError('%s got unexpected arg %r' %
(self.__class__.__name__, key))
self.__dict__.update(kwargs)
@@ -850,7 +850,7 @@
names, and the values are lists of C{VariableDoc}s. The order
that groups should be listed in should be taken from
L{group_specs}.
- @type: C{dict} from C{str} to C{list} of L{APIDoc}"""
+ @type: C{dict} from C{str} to C{list} of L{VariableDoc}"""
#} end of group "information about variables"
def __init__(self, **kwargs):
@@ -996,7 +996,7 @@
names, and the values are lists of C{ModuleDoc}s. The order
that groups should be listed in should be taken from
L{group_specs}.
- @type: C{dict} from C{str} to C{list} of L{APIDoc}"""
+ @type: C{dict} from C{str} to C{list} of L{ModuleDoc}"""
#{ Information about Packages
package = UNKNOWN
"""@ivar: API documentation for the module's containing package.
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docbuilder.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docbuilder.py 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docbuilder.py 2006-09-14 21:37:38 UTC (rev 1389)
@@ -191,6 +191,12 @@
if (isinstance(val_doc, NamespaceDoc) and
val_doc.variables not in (None, UNKNOWN)):
for var_doc in val_doc.variables.values():
+ # Now we have a chance to propagate the defining module
+ # to objects for which introspection is not possible,
+ # such as properties.
+ if (isinstance(var_doc.value, ValueDoc)
+ and var_doc.value.defining_module is UNKNOWN):
+ var_doc.value.defining_module = val_doc.defining_module
parse_docstring(var_doc, docindex)
log.end_progress()
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docintrospecter.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docintrospecter.py 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docintrospecter.py 2006-09-14 21:37:38 UTC (rev 1389)
@@ -246,7 +246,7 @@
# Create a VariableDoc for the child, and introspect its
# value if it's defined in this module.
container = get_containing_module(child)
- if container != None and container == module_doc.canonical_name:
+ if container is not None and container == module_doc.canonical_name:
# Local variable.
child_val_doc = introspect_docs(child, context=module_doc)
child_var_doc = VariableDoc(name=child_name,
@@ -255,6 +255,10 @@
container=module_doc,
docs_extracted_by='introspecter')
elif container is None or module_doc.canonical_name is UNKNOWN:
+
+ # Don't introspect stuff "from __future__"
+ if is_future_feature(child): continue
+
# Possibly imported variable.
child_val_doc = introspect_docs(child, context=module_doc)
child_var_doc = VariableDoc(name=child_name,
@@ -295,7 +299,8 @@
#: A list of class variables that should not be included in a
#: class's API documentation.
UNDOCUMENTED_CLASS_VARS = (
- '__doc__', '__module__', '__dict__', '__weakref__', '__slots__')
+ '__doc__', '__module__', '__dict__', '__weakref__', '__slots__',
+ '__pyx_vtable__')
def introspect_class(cls, class_doc):
"""
@@ -483,6 +488,31 @@
"""
return isinstance(object, (TypeType, ClassType))
+__future_check_works = None
+
+def is_future_feature(object):
+ """
+ Return True if C{object} results from a C{from __future__ import feature"}
+ statement.
+ """
+ # Guard from unexpected implementation changes of the __future__ module.
+ global __future_check_works
+ if __future_check_works is not None:
+ if __future_check_works:
+ import __future__
+ return isinstance(object, __future__._Feature)
+ else:
+ return False
+ else:
+ __future_check_works = True
+ try:
+ return is_future_feature(object)
+ except:
+ __future_check_works = False
+ log.warning("Troubles inspecting __future__. Python implementation"
+ " may have been changed.")
+ return False
+
def get_docstring(value):
"""
Return the docstring for the given value; or C{None} if it
@@ -685,15 +715,26 @@
register_introspecter(inspect.isroutine, introspect_routine, priority=28)
register_introspecter(is_property, introspect_property, priority=30)
+# Register getset_descriptor as a property
try:
import array
- attribute = type(array.array.typecode)
+ getset_type = type(array.array.typecode)
del array
- def is_attribute(v): return isinstance(v, attribute)
- register_introspecter(is_attribute, introspect_property, priority=32)
+ def is_getset(v): return isinstance(v, getset_type)
+ register_introspecter(is_getset, introspect_property, priority=32)
except:
pass
+# Register member_descriptor as a property
+try:
+ import datetime
+ member_type = type(datetime.timedelta.days)
+ del datetime
+ def is_member(v): return isinstance(v, member_type)
+ register_introspecter(is_member, introspect_property, priority=34)
+except:
+ pass
+
#////////////////////////////////////////////////////////////
# Import support
#////////////////////////////////////////////////////////////
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docparser.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docparser.py 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docparser.py 2006-09-14 21:37:38 UTC (rev 1389)
@@ -157,7 +157,7 @@
"""
#{ Configuration Constants: Comment docstrings
-COMMENT_DOCSTRING_MARKER = '#: '
+COMMENT_DOCSTRING_MARKER = '#:'
"""The prefix used to mark comments that contain attribute
docstrings for variables."""
@@ -577,6 +577,8 @@
elif toktype == tokenize.COMMENT:
if toktext.startswith(COMMENT_DOCSTRING_MARKER):
comment_line = toktext[len(COMMENT_DOCSTRING_MARKER):].rstrip()
+ if comment_line.startswith(" "):
+ comment_line = comment_line[1:]
comments.append( [comment_line, srow])
elif toktext.startswith(START_GROUP_MARKER):
start_group = toktext[len(START_GROUP_MARKER):].strip()
@@ -844,12 +846,24 @@
# >>> from os.path import join, split
else:
src_name = parse_dotted_name(lhs)
- for elt in rhs:
- if elt != (token.OP, ','):
- var_name = parse_name(elt)
+ parts = split_on(rhs, (token.OP, ','))
+ for part in parts:
+ # from m import x
+ if len(part) == 1:
+ var_name = parse_name(part[0])
_import_var_as(DottedName(src_name, var_name),
var_name, parent_docs)
-
+
+ # from m import x as y
+ elif len(part) == 3 and part[1] == (token.NAME, 'as'):
+ orig_name = parse_name(part[0])
+ var_name = parse_name(part[2])
+ _import_var_as(DottedName(src_name, orig_name),
+ var_name, parent_docs)
+
+ else:
+ ParseError("Bad from-import")
+
def _process_fromstar_import(src, parent_docs):
"""
Handle a statement of the form:
Modified: branches/exp-args_in_class/epydoc/src/epydoc/docwriter/html.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/docwriter/html.py 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/docwriter/html.py 2006-09-14 21:37:38 UTC (rev 1389)
@@ -2498,8 +2498,11 @@
else:
return '??'
else:
- context_name = context.canonical_name
- return str(doc.canonical_name.contextualize(context_name))
+ if context is UNKNOWN:
+ return str(doc.canonical_name)
+ else:
+ context_name = context.canonical_name
+ return str(doc.canonical_name.contextualize(context_name))
#////////////////////////////////////////////////////////////
#{ Function Signatures
Modified: branches/exp-args_in_class/epydoc/src/epydoc/markup/restructuredtext.py
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/markup/restructuredtext.py 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/markup/restructuredtext.py 2006-09-14 21:37:38 UTC (rev 1389)
@@ -215,7 +215,9 @@
# depending on the version of docutils that's being used, because
# the default_transforms attribute was deprecated & replaced by
# get_transforms().
- if [int(v) for v in docutils.__version__.split('.')] < [0,4,0]:
+ version = [int(v) for v in docutils.__version__.split('.')]
+ version += [ 0 ] * (3 - len(version))
+ if version < [0,4,0]:
default_transforms = list(StandaloneReader.default_transforms)
try: default_transforms.remove(docutils.transforms.frontmatter.DocInfo)
except ValueError: pass
@@ -223,6 +225,7 @@
def get_transforms(self):
return [t for t in StandaloneReader.get_transforms(self)
if t != docutils.transforms.frontmatter.DocInfo]
+ del version
def __init__(self, errors):
self._errors = errors
Modified: branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/test/docbuilder.doctest 2006-09-14 21:37:38 UTC (rev 1389)
@@ -3,31 +3,26 @@
Test Function
=============
+
This test function takes a string containing the contents of a module.
It writes the string contents to a file, imports the file as a module,
and uses build_doc to build documentation, and pretty prints the resulting
ModuleDoc object. The `attribs` argument specifies which attributes
-of the `APIDoc`s should be displayed. The `introspect` argument gives the
-name of a variable in the module whose value should be introspected,
-instead of introspecting the whole module.
+of the `APIDoc`s should be displayed. The `build` argument gives the
+name of a variable in the module whose documentation should be built,
+instead of bilding docs for the whole module.
>>> import tempfile, re, os, os.path, textwrap, sys
>>> from epydoc.docbuilder import build_doc
- >>> def runbuilder(s, attribs='', introspect=None, exclude=''):
+ >>> def runbuilder(s, attribs='', build=None, exclude=''):
... # Write it to a temp file.
... tmp_dir = tempfile.mkdtemp()
... out = open(os.path.join(tmp_dir, 'epydoc_test.py'), 'w')
... out.write(textwrap.dedent(s))
... out.close()
- ... # Import it.
- ... sys.path.insert(0, tmp_dir)
- ... if introspect is None:
- ... import epydoc_test as val
- ... else:
- ... exec("from epydoc_test import %s as val" % introspect)
- ... del sys.path[0]
- ... # Introspect it.
- ... val_doc = build_doc(val)
+ ... # Build it.
+ ... val_doc = build_doc(os.path.join(tmp_dir, 'epydoc_test.py'))
+ ... if build: val_doc = val_doc.variables[build].value
... # Display it.
... s = val_doc.pp(include=attribs.split(),exclude=exclude.split())
... s = re.sub(r"(filename = ).*", r"\1...", s)
@@ -42,7 +37,92 @@
... os.rmdir(tmp_dir)
... del sys.modules['epydoc_test']
+Docformat selection
+===================
+The docstrings format can be selected using the ``__docformat__`` module
+variable.
+
+ >>> runbuilder(s='''
+ ... __docformat__ = 'restructuredtext'
+ ...
+ ... class Foo:
+ ... """Testing defining_module
+ ...
+ ... :cvar `c`: class var in class docstring
+ ... :type `c`: str
+ ... """
+ ... c = 'abc'
+ ...
+ ... def __init__(self):
+ ... #: A funny number
+ ... #:
+ ... #: :type: float
+ ... self.x = 108.0
+ ...
+ ... y = property(
+ ... fget=lambda self: 42,
+ ... doc="""A property has no defining module
+ ...
+ ... :type: int
+ ... """)
+ ...
+ ... def f(self):
+ ... """A function has a defining module
+ ...
+ ... :rtype: int
+ ... """
+ ... return 42
+ ... ''',
+ ... build='Foo',
+ ... attribs="variables name value type_descr return_type descr")
+ ClassDoc for epydoc_test.Foo [0]
+ +- descr = u'Testing defining_module'
+ +- variables
+ +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
+ | +- descr = None
+ | +- name = '__init__'
+ | +- type_descr = None
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.__init__ [2]
+ | +- descr = None
+ | +- return_type = None
+ +- c => VariableDoc for epydoc_test.Foo.c [3]
+ | +- descr = u'class var in class docstring'
+ | +- name = 'c'
+ | +- type_descr = u'str'
+ | +- value
+ | +- GenericValueDoc [4]
+ | +- descr = None
+ +- f => VariableDoc for epydoc_test.Foo.f [5]
+ | +- descr = None
+ | +- name = 'f'
+ | +- type_descr = None
+ | +- value
+ | +- RoutineDoc for epydoc_test.Foo.f [6]
+ | +- descr = u'A function has a defining module'
+ | +- return_type = u'int'
+ +- x => VariableDoc for epydoc_test.Foo.x [7]
+ | +- descr = u'A funny number'
+ | +- name = u'x'
+ | +- type_descr = u'float'
+ | +- value = <UNKNOWN>
+ +- y => VariableDoc for epydoc_test.Foo.y [8]
+ +- descr = None
+ +- name = 'y'
+ +- type_descr = None
+ +- value
+ +- PropertyDoc for epydoc_test.Foo.y [9]
+ +- descr = u'A property has no defining module'
+ +- type_descr = u'int'
+
+ >>> runbuilder(s="""
+ ... from __future__ import division
+ ... from re import match
+ ... """,
+ ... attribs='variables value')
+
+
Specifying constructor signature in class docstring
===================================================
Modified: branches/exp-args_in_class/epydoc/src/epydoc/test/docintrospecter.doctest
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/test/docintrospecter.doctest 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/test/docintrospecter.doctest 2006-09-14 21:37:38 UTC (rev 1389)
@@ -520,6 +520,16 @@
+- ModuleDoc for re [4]
+- variables = {}
+ >>> runintrospecter(s="""
+ ... from __future__ import division
+ ... from re import match
+ ... """,
+ ... attribs='variables value')
+ ModuleDoc for epydoc_test [0]
+ +- variables
+ +- match => VariableDoc for epydoc_test.match [1]
+ +- value
+ +- ValueDoc for sre.match [2]
Unicode
=======
Modified: branches/exp-args_in_class/epydoc/src/epydoc/test/docparser.doctest
===================================================================
--- branches/exp-args_in_class/epydoc/src/epydoc/test/docparser.doctest 2006-09-13 03:24:38 UTC (rev 1388)
+++ branches/exp-args_in_class/epydoc/src/epydoc/test/docparser.doctest 2006-09-14 21:37:38 UTC (rev 1389)
@@ -710,6 +710,21 @@
+- is_imported = True
+- value = <UNKNOWN>
+ >>> runparser(s="""
+ ... from re import match as much, split, sub as scuba
+ ... """,
+ ... attribs='variables name imported_from')
+ ModuleDoc for test [0]
+ +- variables
+ +- much => VariableDoc for test.much [1]
+ | +- imported_from = DottedName(u're', u'match')
+ | +- name = u'much'
+ +- scuba => VariableDoc for test.scuba [2]
+ | +- imported_from = DottedName(u're', u'sub')
+ | +- name = u'scuba'
+ +- split => VariableDoc for test.split [3]
+ +- imported_from = DottedName(u're', u'split')
+ +- name = u'split'
Unicode
=======
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-13 03:24:43
|
Revision: 1388
http://svn.sourceforge.net/epydoc/?rev=1388&view=rev
Author: dvarrazzo
Date: 2006-09-12 20:24:38 -0700 (Tue, 12 Sep 2006)
Log Message:
-----------
- member_descriptor attributes are recognized as property.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docintrospecter.py
Modified: trunk/epydoc/src/epydoc/docintrospecter.py
===================================================================
--- trunk/epydoc/src/epydoc/docintrospecter.py 2006-09-13 03:04:00 UTC (rev 1387)
+++ trunk/epydoc/src/epydoc/docintrospecter.py 2006-09-13 03:24:38 UTC (rev 1388)
@@ -715,15 +715,26 @@
register_introspecter(inspect.isroutine, introspect_routine, priority=28)
register_introspecter(is_property, introspect_property, priority=30)
+# Register getset_descriptor as a property
try:
import array
- attribute = type(array.array.typecode)
+ getset_type = type(array.array.typecode)
del array
- def is_attribute(v): return isinstance(v, attribute)
- register_introspecter(is_attribute, introspect_property, priority=32)
+ def is_getset(v): return isinstance(v, getset_type)
+ register_introspecter(is_getset, introspect_property, priority=32)
except:
pass
+# Register member_descriptor as a property
+try:
+ import datetime
+ member_type = type(datetime.timedelta.days)
+ del datetime
+ def is_member(v): return isinstance(v, member_type)
+ register_introspecter(is_member, introspect_property, priority=34)
+except:
+ pass
+
#////////////////////////////////////////////////////////////
# Import support
#////////////////////////////////////////////////////////////
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-13 03:04:05
|
Revision: 1387
http://svn.sourceforge.net/epydoc/?rev=1387&view=rev
Author: dvarrazzo
Date: 2006-09-12 20:04:00 -0700 (Tue, 12 Sep 2006)
Log Message:
-----------
- Added a filter to remove the class vtable generated by Pyrex for
extension modules.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docintrospecter.py
Modified: trunk/epydoc/src/epydoc/docintrospecter.py
===================================================================
--- trunk/epydoc/src/epydoc/docintrospecter.py 2006-09-11 16:12:51 UTC (rev 1386)
+++ trunk/epydoc/src/epydoc/docintrospecter.py 2006-09-13 03:04:00 UTC (rev 1387)
@@ -299,7 +299,8 @@
#: A list of class variables that should not be included in a
#: class's API documentation.
UNDOCUMENTED_CLASS_VARS = (
- '__doc__', '__module__', '__dict__', '__weakref__', '__slots__')
+ '__doc__', '__module__', '__dict__', '__weakref__', '__slots__',
+ '__pyx_vtable__')
def introspect_class(cls, class_doc):
"""
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dva...@us...> - 2006-09-11 16:13:01
|
Revision: 1386
http://svn.sourceforge.net/epydoc/?rev=1386&view=rev
Author: dvarrazzo
Date: 2006-09-11 09:12:51 -0700 (Mon, 11 Sep 2006)
Log Message:
-----------
- Fixed parsing of import statements in the form::
from mod import a as b
Modified Paths:
--------------
trunk/epydoc/src/epydoc/docparser.py
trunk/epydoc/src/epydoc/test/docparser.doctest
Modified: trunk/epydoc/src/epydoc/docparser.py
===================================================================
--- trunk/epydoc/src/epydoc/docparser.py 2006-09-11 13:45:12 UTC (rev 1385)
+++ trunk/epydoc/src/epydoc/docparser.py 2006-09-11 16:12:51 UTC (rev 1386)
@@ -846,12 +846,24 @@
# >>> from os.path import join, split
else:
src_name = parse_dotted_name(lhs)
- for elt in rhs:
- if elt != (token.OP, ','):
- var_name = parse_name(elt)
+ parts = split_on(rhs, (token.OP, ','))
+ for part in parts:
+ # from m import x
+ if len(part) == 1:
+ var_name = parse_name(part[0])
_import_var_as(DottedName(src_name, var_name),
var_name, parent_docs)
-
+
+ # from m import x as y
+ elif len(part) == 3 and part[1] == (token.NAME, 'as'):
+ orig_name = parse_name(part[0])
+ var_name = parse_name(part[2])
+ _import_var_as(DottedName(src_name, orig_name),
+ var_name, parent_docs)
+
+ else:
+ ParseError("Bad from-import")
+
def _process_fromstar_import(src, parent_docs):
"""
Handle a statement of the form:
Modified: trunk/epydoc/src/epydoc/test/docparser.doctest
===================================================================
--- trunk/epydoc/src/epydoc/test/docparser.doctest 2006-09-11 13:45:12 UTC (rev 1385)
+++ trunk/epydoc/src/epydoc/test/docparser.doctest 2006-09-11 16:12:51 UTC (rev 1386)
@@ -710,6 +710,21 @@
+- is_imported = True
+- value = <UNKNOWN>
+ >>> runparser(s="""
+ ... from re import match as much, split, sub as scuba
+ ... """,
+ ... attribs='variables name imported_from')
+ ModuleDoc for test [0]
+ +- variables
+ +- much => VariableDoc for test.much [1]
+ | +- imported_from = DottedName(u're', u'match')
+ | +- name = u'much'
+ +- scuba => VariableDoc for test.scuba [2]
+ | +- imported_from = DottedName(u're', u'sub')
+ | +- name = u'scuba'
+ +- split => VariableDoc for test.split [3]
+ +- imported_from = DottedName(u're', u'split')
+ +- name = u'split'
Unicode
=======
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|