mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
autodoc: Handle explicit instance attributes in :members: (re #904)
This commit is contained in:
parent
34cbd684a9
commit
6f9e541ab5
@ -489,20 +489,26 @@ class Documenter(object):
|
|||||||
If *want_all* is True, return all members. Else, only return those
|
If *want_all* is True, return all members. Else, only return those
|
||||||
members given by *self.options.members* (which may also be none).
|
members given by *self.options.members* (which may also be none).
|
||||||
"""
|
"""
|
||||||
|
analyzed_member_names = set()
|
||||||
|
if self.analyzer:
|
||||||
|
attr_docs = self.analyzer.find_attr_docs()
|
||||||
|
namespace = '.'.join(self.objpath)
|
||||||
|
for item in attr_docs.iteritems():
|
||||||
|
if item[0][0] == namespace:
|
||||||
|
analyzed_member_names.add(item[0][1])
|
||||||
if not want_all:
|
if not want_all:
|
||||||
if not self.options.members:
|
if not self.options.members:
|
||||||
return False, []
|
return False, []
|
||||||
# specific members given
|
# specific members given
|
||||||
ret = []
|
members = []
|
||||||
for mname in self.options.members:
|
for mname in self.options.members:
|
||||||
try:
|
try:
|
||||||
ret.append((mname, self.get_attr(self.object, mname)))
|
members.append((mname, self.get_attr(self.object, mname)))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self.directive.warn('missing attribute %s in object %s'
|
if mname not in analyzed_member_names:
|
||||||
% (mname, self.fullname))
|
self.directive.warn('missing attribute %s in object %s'
|
||||||
return False, ret
|
% (mname, self.fullname))
|
||||||
|
elif self.options.inherited_members:
|
||||||
if self.options.inherited_members:
|
|
||||||
# safe_getmembers() uses dir() which pulls in members from all
|
# safe_getmembers() uses dir() which pulls in members from all
|
||||||
# base classes
|
# base classes
|
||||||
members = safe_getmembers(self.object)
|
members = safe_getmembers(self.object)
|
||||||
@ -521,13 +527,10 @@ class Documenter(object):
|
|||||||
for mname in obj_dict.keys()]
|
for mname in obj_dict.keys()]
|
||||||
membernames = set(m[0] for m in members)
|
membernames = set(m[0] for m in members)
|
||||||
# add instance attributes from the analyzer
|
# add instance attributes from the analyzer
|
||||||
if self.analyzer:
|
for aname in analyzed_member_names:
|
||||||
attr_docs = self.analyzer.find_attr_docs()
|
if aname not in membernames and \
|
||||||
namespace = '.'.join(self.objpath)
|
(want_all or aname in self.options.members):
|
||||||
for item in attr_docs.iteritems():
|
members.append((aname, INSTANCEATTR))
|
||||||
if item[0][0] == namespace:
|
|
||||||
if item[0][1] not in membernames:
|
|
||||||
members.append((item[0][1], INSTANCEATTR))
|
|
||||||
return False, sorted(members)
|
return False, sorted(members)
|
||||||
|
|
||||||
def filter_members(self, members, want_all):
|
def filter_members(self, members, want_all):
|
||||||
|
@ -32,3 +32,16 @@ Just testing a few autodoc possibilities...
|
|||||||
:noindex:
|
:noindex:
|
||||||
|
|
||||||
.. autoclass:: MarkupError
|
.. autoclass:: MarkupError
|
||||||
|
|
||||||
|
|
||||||
|
.. currentmodule:: test_autodoc
|
||||||
|
|
||||||
|
.. autoclass:: InstAttCls
|
||||||
|
:members:
|
||||||
|
|
||||||
|
All members (5 total)
|
||||||
|
|
||||||
|
.. autoclass:: InstAttCls
|
||||||
|
:members: ca1, ia1
|
||||||
|
|
||||||
|
Specific members (2 total)
|
||||||
|
@ -540,6 +540,32 @@ def test_generate():
|
|||||||
assert_result_contains(
|
assert_result_contains(
|
||||||
' :annotation: = None', 'attribute', 'AttCls.a2')
|
' :annotation: = None', 'attribute', 'AttCls.a2')
|
||||||
|
|
||||||
|
# test explicit members with instance attributes
|
||||||
|
del directive.env.temp_data['autodoc:class']
|
||||||
|
del directive.env.temp_data['autodoc:module']
|
||||||
|
directive.env.temp_data['py:module'] = 'test_autodoc'
|
||||||
|
options.inherited_members = False
|
||||||
|
options.undoc_members = False
|
||||||
|
options.members = ALL
|
||||||
|
assert_processes([
|
||||||
|
('class', 'test_autodoc.InstAttCls'),
|
||||||
|
('attribute', 'test_autodoc.InstAttCls.ca1'),
|
||||||
|
('attribute', 'test_autodoc.InstAttCls.ca2'),
|
||||||
|
('attribute', 'test_autodoc.InstAttCls.ca3'),
|
||||||
|
('attribute', 'test_autodoc.InstAttCls.ia1'),
|
||||||
|
('attribute', 'test_autodoc.InstAttCls.ia2'),
|
||||||
|
], 'class', 'InstAttCls')
|
||||||
|
del directive.env.temp_data['autodoc:class']
|
||||||
|
del directive.env.temp_data['autodoc:module']
|
||||||
|
options.members = ['ca1', 'ia1']
|
||||||
|
assert_processes([
|
||||||
|
('class', 'test_autodoc.InstAttCls'),
|
||||||
|
('attribute', 'test_autodoc.InstAttCls.ca1'),
|
||||||
|
('attribute', 'test_autodoc.InstAttCls.ia1'),
|
||||||
|
], 'class', 'InstAttCls')
|
||||||
|
del directive.env.temp_data['autodoc:class']
|
||||||
|
del directive.env.temp_data['autodoc:module']
|
||||||
|
del directive.env.temp_data['py:module']
|
||||||
|
|
||||||
# --- generate fodder ------------
|
# --- generate fodder ------------
|
||||||
|
|
||||||
@ -680,3 +706,22 @@ class StrRepr(str):
|
|||||||
class AttCls(object):
|
class AttCls(object):
|
||||||
a1 = StrRepr('hello\nworld')
|
a1 = StrRepr('hello\nworld')
|
||||||
a2 = None
|
a2 = None
|
||||||
|
|
||||||
|
class InstAttCls(object):
|
||||||
|
"""Class with documented class and instance attributes."""
|
||||||
|
|
||||||
|
#: Doc comment for class attribute InstAttCls.ca1.
|
||||||
|
#: It can have multiple lines.
|
||||||
|
ca1 = 'a'
|
||||||
|
|
||||||
|
ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only.
|
||||||
|
|
||||||
|
ca3 = 'c'
|
||||||
|
"""Docstring for class attribute InstAttCls.ca3."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
#: Doc comment for instance attribute InstAttCls.ia1
|
||||||
|
self.ia1 = 'd'
|
||||||
|
|
||||||
|
self.ia2 = 'e'
|
||||||
|
"""Docstring for instance attribute InstAttCls.ia2."""
|
||||||
|
Loading…
Reference in New Issue
Block a user