From 69d93c967c591a65f10bcb9cb07e03d5cf03cce6 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 1 Jun 2019 23:18:37 +0900 Subject: [PATCH] Fix #1063: autodoc: automodule directive handles undocumented module level variables --- CHANGES | 2 ++ sphinx/ext/autodoc/__init__.py | 13 ++++++++-- tests/roots/test-ext-autodoc/target/module.py | 4 ++++ tests/test_autodoc.py | 24 +++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/roots/test-ext-autodoc/target/module.py diff --git a/CHANGES b/CHANGES index 2363ea759..c228978ec 100644 --- a/CHANGES +++ b/CHANGES @@ -90,6 +90,8 @@ Features added autodoc considers values as a docstring of the attribute * #6361: autodoc: Add :confval:`autodoc_typehints` to suppress typehints from signature +* #1063: autodoc: ``automodule`` directive now handles undocumented module level + variables * #6212 autosummary: Add :confval:`autosummary_imported_members` to display imported members on autosummary * #6271: ``make clean`` is catastrophically broken if building into '.' diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 7172553ac..f66269a6b 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -549,8 +549,10 @@ class Documenter: if self.analyzer: attr_docs = self.analyzer.find_attr_docs() + tagorder = self.analyzer.tagorder else: attr_docs = {} + tagorder = {} # process members and determine which to skip for (membername, member) in members: @@ -580,12 +582,13 @@ class Documenter: membername in self.options.special_members: keep = has_doc or self.options.undoc_members elif (namespace, membername) in attr_docs: + has_doc = bool(attr_docs[namespace, membername]) if want_all and membername.startswith('_'): # ignore members whose name starts with _ by default - keep = self.options.private_members + keep = has_doc and self.options.private_members else: # keep documented attributes - keep = True + keep = has_doc isattr = True elif want_all and membername.startswith('_'): # ignore members whose name starts with _ by default @@ -594,6 +597,8 @@ class Documenter: else: # ignore undocumented members if :undoc-members: is not given keep = has_doc or self.options.undoc_members + # module top level item or not + isattr = membername in tagorder # give the user a chance to decide whether this member # should be skipped @@ -1291,6 +1296,10 @@ class DataDocumenter(ModuleLevelDocumenter): return self.get_attr(self.parent or self.object, '__module__', None) \ or self.modname + def get_doc(self, encoding=None, ignore=1): + # type: (str, int) -> List[List[str]] + return [] + class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore """ diff --git a/tests/roots/test-ext-autodoc/target/module.py b/tests/roots/test-ext-autodoc/target/module.py new file mode 100644 index 000000000..d5b557d94 --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/module.py @@ -0,0 +1,4 @@ +#: docstring for CONSTANT1 +CONSTANT1 = "" + +CONSTANT2 = "" diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index f6f5a618c..518d23e8c 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -1689,6 +1689,30 @@ def test_partialmethod(app): assert list(actual) == expected +@pytest.mark.usefixtures('setup_test') +def test_module_variables(): + options = {"members": None, + "undoc-members": True} + actual = do_autodoc(app, 'module', 'target.module', options) + assert list(actual) == [ + '', + '.. py:module:: target.module', + '', + '', + '.. py:data:: CONSTANT1', + ' :module: target.module', + " :annotation: = ''", + '', + ' docstring for CONSTANT1', + ' ', + '', + '.. py:data:: CONSTANT2', + ' :module: target.module', + " :annotation: = ''", + '', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_typehints_signature(app): app.config.autodoc_typehints = "signature"