Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autosummary to include instance attributes #9146

Merged
merged 4 commits into from May 5, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions sphinx/ext/autosummary/__init__.py
Expand Up @@ -662,8 +662,10 @@ def import_ivar_by_name(name: str, prefixes: List[str] = [None]) -> Tuple[str, A
name, attr = name.rsplit(".", 1)
real_name, obj, parent, modname = import_by_name(name, prefixes)
qualname = real_name.replace(modname + ".", "")
analyzer = ModuleAnalyzer.for_module(modname)
if (qualname, attr) in analyzer.find_attr_docs():
analyzer = ModuleAnalyzer.for_module(getattr(obj, '__module__', modname))
analyzer.analyze()
# check for presence in `annotations` to include dataclass attributes
if (qualname, attr) in analyzer.attr_docs or (qualname, attr) in analyzer.annotations:
return real_name + "." + attr, INSTANCEATTR, obj, modname
except (ImportError, ValueError, PycodeError):
pass
Expand Down
18 changes: 12 additions & 6 deletions sphinx/ext/autosummary/generate.py
Expand Up @@ -39,7 +39,7 @@
from sphinx.builders import Builder
from sphinx.config import Config
from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.ext.autodoc import Documenter
from sphinx.ext.autodoc import Documenter, ObjectMember
from sphinx.ext.autodoc.importer import import_module
from sphinx.ext.autosummary import get_documenter, import_by_name, import_ivar_by_name
from sphinx.locale import __
Expand Down Expand Up @@ -239,15 +239,21 @@ def skip_member(obj: Any, name: str, objtype: str) -> bool:
name, exc, type='autosummary')
return False

def attr_getter(obj, name, *defargs):
return sphinx.ext.autodoc.autodoc_attrgetter(app, obj, name, *defargs)

def get_all_members(obj: Any) -> Dict[str, ObjectMember]:
all_members = sphinx.ext.autodoc.get_class_members(obj, [qualname], attr_getter)
return all_members

def get_members(obj: Any, types: Set[str], include_public: List[str] = [],
imported: bool = True) -> Tuple[List[str], List[str]]:
items: List[str] = []
public: List[str] = []
for name in dir(obj):
try:
value = safe_getattr(obj, name)
except AttributeError:
continue

all_members = get_all_members(obj)
tk0miya marked this conversation as resolved.
Show resolved Hide resolved
for name, member in all_members.items():
value = member.object
documenter = get_documenter(app, value, obj)
if documenter.objtype in types:
# skip imported members if expected
Expand Down
7 changes: 7 additions & 0 deletions tests/roots/test-autosummary/dummy_module.py
Expand Up @@ -3,6 +3,7 @@

module_attr
C.class_attr
C.instance_attr
C.prop_attr1
C.prop_attr2
C.C2
Expand Down Expand Up @@ -51,6 +52,12 @@ class C:
#: value is integer.
class_attr = 42

def __init__(self):
#: This is an instance attribute
#:
#: value is a string
self.instance_attr = "42"

def _prop_attr_get(self):
"""
This is a function docstring
Expand Down
2 changes: 2 additions & 0 deletions tests/test_ext_autosummary.py
Expand Up @@ -161,6 +161,7 @@ def handler(app, what, name, obj, options, lines):
'emptyLine': "This is the real summary",
'module_attr': 'This is a module attribute',
'C.class_attr': 'This is a class attribute',
'C.instance_attr': 'This is an instance attribute',
'C.prop_attr1': 'This is a function docstring',
'C.prop_attr2': 'This is a attribute docstring',
'C.C2': 'This is a nested inner class docstring',
Expand Down Expand Up @@ -329,6 +330,7 @@ def test_autosummary_generate(app, status, warning):
' ~Foo.CONSTANT3\n'
' ~Foo.CONSTANT4\n'
' ~Foo.baz\n'
' ~Foo.value\n'
' \n' in Foo)

FooBar = (app.srcdir / 'generated' / 'autosummary_dummy_module.Foo.Bar.rst').read_text()
Expand Down