-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Describe the bug
Metadata in the docstrings (or doc-comments) of attributes is ignored; for example, :meta public: does not make an attribute whose name starts with an underscore public.
To Reproduce
Apply autodoc to a class such as the following:
class Foo:
#: A class attribute whose name starts with an underscore.
#:
#: :meta public:
_bar = 12
There will be no entry generated for _bar.
Expected behavior
The attribute _bar above should be listed in the generated documentation.
Your project
Here is a tiny project using the example above: example.zip
Environment info
- OS: macOS 10.14.6
- Python version: 3.8.0
- Sphinx version: 3.3.0 (I tried my patch below on the
3.xbranch) - Sphinx extensions:
sphinx.ext.autodoc
Additional context
The cause of the bug is that autodoc.Documenter.filter_members does not properly look up the docstring/doc-comments for attributes when searching for metadata. The following patch seems to fix the problem (I haven't made a PR since I'm not at all sure that this is the right way to do it):
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index ed02c2c90..0d9dc5f5f 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -647,20 +647,24 @@ class Documenter:
else:
isattr = False
- doc = getdoc(member, self.get_attr, self.env.config.autodoc_inherit_docstrings,
- self.parent, self.object_name)
- if not isinstance(doc, str):
- # Ignore non-string __doc__
- doc = None
-
- # if the member __doc__ is the same as self's __doc__, it's just
- # inherited and therefore not the member's doc
- cls = self.get_attr(member, '__class__', None)
- if cls:
- cls_doc = self.get_attr(cls, '__doc__', None)
- if cls_doc == doc:
+ if (namespace, membername) in attr_docs:
+ doc = '\n'.join(attr_docs[(namespace, membername)])
+ has_doc = True
+ else:
+ doc = getdoc(member, self.get_attr, self.env.config.autodoc_inherit_docstrings,
+ self.parent, self.object_name)
+ if not isinstance(doc, str):
+ # Ignore non-string __doc__
doc = None
- has_doc = bool(doc)
+
+ # if the member __doc__ is the same as self's __doc__, it's just
+ # inherited and therefore not the member's doc
+ cls = self.get_attr(member, '__class__', None)
+ if cls:
+ cls_doc = self.get_attr(cls, '__doc__', None)
+ if cls_doc == doc:
+ doc = None
+ has_doc = bool(doc)
metadata = extract_metadata(doc)
if 'private' in metadata: