diff options
| -rw-r--r-- | MANIFEST.in | 1 | ||||
| -rw-r--r-- | doc/ext/autodoc.rst | 18 | ||||
| -rw-r--r-- | sphinx/config.py | 2 | ||||
| -rw-r--r-- | sphinx/environment.py | 2 | ||||
| -rw-r--r-- | sphinx/ext/autodoc.py | 4 | ||||
| -rw-r--r-- | sphinx/pycode/__init__.py | 5 | ||||
| -rw-r--r-- | sphinx/pycode/pgen2/tokenize.py | 9 | ||||
| -rw-r--r-- | sphinx/util/compat.py | 2 | ||||
| -rw-r--r-- | tests/test_build.py | 2 |
9 files changed, 37 insertions, 8 deletions
diff --git a/MANIFEST.in b/MANIFEST.in index a22d6a8e..e1f0b575 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -16,6 +16,7 @@ recursive-include sphinx/themes * recursive-include sphinx/locale * recursive-include tests * recursive-include utils * +include sphinx/pycode/Grammar.txt recursive-include doc * prune doc/_build diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst index 993f971a..e0766938 100644 --- a/doc/ext/autodoc.rst +++ b/doc/ext/autodoc.rst @@ -135,12 +135,30 @@ directive. .. directive:: autofunction + autodata automethod autoattribute These work exactly like :dir:`autoclass` etc., but do not offer the options used for automatic member documentation. + For module data members and class attributes, documentation can either be put + into a special-formatted comment *before* the attribute definition, or in a + docstring *after* the definition. This means that in the following class + definition, both attributes can be autodocumented:: + + class Foo: + """Docstring for class Foo.""" + + #: Doc comment for attribute Foo.bar. + bar = 1 + + baz = 2 + """Docstring for attribute Foo.baz.""" + + .. versionchanged:: 0.6 + :dir:`autodata` and :dir:`autoattribute` can now extract docstrings. + .. note:: If you document decorated functions or methods, keep in mind that autodoc diff --git a/sphinx/config.py b/sphinx/config.py index 60f85375..5942fcf8 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -139,7 +139,7 @@ class Config(object): if name not in self.values: raise AttributeError('No such config value: %s' % name) default = self.values[name][0] - if callable(default): + if hasattr(default, '__call__'): return default(self) return default diff --git a/sphinx/environment.py b/sphinx/environment.py index b70bd250..fe4cba6b 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -541,7 +541,7 @@ class BuildEnvironment: doctree = pub.document except UnicodeError, err: from sphinx.application import SphinxError - raise SphinxError(err.message) + raise SphinxError(str(err)) self.filter_messages(doctree) self.process_dependencies(docname, doctree) self.process_images(docname, doctree) diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py index be3e3f0f..d0512f2b 100644 --- a/sphinx/ext/autodoc.py +++ b/sphinx/ext/autodoc.py @@ -166,7 +166,7 @@ def between(marker, what=None, keepempty=False): def isdescriptor(x): """Check if the object is some kind of descriptor.""" for item in '__get__', '__set__', '__delete__': - if callable(getattr(x, item, None)): + if hasattr(getattr(x, item, None), '__call__'): return True return False @@ -380,6 +380,8 @@ class RstGenerator(object): # try to also get a source code analyzer for attribute docs try: analyzer = ModuleAnalyzer.for_module(mod) + # parse right now, to get PycodeErrors on parsing + analyzer.parse() except PycodeError, err: # no source file -- e.g. for builtin and C modules analyzer = None diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py index 17dc6afb..c2086da5 100644 --- a/sphinx/pycode/__init__.py +++ b/sphinx/pycode/__init__.py @@ -210,7 +210,10 @@ class ModuleAnalyzer(object): if self.parsetree is not None: return self.tokenize() - self.parsetree = pydriver.parse_tokens(self.tokens) + try: + self.parsetree = pydriver.parse_tokens(self.tokens) + except parse.ParseError, err: + raise PycodeError('parsing failed', err) # find the source code encoding encoding = sys.getdefaultencoding() comments = self.parsetree.get_prefix() diff --git a/sphinx/pycode/pgen2/tokenize.py b/sphinx/pycode/pgen2/tokenize.py index 46ee7842..4489db89 100644 --- a/sphinx/pycode/pgen2/tokenize.py +++ b/sphinx/pycode/pgen2/tokenize.py @@ -274,12 +274,17 @@ def generate_tokens(readline): line = readline() except StopIteration: line = '' + # if we are not at the end of the file make sure the + # line ends with a newline because the parser depends + # on that. + if line: + line = line.rstrip() + '\n' lnum = lnum + 1 pos, max = 0, len(line) if contstr: # continued string if not line: - raise TokenError, ("EOF in multi-line string", strstart) + raise TokenError("EOF in multi-line string", strstart) endmatch = endprog.match(line) if endmatch: pos = end = endmatch.end(0) @@ -335,7 +340,7 @@ def generate_tokens(readline): else: # continued statement if not line: - raise TokenError, ("EOF in multi-line statement", (lnum, 0)) + raise TokenError("EOF in multi-line statement", (lnum, 0)) continued = 0 while pos < max: diff --git a/sphinx/util/compat.py b/sphinx/util/compat.py index 4d5e1996..56ac9e80 100644 --- a/sphinx/util/compat.py +++ b/sphinx/util/compat.py @@ -27,7 +27,7 @@ def make_admonition(node_class, name, arguments, options, content, lineno, textnodes, messages = state.inline_text(title_text, lineno) admonition_node += nodes.title(title_text, '', *textnodes) admonition_node += messages - if options.has_key('class'): + if 'class' in options: classes = options['class'] else: classes = ['admonition-' + nodes.make_id(title_text)] diff --git a/tests/test_build.py b/tests/test_build.py index 5e815e88..9999abd0 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -129,7 +129,7 @@ def test_html(app): for path, check in paths.iteritems(): nodes = list(etree.findall(path)) assert nodes != [] - if callable(check): + if hasattr(check, '__call__'): check(nodes) elif not check: # only check for node presence |
