Commits

Takayuki Shimizukawa committed 7029194

* Fix: autosummary does not create the description from attributes docstring. Closes #1444

Comments (0)

Files changed (4)

   from '.js_t' and '.html'. The issue was introduced from Sphinx-1.1
 * #1363: Fix i18n: missing python domain's cross-references with currentmodule
   directive or currentclass directive.
-
+* #1444: autosummary does not create the description from attributes docstring.
 
 Release 1.2.2 (released Mar 2, 2014)
 ====================================

sphinx/ext/autosummary/__init__.py

 
 from sphinx import addnodes
 from sphinx.util.compat import Directive
+from sphinx.pycode import ModuleAnalyzer, PycodeError
 
 
 # -- autosummary_toc node ------------------------------------------------------
         self.env = env = self.state.document.settings.env
         self.genopt = {}
         self.warnings = []
+        self.result = ViewList()
 
         names = [x.strip().split()[0] for x in self.content
                  if x.strip() and re.search(r'^[~a-zA-Z_]', x.strip()[0])]
 
             # NB. using real_name here is important, since Documenters
             #     handle module prefixes slightly differently
+            self.result = ViewList()  # initialize for each documenter
             documenter = get_documenter(obj, parent)(self, real_name)
             if not documenter.parse_name():
                 self.warn('failed to parse name %s' % real_name)
                 items.append((display_name, '', '', real_name))
                 continue
 
+            # try to also get a source code analyzer for attribute docs
+            try:
+                documenter.analyzer = ModuleAnalyzer.for_module(documenter.get_real_modname())
+                # parse right now, to get PycodeErrors on parsing (results will
+                # be cached anyway)
+                documenter.analyzer.find_attr_docs()
+            except PycodeError, err:
+                documenter.env.app.debug('[autodoc] module analyzer failed: %s', err)
+                # no source file -- e.g. for builtin and C modules
+                documenter.analyzer = None
+
             # -- Grab the signature
 
             sig = documenter.format_signature()
 
             # -- Grab the summary
 
-            doc = list(documenter.process_doc(documenter.get_doc()))
+            documenter.add_content(None)
+            doc = list(documenter.process_doc([self.result.data]))
 
             while doc and not doc[0].strip():
                 doc.pop(0)

tests/roots/test-autosummary/dummy_module.py

+"""
+.. autosummary::
+
+   module_attr
+   C.class_attr
+   C.prop_attr1
+   C.prop_attr2
+"""
 
 def withSentence():
     '''I have a sentence which
     However, it did't end with a period.
     '''
     pass
+
+
+#: This is a module attribute
+#:
+#: value is integer.
+module_attr = 1
+
+
+class C:
+    '''
+    My C class
+
+    with class_attr attribute
+    '''
+
+    #: This is a class attribute
+    #:
+    #: value is integer.
+    class_attr = 42
+
+    def _prop_attr_get(self):
+        """
+        This is a function docstring
+
+        return value is string.
+        """
+        return 'spam egg'
+
+    prop_attr1 = property(_prop_attr_get)
+
+    prop_attr2 = property(_prop_attr_get)
+    """
+    This is a attribute docstring
+
+    value is string.
+    """

tests/test_autosummary.py

         'withSentence': 'I have a sentence which spans multiple lines.',
         'noSentence': "this doesn't start with a",
         'emptyLine': "This is the real summary",
+        'module_attr': 'This is a module attribute',
+        'C.class_attr': 'This is a class attribute',
+        'C.prop_attr1': 'This is a function docstring',
+        'C.prop_attr2': 'This is a attribute docstring',
     }
     for key, expected in expected_values.iteritems():
         assert autosummary_items[key][2] == expected, 'Summary for %s was %r -'\
             ' expected %r' % (key, autosummary_items[key], expected)
+
+
+@with_app(confoverrides={'extensions': ['sphinx.ext.autosummary'],
+                         'autosummary_generate': True,
+                         'source_suffix': '.rst'},
+          buildername='html', srcdir=(test_roots / 'test-autosummary'))
+def test_process_doc_event(app):
+    app.builddir.rmtree(True)
+
+    # Now, modify the python path...
+    srcdir = test_roots / 'test-autosummary'
+    sys.path.insert(0, srcdir)
+    try:
+        def handler(app, what, name, obj, options, lines):
+            assert isinstance(lines, list)
+        app.connect('autodoc-process-docstring', handler)
+        app.builder.build_all()
+    finally:
+        if srcdir in sys.path:
+            sys.path.remove(srcdir)
+        # remove the auto-generated dummy_module.rst
+        dummy_rst = srcdir / 'dummy_module.rst'
+        if dummy_rst.isfile():
+            dummy_rst.unlink()