mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch 'master' into graphviz_width_of_svg
This commit is contained in:
commit
b09c54e669
6
CHANGES
6
CHANGES
@ -12,6 +12,9 @@ Dependencies
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
* #5156: the :py:mod:`sphinx.ext.graphviz: extension runs `dot` in the
|
||||
directory of the document being built instead of in the root directory of
|
||||
the documentation.
|
||||
* #4460: extensions which stores any data to environment should return the
|
||||
version of its env data structure as metadata. In detail, please see
|
||||
:ref:`ext-metadata`.
|
||||
@ -55,6 +58,7 @@ Deprecated
|
||||
----------
|
||||
|
||||
* :confval:`source_parsers` is deprecated
|
||||
* quickstart: ``--epub`` option becomes default, so it is deprecated
|
||||
* Drop function based directive support. For now, Sphinx only supports class
|
||||
based directives.
|
||||
* ``sphinx.util.docutils.directive_helper()`` is deprecated
|
||||
@ -186,6 +190,7 @@ Features added
|
||||
* #5140: linkcheck: Add better Accept header to HTTP client
|
||||
* #4614: sphinx-build: Add ``--keep-going`` option to show all warnings
|
||||
* Add :rst:role:`math:numref` role to refer equations (Same as :rst:role:`eq`)
|
||||
* quickstart: epub builder is enabled by default
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@ -200,6 +205,7 @@ Bugs fixed
|
||||
* #5114: sphinx-build: Handle errors on scanning documents
|
||||
* epub: spine has been broken when "self" is listed on toctree (refs: #4611)
|
||||
* #344: autosummary does not understand docstring of module level attributes
|
||||
* #5191: C++, prevent nested declarations in functions to avoid lookup problems.
|
||||
* #5002: graphviz: SVGs do not adapt to the column width
|
||||
|
||||
Testing
|
||||
|
@ -74,7 +74,6 @@ DEFAULTS = {
|
||||
'language': None,
|
||||
'suffix': '.rst',
|
||||
'master': 'index',
|
||||
'epub': False,
|
||||
'makefile': True,
|
||||
'batchfile': True,
|
||||
}
|
||||
@ -246,7 +245,6 @@ def ask_user(d):
|
||||
* language: document language
|
||||
* suffix: source file suffix
|
||||
* master: master document name
|
||||
* epub: use epub (bool)
|
||||
* extensions: extensions to use (list)
|
||||
* makefile: make Makefile
|
||||
* batchfile: make command file
|
||||
@ -347,12 +345,6 @@ document is a custom template, you can also set this to another filename.'''))
|
||||
d['master'] = do_prompt(__('Please enter a new file name, or rename the '
|
||||
'existing file and press Enter'), d['master'])
|
||||
|
||||
if 'epub' not in d:
|
||||
print(__('''
|
||||
Sphinx can also add configuration for epub output:'''))
|
||||
d['epub'] = do_prompt(__('Do you want to use the epub builder (y/n)'),
|
||||
'n', boolean)
|
||||
|
||||
if 'extensions' not in d:
|
||||
print(__('Indicate which of the following Sphinx extensions should be '
|
||||
'enabled:'))
|
||||
|
@ -2085,7 +2085,7 @@ class ASTTrailingTypeSpecName(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> Any
|
||||
# type: () -> ASTNestedName
|
||||
return self.nestedName
|
||||
|
||||
def get_id(self, version):
|
||||
@ -2379,7 +2379,7 @@ class ASTDeclSpecs(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.trailingTypeSpec.name
|
||||
|
||||
def get_id(self, version):
|
||||
@ -2487,7 +2487,7 @@ class ASTDeclaratorPtr(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.next.name
|
||||
|
||||
@property
|
||||
@ -2583,7 +2583,7 @@ class ASTDeclaratorRef(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.next.name
|
||||
|
||||
@property
|
||||
@ -2638,7 +2638,7 @@ class ASTDeclaratorParamPack(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.next.name
|
||||
|
||||
@property
|
||||
@ -2702,7 +2702,7 @@ class ASTDeclaratorMemPtr(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.next.name
|
||||
|
||||
@property
|
||||
@ -2798,7 +2798,7 @@ class ASTDeclaratorParen(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.inner.name
|
||||
|
||||
@property
|
||||
@ -2864,7 +2864,7 @@ class ASTDeclaratorNameParamQual(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.declId
|
||||
|
||||
@property
|
||||
@ -2962,9 +2962,8 @@ class ASTType(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
name = self.decl.name
|
||||
return name
|
||||
# type: () -> ASTNestedName
|
||||
return self.decl.name
|
||||
|
||||
@property
|
||||
def function_params(self):
|
||||
@ -3054,7 +3053,7 @@ class ASTTypeWithInit(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.type.name
|
||||
|
||||
def get_id(self, version, objectType=None, symbol=None):
|
||||
@ -3122,7 +3121,7 @@ class ASTConcept(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.nestedName
|
||||
|
||||
def get_id(self, version, objectType=None, symbol=None):
|
||||
@ -3326,7 +3325,7 @@ class ASTDeclaration(ASTBase):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# type: () -> unicode
|
||||
# type: () -> ASTNestedName
|
||||
return self.declaration.name
|
||||
|
||||
@property
|
||||
@ -5791,12 +5790,37 @@ class CPPObject(ObjectDescription):
|
||||
# type: (addnodes.desc_signature, Any, Dict) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
||||
|
||||
def run(self):
|
||||
env = self.state.document.settings.env # from ObjectDescription.run
|
||||
if 'cpp:parent_symbol' not in env.temp_data:
|
||||
root = env.domaindata['cpp']['root_symbol']
|
||||
env.temp_data['cpp:parent_symbol'] = root
|
||||
env.ref_context['cpp:parent_key'] = root.get_lookup_key()
|
||||
|
||||
# The lookup keys assume that no nested scopes exists inside overloaded functions.
|
||||
# (see also #5191)
|
||||
# Example:
|
||||
# .. cpp:function:: void f(int)
|
||||
# .. cpp:function:: void f(double)
|
||||
#
|
||||
# .. cpp:function:: void g()
|
||||
#
|
||||
# :cpp:any:`boom`
|
||||
#
|
||||
# So we disallow any signatures inside functions.
|
||||
parentSymbol = env.temp_data['cpp:parent_symbol']
|
||||
parentDecl = parentSymbol.declaration
|
||||
if parentDecl is not None and parentDecl.objectType == 'function':
|
||||
self.warn("C++ declarations inside functions are not supported." +
|
||||
" Parent function is " + text_type(parentSymbol.get_full_nested_name()))
|
||||
name = _make_phony_error_name()
|
||||
symbol = parentSymbol.add_name(name)
|
||||
env.temp_data['cpp:last_symbol'] = symbol
|
||||
return []
|
||||
return ObjectDescription.run(self)
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (unicode, addnodes.desc_signature) -> Any
|
||||
if 'cpp:parent_symbol' not in self.env.temp_data:
|
||||
root = self.env.domaindata['cpp']['root_symbol']
|
||||
self.env.temp_data['cpp:parent_symbol'] = root
|
||||
self.env.ref_context['cpp:parent_key'] = root.get_lookup_key()
|
||||
parentSymbol = self.env.temp_data['cpp:parent_symbol']
|
||||
|
||||
parser = DefinitionParser(sig, self, self.env.config)
|
||||
|
@ -156,7 +156,10 @@ class Graphviz(SphinxDirective):
|
||||
line=self.lineno)]
|
||||
node = graphviz()
|
||||
node['code'] = dotcode
|
||||
node['options'] = {}
|
||||
node['options'] = {
|
||||
'docname': path.splitext(self.state.document.current_source)[0],
|
||||
}
|
||||
|
||||
if 'graphviz_dot' in self.options:
|
||||
node['options']['graphviz_dot'] = self.options['graphviz_dot']
|
||||
if 'alt' in self.options:
|
||||
@ -193,7 +196,9 @@ class GraphvizSimple(SphinxDirective):
|
||||
node = graphviz()
|
||||
node['code'] = '%s %s {\n%s\n}\n' % \
|
||||
(self.name, self.arguments[0], '\n'.join(self.content))
|
||||
node['options'] = {}
|
||||
node['options'] = {
|
||||
'docname': path.splitext(self.state.document.current_source)[0],
|
||||
}
|
||||
if 'graphviz_dot' in self.options:
|
||||
node['options']['graphviz_dot'] = self.options['graphviz_dot']
|
||||
if 'alt' in self.options:
|
||||
@ -236,10 +241,14 @@ def render_dot(self, code, options, format, prefix='graphviz'):
|
||||
dot_args = [graphviz_dot]
|
||||
dot_args.extend(self.builder.config.graphviz_dot_args)
|
||||
dot_args.extend(['-T' + format, '-o' + outfn])
|
||||
|
||||
docname = options.get('docname', 'index')
|
||||
cwd = path.dirname(path.join(self.builder.srcdir, docname))
|
||||
|
||||
if format == 'png':
|
||||
dot_args.extend(['-Tcmapx', '-o%s.map' % outfn])
|
||||
try:
|
||||
p = Popen(dot_args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
|
||||
p = Popen(dot_args, stdout=PIPE, stdin=PIPE, stderr=PIPE, cwd=cwd)
|
||||
except OSError as err:
|
||||
if err.errno != ENOENT: # No such file or directory
|
||||
raise
|
||||
|
@ -165,16 +165,12 @@ texinfo_documents = [
|
||||
author, '{{ project_fn }}', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
{%- if epub %}
|
||||
|
||||
|
||||
# -- Options for Epub output -------------------------------------------------
|
||||
|
||||
# Bibliographic Dublin Core info.
|
||||
epub_title = project
|
||||
epub_author = author
|
||||
epub_publisher = author
|
||||
epub_copyright = copyright
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
@ -187,7 +183,6 @@ epub_copyright = copyright
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
epub_exclude_files = ['search.html']
|
||||
{%- endif %}
|
||||
{%- if extensions %}
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@ from docutils.statemachine import ViewList
|
||||
from six import PY3
|
||||
|
||||
from sphinx.ext.autodoc import (
|
||||
AutoDirective, ModuleLevelDocumenter, FunctionDocumenter, cut_lines, between, ALL
|
||||
AutoDirective, ModuleLevelDocumenter, cut_lines, between, ALL
|
||||
)
|
||||
from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options
|
||||
from sphinx.testing.util import SphinxTestApp, Struct # NOQA
|
||||
@ -28,6 +28,11 @@ from sphinx.util.docutils import LoggingReporter
|
||||
|
||||
app = None
|
||||
|
||||
if PY3:
|
||||
ROGER_METHOD = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)'
|
||||
else:
|
||||
ROGER_METHOD = ' .. py:classmethod:: Class.roger(a, e=5, f=6)'
|
||||
|
||||
|
||||
def do_autodoc(app, objtype, name, options={}):
|
||||
doccls = app.registry.documenters[objtype]
|
||||
@ -512,43 +517,6 @@ def test_docstring_processing():
|
||||
app.disconnect(lid)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_docstring_property_processing():
|
||||
def genarate_docstring(objtype, name, **kw):
|
||||
del processed_docstrings[:]
|
||||
del processed_signatures[:]
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.generate(**kw)
|
||||
results = list(directive.result)
|
||||
docstrings = inst.get_doc()[0]
|
||||
del directive.result[:]
|
||||
return results, docstrings
|
||||
|
||||
directive.env.config.autodoc_docstring_signature = False
|
||||
results, docstrings = \
|
||||
genarate_docstring('attribute', 'target.DocstringSig.prop1')
|
||||
assert '.. py:attribute:: DocstringSig.prop1' in results
|
||||
assert 'First line of docstring' in docstrings
|
||||
assert 'DocstringSig.prop1(self)' in docstrings
|
||||
results, docstrings = \
|
||||
genarate_docstring('attribute', 'target.DocstringSig.prop2')
|
||||
assert '.. py:attribute:: DocstringSig.prop2' in results
|
||||
assert 'First line of docstring' in docstrings
|
||||
assert 'Second line of docstring' in docstrings
|
||||
|
||||
directive.env.config.autodoc_docstring_signature = True
|
||||
results, docstrings = \
|
||||
genarate_docstring('attribute', 'target.DocstringSig.prop1')
|
||||
assert '.. py:attribute:: DocstringSig.prop1' in results
|
||||
assert 'First line of docstring' in docstrings
|
||||
assert 'DocstringSig.prop1(self)' not in docstrings
|
||||
results, docstrings = \
|
||||
genarate_docstring('attribute', 'target.DocstringSig.prop2')
|
||||
assert '.. py:attribute:: DocstringSig.prop2' in results
|
||||
assert 'First line of docstring' in docstrings
|
||||
assert 'Second line of docstring' in docstrings
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_new_documenter():
|
||||
logging.setup(app, app._status, app._warning)
|
||||
@ -617,73 +585,12 @@ def test_attrgetter_using():
|
||||
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_generate():
|
||||
logging.setup(app, app._status, app._warning)
|
||||
|
||||
def assert_warns(warn_str, objtype, name, **kw):
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.generate(**kw)
|
||||
assert len(directive.result) == 0, directive.result
|
||||
|
||||
assert warn_str in app._warning.getvalue()
|
||||
app._warning.truncate(0)
|
||||
|
||||
def assert_works(objtype, name, **kw):
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.generate(**kw)
|
||||
assert directive.result
|
||||
# print '\n'.join(directive.result)
|
||||
assert app._warning.getvalue() == ''
|
||||
del directive.result[:]
|
||||
|
||||
def assert_processes(items, objtype, name, **kw):
|
||||
del processed_docstrings[:]
|
||||
del processed_signatures[:]
|
||||
assert_works(objtype, name, **kw)
|
||||
assert set(processed_docstrings) | set(processed_signatures) == set(items)
|
||||
|
||||
def assert_result_contains(item, objtype, name, **kw):
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.generate(**kw)
|
||||
# print '\n'.join(directive.result)
|
||||
assert app._warning.getvalue() == ''
|
||||
assert item in directive.result
|
||||
del directive.result[:]
|
||||
|
||||
def assert_order(items, objtype, name, member_order, **kw):
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.options.member_order = member_order
|
||||
inst.generate(**kw)
|
||||
assert app._warning.getvalue() == ''
|
||||
items = list(reversed(items))
|
||||
lineiter = iter(directive.result)
|
||||
# for line in directive.result:
|
||||
# if line.strip():
|
||||
# print repr(line)
|
||||
while items:
|
||||
item = items.pop()
|
||||
for line in lineiter:
|
||||
if line == item:
|
||||
break
|
||||
else: # ran out of items!
|
||||
assert False, ('item %r not found in result or not in the '
|
||||
' correct order' % item)
|
||||
del directive.result[:]
|
||||
|
||||
options.members = []
|
||||
|
||||
# no module found?
|
||||
assert_warns("import for autodocumenting 'foobar'",
|
||||
'function', 'foobar', more_content=None)
|
||||
# importing
|
||||
assert_warns("failed to import module 'test_foobar'",
|
||||
'module', 'test_foobar', more_content=None)
|
||||
# attributes missing
|
||||
assert_warns("failed to import function 'foobar' from module 'util'",
|
||||
'function', 'util.foobar', more_content=None)
|
||||
# method missing
|
||||
assert_warns("failed to import method 'Class.foobar' from module 'target';",
|
||||
'method', 'target.Class.foobar', more_content=None)
|
||||
|
||||
# test auto and given content mixing
|
||||
directive.env.ref_context['py:module'] = 'target'
|
||||
assert_result_contains(' Function.', 'method', 'Class.meth')
|
||||
@ -694,80 +601,238 @@ def test_generate():
|
||||
assert_result_contains(' Content.', 'method',
|
||||
'Class.meth', more_content=add_content)
|
||||
|
||||
# test check_module
|
||||
inst = FunctionDocumenter(directive, 'add_documenter')
|
||||
inst.generate(check_module=True)
|
||||
assert len(directive.result) == 0
|
||||
|
||||
# assert that exceptions can be documented
|
||||
assert_works('exception', 'target.CustomEx', all_members=True)
|
||||
assert_works('exception', 'target.CustomEx')
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_exception(app):
|
||||
actual = do_autodoc(app, 'exception', 'target.CustomEx')
|
||||
assert list(actual) == [
|
||||
'',
|
||||
'.. py:exception:: CustomEx',
|
||||
' :module: target',
|
||||
'',
|
||||
' My custom exception.',
|
||||
' '
|
||||
]
|
||||
|
||||
# test diverse inclusion settings for members
|
||||
should = [('class', 'target.Class')]
|
||||
assert_processes(should, 'class', 'Class')
|
||||
should.extend([('method', 'target.Class.meth')])
|
||||
options.members = ['meth']
|
||||
options.exclude_members = set(['excludemeth'])
|
||||
assert_processes(should, 'class', 'Class')
|
||||
should.extend([('attribute', 'target.Class.prop'),
|
||||
('attribute', 'target.Class.descr'),
|
||||
('attribute', 'target.Class.attr'),
|
||||
('attribute', 'target.Class.docattr'),
|
||||
('attribute', 'target.Class.udocattr'),
|
||||
('attribute', 'target.Class.mdocattr'),
|
||||
('attribute', 'target.Class.inst_attr_comment'),
|
||||
('attribute', 'target.Class.inst_attr_inline'),
|
||||
('attribute', 'target.Class.inst_attr_string'),
|
||||
('method', 'target.Class.moore'),
|
||||
])
|
||||
options.members = ALL
|
||||
assert_processes(should, 'class', 'Class')
|
||||
options.undoc_members = True
|
||||
should.extend((('attribute', 'target.Class.skipattr'),
|
||||
('method', 'target.Class.undocmeth'),
|
||||
('method', 'target.Class.roger')))
|
||||
assert_processes(should, 'class', 'Class')
|
||||
options.inherited_members = True
|
||||
should.append(('method', 'target.Class.inheritedmeth'))
|
||||
should.append(('method', 'target.Class.inheritedclassmeth'))
|
||||
should.append(('method', 'target.Class.inheritedstaticmeth'))
|
||||
assert_processes(should, 'class', 'Class')
|
||||
|
||||
# test special members
|
||||
options.special_members = ['__special1__']
|
||||
should.append(('method', 'target.Class.__special1__'))
|
||||
assert_processes(should, 'class', 'Class')
|
||||
options.special_members = ALL
|
||||
should.append(('method', 'target.Class.__special2__'))
|
||||
assert_processes(should, 'class', 'Class')
|
||||
options.special_members = False
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_warnings(app, warning):
|
||||
app.env.temp_data['docname'] = 'dummy'
|
||||
|
||||
options.members = []
|
||||
# test module flags
|
||||
assert_result_contains('.. py:module:: target',
|
||||
'module', 'target')
|
||||
options.synopsis = 'Synopsis'
|
||||
assert_result_contains(' :synopsis: Synopsis', 'module', 'target')
|
||||
options.deprecated = True
|
||||
assert_result_contains(' :deprecated:', 'module', 'target')
|
||||
options.platform = 'Platform'
|
||||
assert_result_contains(' :platform: Platform', 'module', 'target')
|
||||
# test if __all__ is respected for modules
|
||||
options.members = ALL
|
||||
assert_result_contains('.. py:class:: Class(arg)', 'module', 'target')
|
||||
try:
|
||||
assert_result_contains('.. py:exception:: CustomEx',
|
||||
'module', 'target')
|
||||
except AssertionError:
|
||||
pass
|
||||
else:
|
||||
assert False, 'documented CustomEx which is not in __all__'
|
||||
# can't import module
|
||||
do_autodoc(app, 'module', 'unknown')
|
||||
assert "failed to import module 'unknown'" in warning.getvalue()
|
||||
|
||||
# test ignore-module-all
|
||||
options.ignore_module_all = True
|
||||
assert_result_contains('.. py:class:: Class(arg)', 'module', 'target')
|
||||
assert_result_contains('.. py:exception:: CustomEx', 'module', 'target')
|
||||
# missing function
|
||||
do_autodoc(app, 'function', 'unknown')
|
||||
assert "import for autodocumenting 'unknown'" in warning.getvalue()
|
||||
|
||||
do_autodoc(app, 'function', 'target.unknown')
|
||||
assert "failed to import function 'unknown' from module 'target'" in warning.getvalue()
|
||||
|
||||
# missing method
|
||||
do_autodoc(app, 'method', 'target.Class.unknown')
|
||||
assert "failed to import method 'Class.unknown' from module 'target'" in warning.getvalue()
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_attributes(app):
|
||||
options = {"synopsis": 'Synopsis',
|
||||
"platform": "Platform",
|
||||
"deprecated": None}
|
||||
actual = do_autodoc(app, 'module', 'target', options)
|
||||
assert list(actual) == [
|
||||
'',
|
||||
'.. py:module:: target',
|
||||
' :synopsis: Synopsis',
|
||||
' :platform: Platform',
|
||||
' :deprecated:',
|
||||
''
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_members(app):
|
||||
# default (no-members)
|
||||
actual = do_autodoc(app, 'class', 'target.Base')
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base',
|
||||
]
|
||||
|
||||
# default ALL-members
|
||||
options = {"members": None}
|
||||
actual = do_autodoc(app, 'class', 'target.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base',
|
||||
' .. py:classmethod:: Base.inheritedclassmeth()',
|
||||
' .. py:method:: Base.inheritedmeth()',
|
||||
' .. py:staticmethod:: Base.inheritedstaticmeth(cls)'
|
||||
]
|
||||
|
||||
# default specific-members
|
||||
options = {"members": "inheritedmeth,inheritedstaticmeth"}
|
||||
actual = do_autodoc(app, 'class', 'target.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base',
|
||||
' .. py:method:: Base.inheritedmeth()',
|
||||
' .. py:staticmethod:: Base.inheritedstaticmeth(cls)'
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_exclude_members(app):
|
||||
options = {"members": None,
|
||||
"exclude-members": "inheritedmeth,inheritedstaticmeth"}
|
||||
actual = do_autodoc(app, 'class', 'target.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base',
|
||||
' .. py:classmethod:: Base.inheritedclassmeth()'
|
||||
]
|
||||
|
||||
# members vs exclude-members
|
||||
options = {"members": "inheritedmeth",
|
||||
"exclude-members": "inheritedmeth"}
|
||||
actual = do_autodoc(app, 'class', 'target.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base',
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_undoc_members(app):
|
||||
options = {"members": None,
|
||||
"undoc-members": None}
|
||||
actual = do_autodoc(app, 'class', 'target.Class', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Class(arg)',
|
||||
' .. 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')
|
||||
def test_autodoc_inherited_members(app):
|
||||
options = {"members": None,
|
||||
"inherited-members": None}
|
||||
actual = do_autodoc(app, 'class', 'target.Class', options)
|
||||
assert list(filter(lambda l: 'method::' in l, actual)) == [
|
||||
' .. py:method:: Class.excludemeth()',
|
||||
' .. py:classmethod:: Class.inheritedclassmeth()',
|
||||
' .. py:method:: Class.inheritedmeth()',
|
||||
' .. py:staticmethod:: Class.inheritedstaticmeth(cls)',
|
||||
' .. py:method:: Class.meth()',
|
||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
||||
' .. py:method:: Class.skipmeth()'
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_imported_members(app):
|
||||
options = {"members": None,
|
||||
"imported-members": None,
|
||||
"ignore-module-all": None}
|
||||
actual = do_autodoc(app, 'module', 'target', options)
|
||||
assert '.. py:function:: add_documenter(cls)' in actual
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_special_members(app):
|
||||
# all special methods
|
||||
options = {"members": None,
|
||||
"undoc-members": None,
|
||||
"special-members": None}
|
||||
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:attribute:: Class.__module__',
|
||||
' .. py:method:: Class.__special1__()',
|
||||
' .. py:method:: Class.__special2__()',
|
||||
' .. 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()'
|
||||
]
|
||||
|
||||
# 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')
|
||||
def test_autodoc_ignore_module_all(app):
|
||||
# default (no-ignore-module-all)
|
||||
options = {"members": None}
|
||||
actual = do_autodoc(app, 'module', 'target', options)
|
||||
assert list(filter(lambda l: 'class::' in l, actual)) == [
|
||||
'.. py:class:: Class(arg)',
|
||||
]
|
||||
|
||||
# ignore-module-all
|
||||
options = {"members": None,
|
||||
"ignore-module-all": None}
|
||||
actual = do_autodoc(app, 'module', 'target', options)
|
||||
assert list(filter(lambda l: 'class::' in l, actual)) == [
|
||||
'.. py:class:: Class(arg)',
|
||||
'.. py:class:: CustomDataDescriptor(doc)',
|
||||
'.. py:class:: CustomDataDescriptor2(doc)',
|
||||
'.. py:class:: CustomDataDescriptorMeta',
|
||||
'.. py:class:: CustomDict',
|
||||
'.. py:class:: EnumCls',
|
||||
'.. py:class:: InstAttCls()',
|
||||
'.. py:class:: Outer',
|
||||
' .. py:class:: Outer.Inner',
|
||||
'.. py:class:: StrRepr'
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
@ -889,11 +954,6 @@ def test_autodoc_c_module(app):
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_member_order(app):
|
||||
if PY3:
|
||||
roger_method = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)'
|
||||
else:
|
||||
roger_method = ' .. py:classmethod:: Class.roger(a, e=5, f=6)'
|
||||
|
||||
# case member-order='bysource'
|
||||
options = {"members": None,
|
||||
'member-order': 'bysource',
|
||||
@ -913,7 +973,7 @@ def test_autodoc_member_order(app):
|
||||
' .. py:attribute:: Class.docattr',
|
||||
' .. py:attribute:: Class.udocattr',
|
||||
' .. py:attribute:: Class.mdocattr',
|
||||
roger_method,
|
||||
ROGER_METHOD,
|
||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
||||
' .. py:attribute:: Class.inst_attr_inline',
|
||||
' .. py:attribute:: Class.inst_attr_comment',
|
||||
@ -932,7 +992,7 @@ def test_autodoc_member_order(app):
|
||||
' .. py:method:: Class.excludemeth()',
|
||||
' .. py:method:: Class.meth()',
|
||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
||||
roger_method,
|
||||
ROGER_METHOD,
|
||||
' .. py:method:: Class.skipmeth()',
|
||||
' .. py:method:: Class.undocmeth()',
|
||||
' .. py:attribute:: Class._private_inst_attr',
|
||||
@ -967,7 +1027,7 @@ def test_autodoc_member_order(app):
|
||||
' .. py:method:: Class.meth()',
|
||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
||||
' .. py:attribute:: Class.prop',
|
||||
roger_method,
|
||||
ROGER_METHOD,
|
||||
' .. py:attribute:: Class.skipattr',
|
||||
' .. py:method:: Class.skipmeth()',
|
||||
' .. py:attribute:: Class.udocattr',
|
||||
|
@ -197,7 +197,6 @@ def test_quickstart_all_answers(tempdir):
|
||||
assert ns['latex_documents'] == [
|
||||
('contents', 'STASI.tex', u'STASI™ Documentation',
|
||||
u'Wolfgang Schäuble \\& G\'Beckstein', 'manual')]
|
||||
assert ns['epub_author'] == u'Wolfgang Schäuble & G\'Beckstein'
|
||||
assert ns['man_pages'] == [
|
||||
('contents', 'stasi', u'STASI™ Documentation',
|
||||
[u'Wolfgang Schäuble & G\'Beckstein'], 1)]
|
||||
|
Loading…
Reference in New Issue
Block a user