mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #2401: autodoc: `:members:
causes
:special-members:
` not to be shown
This commit is contained in:
parent
c6e0d92d10
commit
06aa1a7864
1
CHANGES
1
CHANGES
@ -30,6 +30,7 @@ Bugs fixed
|
|||||||
* #5348: download reference to remote file is not displayed
|
* #5348: download reference to remote file is not displayed
|
||||||
* #5282: html theme: ``pygments_style`` of theme was overrided by ``conf.py``
|
* #5282: html theme: ``pygments_style`` of theme was overrided by ``conf.py``
|
||||||
by default
|
by default
|
||||||
|
* #2401: autodoc: ``:members:`` causes ``:special-members:`` not to be shown
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
@ -110,6 +110,20 @@ def bool_option(arg):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def merge_special_members_option(options):
|
||||||
|
# type: (Dict) -> None
|
||||||
|
"""Merge :special-members: option to :members: option."""
|
||||||
|
if 'special-members' in options and options['special-members'] is not ALL:
|
||||||
|
if options.get('members') is ALL:
|
||||||
|
pass
|
||||||
|
elif options.get('members'):
|
||||||
|
for member in options['special-members']:
|
||||||
|
if member not in options['members']:
|
||||||
|
options['members'].append(member)
|
||||||
|
else:
|
||||||
|
options['members'] = options['special-members']
|
||||||
|
|
||||||
|
|
||||||
class AutodocReporter(object):
|
class AutodocReporter(object):
|
||||||
"""
|
"""
|
||||||
A reporter replacement that assigns the correct source name
|
A reporter replacement that assigns the correct source name
|
||||||
@ -823,6 +837,11 @@ class ModuleDocumenter(Documenter):
|
|||||||
'imported-members': bool_option, 'ignore-module-all': bool_option
|
'imported-members': bool_option, 'ignore-module-all': bool_option
|
||||||
} # type: Dict[unicode, Callable]
|
} # type: Dict[unicode, Callable]
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
# type: (Any) -> None
|
||||||
|
super(ModuleDocumenter, self).__init__(*args)
|
||||||
|
merge_special_members_option(self.options)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_document_member(cls, member, membername, isattr, parent):
|
def can_document_member(cls, member, membername, isattr, parent):
|
||||||
# type: (Any, unicode, bool, Any) -> bool
|
# type: (Any, unicode, bool, Any) -> bool
|
||||||
@ -1075,6 +1094,11 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|||||||
'private-members': bool_option, 'special-members': members_option,
|
'private-members': bool_option, 'special-members': members_option,
|
||||||
} # type: Dict[unicode, Callable]
|
} # type: Dict[unicode, Callable]
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
# type: (Any) -> None
|
||||||
|
super(ClassDocumenter, self).__init__(*args)
|
||||||
|
merge_special_members_option(self.options)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_document_member(cls, member, membername, isattr, parent):
|
def can_document_member(cls, member, membername, isattr, parent):
|
||||||
# type: (Any, unicode, bool, Any) -> bool
|
# type: (Any, unicode, bool, Any) -> bool
|
||||||
|
@ -43,11 +43,12 @@ from sphinx.util.rst import escape as rst_escape
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Callable, Dict, Tuple, List # NOQA
|
from typing import Any, Callable, Dict, List, Tuple, Type # NOQA
|
||||||
from jinja2 import BaseLoader # NOQA
|
from jinja2 import BaseLoader # NOQA
|
||||||
from sphinx import addnodes # NOQA
|
from sphinx import addnodes # NOQA
|
||||||
from sphinx.builders import Builder # NOQA
|
from sphinx.builders import Builder # NOQA
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
from sphinx.environment import BuildEnvironment # NOQA
|
||||||
|
from sphinx.ext.autodoc import Documenter # NOQA
|
||||||
|
|
||||||
|
|
||||||
class DummyApplication(object):
|
class DummyApplication(object):
|
||||||
@ -69,7 +70,7 @@ def setup_documenters(app):
|
|||||||
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
|
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
|
||||||
FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
|
FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
|
||||||
InstanceAttributeDocumenter
|
InstanceAttributeDocumenter
|
||||||
]
|
] # type: List[Type[Documenter]]
|
||||||
for documenter in documenters:
|
for documenter in documenters:
|
||||||
app.registry.add_documenter(documenter.objtype, documenter)
|
app.registry.add_documenter(documenter.objtype, documenter)
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import six
|
|||||||
from docutils.statemachine import ViewList
|
from docutils.statemachine import ViewList
|
||||||
from six import StringIO
|
from six import StringIO
|
||||||
|
|
||||||
from sphinx.ext.autodoc import add_documenter, FunctionDocumenter, ALL # NOQA
|
from sphinx.ext.autodoc import add_documenter, FunctionDocumenter, ALL, Options # NOQA
|
||||||
from sphinx.testing.util import SphinxTestApp, Struct
|
from sphinx.testing.util import SphinxTestApp, Struct
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ def setup_test():
|
|||||||
global options, directive
|
global options, directive
|
||||||
global processed_docstrings, processed_signatures
|
global processed_docstrings, processed_signatures
|
||||||
|
|
||||||
options = Struct(
|
options = Options(
|
||||||
inherited_members = False,
|
inherited_members = False,
|
||||||
undoc_members = False,
|
undoc_members = False,
|
||||||
private_members = False,
|
private_members = False,
|
||||||
|
@ -21,7 +21,7 @@ from six import PY3
|
|||||||
|
|
||||||
from sphinx.ext.autodoc import (
|
from sphinx.ext.autodoc import (
|
||||||
AutoDirective, ModuleLevelDocumenter, cut_lines, between, ALL,
|
AutoDirective, ModuleLevelDocumenter, cut_lines, between, ALL,
|
||||||
merge_autodoc_default_flags
|
merge_autodoc_default_flags, Options
|
||||||
)
|
)
|
||||||
from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options
|
from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options
|
||||||
from sphinx.testing.util import SphinxTestApp, Struct # NOQA
|
from sphinx.testing.util import SphinxTestApp, Struct # NOQA
|
||||||
@ -79,7 +79,7 @@ def setup_test():
|
|||||||
global options, directive
|
global options, directive
|
||||||
global processed_docstrings, processed_signatures
|
global processed_docstrings, processed_signatures
|
||||||
|
|
||||||
options = Struct(
|
options = Options(
|
||||||
inherited_members = False,
|
inherited_members = False,
|
||||||
undoc_members = False,
|
undoc_members = False,
|
||||||
private_members = False,
|
private_members = False,
|
||||||
@ -757,6 +757,29 @@ def test_autodoc_imported_members(app):
|
|||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_autodoc_special_members(app):
|
def test_autodoc_special_members(app):
|
||||||
|
# specific special methods
|
||||||
|
options = {"undoc-members": None,
|
||||||
|
"special-members": "__init__,__special1__"}
|
||||||
|
actual = do_autodoc(app, 'class', 'target.Class', options)
|
||||||
|
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||||
|
'.. py:class:: Class(arg)',
|
||||||
|
' .. py:method:: Class.__init__(arg)',
|
||||||
|
' .. py:method:: Class.__special1__()',
|
||||||
|
]
|
||||||
|
|
||||||
|
# combination with specific members
|
||||||
|
options = {"members": "attr,docattr",
|
||||||
|
"undoc-members": None,
|
||||||
|
"special-members": "__init__,__special1__"}
|
||||||
|
actual = do_autodoc(app, 'class', 'target.Class', options)
|
||||||
|
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||||
|
'.. py:class:: Class(arg)',
|
||||||
|
' .. py:method:: Class.__init__(arg)',
|
||||||
|
' .. py:method:: Class.__special1__()',
|
||||||
|
' .. py:attribute:: Class.attr',
|
||||||
|
' .. py:attribute:: Class.docattr',
|
||||||
|
]
|
||||||
|
|
||||||
# all special methods
|
# all special methods
|
||||||
options = {"members": None,
|
options = {"members": None,
|
||||||
"undoc-members": None,
|
"undoc-members": None,
|
||||||
@ -786,33 +809,6 @@ def test_autodoc_special_members(app):
|
|||||||
' .. py:method:: Class.undocmeth()'
|
' .. py:method:: Class.undocmeth()'
|
||||||
]
|
]
|
||||||
|
|
||||||
# specific special methods
|
|
||||||
options = {"members": None,
|
|
||||||
"undoc-members": None,
|
|
||||||
"special-members": "__init__,__special1__"}
|
|
||||||
actual = do_autodoc(app, 'class', 'target.Class', options)
|
|
||||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
|
||||||
'.. py:class:: Class(arg)',
|
|
||||||
' .. py:method:: Class.__init__(arg)',
|
|
||||||
' .. py:method:: Class.__special1__()',
|
|
||||||
' .. py:attribute:: Class.attr',
|
|
||||||
' .. py:attribute:: Class.descr',
|
|
||||||
' .. py:attribute:: Class.docattr',
|
|
||||||
' .. py:method:: Class.excludemeth()',
|
|
||||||
' .. py:attribute:: Class.inst_attr_comment',
|
|
||||||
' .. py:attribute:: Class.inst_attr_inline',
|
|
||||||
' .. py:attribute:: Class.inst_attr_string',
|
|
||||||
' .. py:attribute:: Class.mdocattr',
|
|
||||||
' .. py:method:: Class.meth()',
|
|
||||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
|
||||||
' .. py:attribute:: Class.prop',
|
|
||||||
ROGER_METHOD,
|
|
||||||
' .. py:attribute:: Class.skipattr',
|
|
||||||
' .. py:method:: Class.skipmeth()',
|
|
||||||
' .. py:attribute:: Class.udocattr',
|
|
||||||
' .. py:method:: Class.undocmeth()'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_autodoc_ignore_module_all(app):
|
def test_autodoc_ignore_module_all(app):
|
||||||
@ -1551,9 +1547,7 @@ def test_autodoc_default_options_with_values(app):
|
|||||||
assert ' .. py:attribute:: EnumCls.val4' not in actual
|
assert ' .. py:attribute:: EnumCls.val4' not in actual
|
||||||
|
|
||||||
# with :special-members:
|
# with :special-members:
|
||||||
# Note that :members: must be *on* for :special-members: to work.
|
|
||||||
app.config.autodoc_default_options = {
|
app.config.autodoc_default_options = {
|
||||||
'members': None,
|
|
||||||
'special-members': '__init__,__iter__',
|
'special-members': '__init__,__iter__',
|
||||||
}
|
}
|
||||||
actual = do_autodoc(app, 'class', 'target.CustomIter')
|
actual = do_autodoc(app, 'class', 'target.CustomIter')
|
||||||
|
Loading…
Reference in New Issue
Block a user