diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2019-05-21 20:20:46 +0300 |
---|---|---|
committer | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2019-05-22 03:56:46 +0300 |
commit | 277aba935d1fc50f823ca9a72047d4556e5d8717 (patch) | |
tree | fca4302c7b34242dcc259660f7d4de526f5fe8b3 /sphinx/ext/autodoc | |
parent | 3de408d2d94feae8a8b62fbec36c87b9622936c8 (diff) |
Close #6325: autodoc: Support attributes in __slots__
Diffstat (limited to 'sphinx/ext/autodoc')
-rw-r--r-- | sphinx/ext/autodoc/__init__.py | 51 | ||||
-rw-r--r-- | sphinx/ext/autodoc/importer.py | 9 |
2 files changed, 59 insertions, 1 deletions
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 3048b8e48..65a292b6a 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -67,6 +67,7 @@ def identity(x): ALL = object() INSTANCEATTR = object() +SLOTSATTR = object() def members_option(arg): @@ -1493,6 +1494,55 @@ class InstanceAttributeDocumenter(AttributeDocumenter): super().add_content(more_content, no_docstring=True) +class SlotsAttributeDocumenter(AttributeDocumenter): + """ + Specialized Documenter subclass for attributes that cannot be imported + because they are attributes in __slots__. + """ + objtype = 'slotsattribute' + directivetype = 'attribute' + member_order = 60 + + # must be higher than AttributeDocumenter + priority = 11 + + @classmethod + def can_document_member(cls, member, membername, isattr, parent): + # type: (Any, str, bool, Any) -> bool + """This documents only SLOTSATTR members.""" + return member is SLOTSATTR + + def import_object(self): + # type: () -> bool + """Never import anything.""" + # disguise as an attribute + self.objtype = 'attribute' + self._datadescriptor = True + + with mock(self.env.config.autodoc_mock_imports): + try: + ret = import_object(self.modname, self.objpath[:-1], 'class', + attrgetter=self.get_attr, + warningiserror=self.env.config.autodoc_warningiserror) + self.module, _, _, self.parent = ret + return True + except ImportError as exc: + logger.warning(exc.args[0], type='autodoc', subtype='import_object') + self.env.note_reread() + return False + + def get_doc(self, encoding=None, ignore=1): + # type: (str, int) -> List[List[str]] + """Decode and return lines of the docstring(s) for the object.""" + name = self.objpath[-1] + __slots__ = safe_getattr(self.parent, '__slots__', []) + if isinstance(__slots__, dict) and isinstance(__slots__.get(name), str): + docstring = prepare_docstring(__slots__[name]) + return [docstring] + else: + return [] + + def get_documenters(app): # type: (Sphinx) -> Dict[str, Type[Documenter]] """Returns registered Documenter classes""" @@ -1554,6 +1604,7 @@ def setup(app): app.add_autodocumenter(AttributeDocumenter) app.add_autodocumenter(PropertyDocumenter) app.add_autodocumenter(InstanceAttributeDocumenter) + app.add_autodocumenter(SlotsAttributeDocumenter) app.add_config_value('autoclass_content', 'class', True) app.add_config_value('autodoc_member_order', 'alphabetic', True) diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index a06d93d52..37bdae8a9 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -15,7 +15,7 @@ from collections import namedtuple from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.util import logging -from sphinx.util.inspect import isenumclass, safe_getattr +from sphinx.util.inspect import isclass, isenumclass, safe_getattr if False: # For type annotation @@ -127,6 +127,13 @@ def get_object_members(subject, objpath, attrgetter, analyzer=None): if name not in superclass.__dict__: members[name] = Attribute(name, True, value) + # members in __slots__ + if isclass(subject) and hasattr(subject, '__slots__'): + from sphinx.ext.autodoc import SLOTSATTR + + for name in subject.__slots__: + members[name] = Attribute(name, True, SLOTSATTR) + # other members for name in dir(subject): try: |