mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '2.0'
This commit is contained in:
commit
65ac90773d
7
CHANGES
7
CHANGES
@ -67,6 +67,9 @@ Deprecated
|
|||||||
* ``sphinx.ext.autodoc.importer.MockLoader``
|
* ``sphinx.ext.autodoc.importer.MockLoader``
|
||||||
* ``sphinx.ext.autodoc.importer.mock()``
|
* ``sphinx.ext.autodoc.importer.mock()``
|
||||||
* ``sphinx.ext.autosummary.autolink_role()``
|
* ``sphinx.ext.autosummary.autolink_role()``
|
||||||
|
* ``sphinx.ext.imgmath.DOC_BODY``
|
||||||
|
* ``sphinx.ext.imgmath.DOC_BODY_PREVIEW``
|
||||||
|
* ``sphinx.ext.imgmath.DOC_HEAD``
|
||||||
* ``sphinx.transforms.CitationReferences``
|
* ``sphinx.transforms.CitationReferences``
|
||||||
* ``sphinx.transforms.SmartQuotesSkipper``
|
* ``sphinx.transforms.SmartQuotesSkipper``
|
||||||
* ``sphinx.util.docfields.DocFieldTransformer.preprocess_fieldtypes()``
|
* ``sphinx.util.docfields.DocFieldTransformer.preprocess_fieldtypes()``
|
||||||
@ -94,9 +97,13 @@ Features added
|
|||||||
variables (refs: #6232, #6303)
|
variables (refs: #6232, #6303)
|
||||||
* #6287: autodoc: Unable to document bound instance methods exported as module
|
* #6287: autodoc: Unable to document bound instance methods exported as module
|
||||||
functions
|
functions
|
||||||
|
* #6289: autodoc: :confval:`autodoc_default_options` now supports
|
||||||
|
``imported-members`` option
|
||||||
* #6212 autosummary: Add :confval:`autosummary_imported_members` to display
|
* #6212 autosummary: Add :confval:`autosummary_imported_members` to display
|
||||||
imported members on autosummary
|
imported members on autosummary
|
||||||
* #6271: ``make clean`` is catastrophically broken if building into '.'
|
* #6271: ``make clean`` is catastrophically broken if building into '.'
|
||||||
|
* Add ``:classmethod:`` and ``:staticmethod:`` options to :rst:dir:`py:method`
|
||||||
|
directive
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
@ -177,6 +177,21 @@ The following is a list of deprecated interfaces.
|
|||||||
- 4.0
|
- 4.0
|
||||||
- ``sphinx.ext.autosummary.AutoLink``
|
- ``sphinx.ext.autosummary.AutoLink``
|
||||||
|
|
||||||
|
* - ``sphinx.ext.imgmath.DOC_BODY``
|
||||||
|
- 2.1
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.ext.imgmath.DOC_BODY_PREVIEW``
|
||||||
|
- 2.1
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.ext.imgmath.DOC_HEAD``
|
||||||
|
- 2.1
|
||||||
|
- 4.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
* - ``sphinx.transforms.CitationReferences``
|
* - ``sphinx.transforms.CitationReferences``
|
||||||
- 2.1
|
- 2.1
|
||||||
- 4.0
|
- 4.0
|
||||||
|
@ -387,14 +387,17 @@ There are also config values that you can set:
|
|||||||
|
|
||||||
The supported options are ``'members'``, ``'member-order'``,
|
The supported options are ``'members'``, ``'member-order'``,
|
||||||
``'undoc-members'``, ``'private-members'``, ``'special-members'``,
|
``'undoc-members'``, ``'private-members'``, ``'special-members'``,
|
||||||
``'inherited-members'``, ``'show-inheritance'``, ``'ignore-module-all'`` and
|
``'inherited-members'``, ``'show-inheritance'``, ``'ignore-module-all'``,
|
||||||
``'exclude-members'``.
|
``'imported-members'`` and ``'exclude-members'``.
|
||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
.. versionchanged:: 2.0
|
.. versionchanged:: 2.0
|
||||||
Accepts ``True`` as a value.
|
Accepts ``True`` as a value.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.1
|
||||||
|
Added ``'imported-members'``.
|
||||||
|
|
||||||
.. confval:: autodoc_docstring_signature
|
.. confval:: autodoc_docstring_signature
|
||||||
|
|
||||||
Functions imported from C modules cannot be introspected, and therefore the
|
Functions imported from C modules cannot be introspected, and therefore the
|
||||||
|
@ -216,6 +216,13 @@ The following directives are provided for module and class contents:
|
|||||||
described for ``function``. See also :ref:`signatures` and
|
described for ``function``. See also :ref:`signatures` and
|
||||||
:ref:`info-field-lists`.
|
:ref:`info-field-lists`.
|
||||||
|
|
||||||
|
The ``classmethod`` option and ``staticmethod`` option can be given (with
|
||||||
|
no value) to indicate the method is a class method (or a static method).
|
||||||
|
|
||||||
|
.. versionchanged:: 2.1
|
||||||
|
|
||||||
|
``:classmethod:`` and ``:staticmethod:`` options added.
|
||||||
|
|
||||||
.. rst:directive:: .. py:staticmethod:: name(parameters)
|
.. rst:directive:: .. py:staticmethod:: name(parameters)
|
||||||
|
|
||||||
Like :rst:dir:`py:method`, but indicates that the method is a static method.
|
Like :rst:dir:`py:method`, but indicates that the method is a static method.
|
||||||
|
@ -562,10 +562,25 @@ class PyClassmember(PyObject):
|
|||||||
class PyMethod(PyObject):
|
class PyMethod(PyObject):
|
||||||
"""Description of a method."""
|
"""Description of a method."""
|
||||||
|
|
||||||
|
option_spec = PyObject.option_spec.copy()
|
||||||
|
option_spec.update({
|
||||||
|
'classmethod': directives.flag,
|
||||||
|
'staticmethod': directives.flag,
|
||||||
|
})
|
||||||
|
|
||||||
def needs_arglist(self):
|
def needs_arglist(self):
|
||||||
# type: () -> bool
|
# type: () -> bool
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_signature_prefix(self, sig):
|
||||||
|
# type: (str) -> str
|
||||||
|
if 'staticmethod' in self.options:
|
||||||
|
return 'static '
|
||||||
|
elif 'classmethod' in self.options:
|
||||||
|
return 'classmethod '
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
def get_index_text(self, modname, name_cls):
|
def get_index_text(self, modname, name_cls):
|
||||||
# type: (str, Tuple[str, str]) -> str
|
# type: (str, Tuple[str, str]) -> str
|
||||||
name, cls = name_cls
|
name, cls = name_cls
|
||||||
@ -579,53 +594,38 @@ class PyMethod(PyObject):
|
|||||||
else:
|
else:
|
||||||
return '%s()' % name
|
return '%s()' % name
|
||||||
|
|
||||||
return _('%s() (%s method)') % (methname, clsname)
|
if 'staticmethod' in self.options:
|
||||||
|
return _('%s() (%s static method)') % (methname, clsname)
|
||||||
|
elif 'classmethod' in self.options:
|
||||||
|
return _('%s() (%s class method)') % (methname, clsname)
|
||||||
|
else:
|
||||||
|
return _('%s() (%s method)') % (methname, clsname)
|
||||||
|
|
||||||
|
|
||||||
class PyClassMethod(PyMethod):
|
class PyClassMethod(PyMethod):
|
||||||
"""Description of a classmethod."""
|
"""Description of a classmethod."""
|
||||||
|
|
||||||
def get_signature_prefix(self, sig):
|
option_spec = PyObject.option_spec.copy()
|
||||||
# type: (str) -> str
|
|
||||||
return 'classmethod '
|
|
||||||
|
|
||||||
def get_index_text(self, modname, name_cls):
|
def run(self):
|
||||||
# type: (str, Tuple[str, str]) -> str
|
# type: () -> List[nodes.Node]
|
||||||
name, cls = name_cls
|
self.name = 'py:method'
|
||||||
try:
|
self.options['classmethod'] = True
|
||||||
clsname, methname = name.rsplit('.', 1)
|
|
||||||
if modname and self.env.config.add_module_names:
|
|
||||||
clsname = '.'.join([modname, clsname])
|
|
||||||
except ValueError:
|
|
||||||
if modname:
|
|
||||||
return _('%s() (in module %s)') % (name, modname)
|
|
||||||
else:
|
|
||||||
return '%s()' % name
|
|
||||||
|
|
||||||
return _('%s() (%s class method)') % (methname, clsname)
|
return super().run()
|
||||||
|
|
||||||
|
|
||||||
class PyStaticMethod(PyMethod):
|
class PyStaticMethod(PyMethod):
|
||||||
"""Description of a staticmethod."""
|
"""Description of a staticmethod."""
|
||||||
|
|
||||||
def get_signature_prefix(self, sig):
|
option_spec = PyObject.option_spec.copy()
|
||||||
# type: (str) -> str
|
|
||||||
return 'static '
|
|
||||||
|
|
||||||
def get_index_text(self, modname, name_cls):
|
def run(self):
|
||||||
# type: (str, Tuple[str, str]) -> str
|
# type: () -> List[nodes.Node]
|
||||||
name, cls = name_cls
|
self.name = 'py:method'
|
||||||
try:
|
self.options['staticmethod'] = True
|
||||||
clsname, methname = name.rsplit('.', 1)
|
|
||||||
if modname and self.env.config.add_module_names:
|
|
||||||
clsname = '.'.join([modname, clsname])
|
|
||||||
except ValueError:
|
|
||||||
if modname:
|
|
||||||
return _('%s() (in module %s)') % (name, modname)
|
|
||||||
else:
|
|
||||||
return '%s()' % name
|
|
||||||
|
|
||||||
return _('%s() (%s static method)') % (methname, clsname)
|
return super().run()
|
||||||
|
|
||||||
|
|
||||||
class PyAttribute(PyObject):
|
class PyAttribute(PyObject):
|
||||||
|
@ -57,10 +57,6 @@ class ReSTMarkup(ObjectDescription):
|
|||||||
|
|
||||||
def get_index_text(self, objectname, name):
|
def get_index_text(self, objectname, name):
|
||||||
# type: (str, str) -> str
|
# type: (str, str) -> str
|
||||||
if self.objtype == 'directive':
|
|
||||||
return _('%s (directive)') % name
|
|
||||||
elif self.objtype == 'role':
|
|
||||||
return _('%s (role)') % name
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
@ -98,6 +94,10 @@ class ReSTDirective(ReSTMarkup):
|
|||||||
signode += addnodes.desc_addname(args, args)
|
signode += addnodes.desc_addname(args, args)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
def get_index_text(self, objectname, name):
|
||||||
|
# type: (str, str) -> str
|
||||||
|
return _('%s (directive)') % name
|
||||||
|
|
||||||
|
|
||||||
class ReSTRole(ReSTMarkup):
|
class ReSTRole(ReSTMarkup):
|
||||||
"""
|
"""
|
||||||
@ -108,6 +108,10 @@ class ReSTRole(ReSTMarkup):
|
|||||||
signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
|
signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
|
||||||
return sig
|
return sig
|
||||||
|
|
||||||
|
def get_index_text(self, objectname, name):
|
||||||
|
# type: (str, str) -> str
|
||||||
|
return _('%s (role)') % name
|
||||||
|
|
||||||
|
|
||||||
class ReSTDomain(Domain):
|
class ReSTDomain(Domain):
|
||||||
"""ReStructuredText domain."""
|
"""ReStructuredText domain."""
|
||||||
|
@ -1269,6 +1269,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
|||||||
Specialized Documenter subclass for methods (normal, static and class).
|
Specialized Documenter subclass for methods (normal, static and class).
|
||||||
"""
|
"""
|
||||||
objtype = 'method'
|
objtype = 'method'
|
||||||
|
directivetype = 'method'
|
||||||
member_order = 50
|
member_order = 50
|
||||||
priority = 1 # must be more than FunctionDocumenter
|
priority = 1 # must be more than FunctionDocumenter
|
||||||
|
|
||||||
@ -1289,16 +1290,11 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
|||||||
if obj is None:
|
if obj is None:
|
||||||
obj = self.object
|
obj = self.object
|
||||||
|
|
||||||
if inspect.isclassmethod(obj):
|
if (inspect.isclassmethod(obj) or
|
||||||
self.directivetype = 'classmethod'
|
inspect.isstaticmethod(obj, cls=self.parent, name=self.object_name)):
|
||||||
# document class and static members before ordinary ones
|
# document class and static members before ordinary ones
|
||||||
self.member_order = self.member_order - 1
|
self.member_order = self.member_order - 1
|
||||||
elif inspect.isstaticmethod(obj, cls=self.parent, name=self.object_name):
|
|
||||||
self.directivetype = 'staticmethod'
|
|
||||||
# document class and static members before ordinary ones
|
|
||||||
self.member_order = self.member_order - 1
|
|
||||||
else:
|
|
||||||
self.directivetype = 'method'
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def format_args(self):
|
def format_args(self):
|
||||||
@ -1314,6 +1310,17 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
|||||||
args = args.replace('\\', '\\\\')
|
args = args.replace('\\', '\\\\')
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
def add_directive_header(self, sig):
|
||||||
|
# type: (str) -> None
|
||||||
|
super().add_directive_header(sig)
|
||||||
|
|
||||||
|
sourcename = self.get_sourcename()
|
||||||
|
obj = self.parent.__dict__.get(self.object_name, self.object)
|
||||||
|
if inspect.isclassmethod(obj):
|
||||||
|
self.add_line(' :classmethod:', sourcename)
|
||||||
|
elif inspect.isstaticmethod(obj, cls=self.parent, name=self.object_name):
|
||||||
|
self.add_line(' :staticmethod:', sourcename)
|
||||||
|
|
||||||
def document_members(self, all_members=False):
|
def document_members(self, all_members=False):
|
||||||
# type: (bool) -> None
|
# type: (bool) -> None
|
||||||
pass
|
pass
|
||||||
|
@ -30,7 +30,8 @@ logger = logging.getLogger(__name__)
|
|||||||
# common option names for autodoc directives
|
# common option names for autodoc directives
|
||||||
AUTODOC_DEFAULT_OPTIONS = ['members', 'undoc-members', 'inherited-members',
|
AUTODOC_DEFAULT_OPTIONS = ['members', 'undoc-members', 'inherited-members',
|
||||||
'show-inheritance', 'private-members', 'special-members',
|
'show-inheritance', 'private-members', 'special-members',
|
||||||
'ignore-module-all', 'exclude-members', 'member-order']
|
'ignore-module-all', 'exclude-members', 'member-order',
|
||||||
|
'imported-members']
|
||||||
|
|
||||||
|
|
||||||
class DummyOptionSpec(dict):
|
class DummyOptionSpec(dict):
|
||||||
|
@ -21,12 +21,15 @@ from subprocess import CalledProcessError, PIPE
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
|
from sphinx import package_dir
|
||||||
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.math import get_node_equation_number, wrap_displaymath
|
from sphinx.util.math import get_node_equation_number, wrap_displaymath
|
||||||
from sphinx.util.osutil import ensuredir
|
from sphinx.util.osutil import ensuredir
|
||||||
from sphinx.util.png import read_png_depth, write_png_depth
|
from sphinx.util.png import read_png_depth, write_png_depth
|
||||||
|
from sphinx.util.template import LaTeXRenderer
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
@ -38,6 +41,8 @@ if False:
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
templates_path = path.join(package_dir, 'templates', 'imgmath')
|
||||||
|
|
||||||
|
|
||||||
class MathExtError(SphinxError):
|
class MathExtError(SphinxError):
|
||||||
category = 'Math extension error'
|
category = 'Math extension error'
|
||||||
@ -87,19 +92,27 @@ DOC_BODY_PREVIEW = r'''
|
|||||||
depth_re = re.compile(br'\[\d+ depth=(-?\d+)\]')
|
depth_re = re.compile(br'\[\d+ depth=(-?\d+)\]')
|
||||||
|
|
||||||
|
|
||||||
def generate_latex_macro(math, config):
|
def generate_latex_macro(math, config, confdir=''):
|
||||||
# type: (str, Config) -> str
|
# type: (str, Config, str) -> str
|
||||||
"""Generate LaTeX macro."""
|
"""Generate LaTeX macro."""
|
||||||
fontsize = config.imgmath_font_size
|
variables = {
|
||||||
baselineskip = int(round(fontsize * 1.2))
|
'fontsize': config.imgmath_font_size,
|
||||||
|
'baselineskip': int(round(config.imgmath_font_size * 1.2)),
|
||||||
|
'preamble': config.imgmath_latex_preamble,
|
||||||
|
'math': math
|
||||||
|
}
|
||||||
|
|
||||||
latex = DOC_HEAD + config.imgmath_latex_preamble
|
|
||||||
if config.imgmath_use_preview:
|
if config.imgmath_use_preview:
|
||||||
latex += DOC_BODY_PREVIEW % (fontsize, baselineskip, math)
|
template_name = 'preview.tex_t'
|
||||||
else:
|
else:
|
||||||
latex += DOC_BODY % (fontsize, baselineskip, math)
|
template_name = 'template.tex_t'
|
||||||
|
|
||||||
return latex
|
for template_dir in config.templates_path:
|
||||||
|
template = path.join(confdir, template_dir, template_name)
|
||||||
|
if path.exists(template):
|
||||||
|
return LaTeXRenderer().render(template, variables)
|
||||||
|
|
||||||
|
return LaTeXRenderer(templates_path).render(template_name, variables)
|
||||||
|
|
||||||
|
|
||||||
def ensure_tempdir(builder):
|
def ensure_tempdir(builder):
|
||||||
@ -220,7 +233,7 @@ def render_math(self, math):
|
|||||||
if image_format not in SUPPORT_FORMAT:
|
if image_format not in SUPPORT_FORMAT:
|
||||||
raise MathExtError('imgmath_image_format must be either "png" or "svg"')
|
raise MathExtError('imgmath_image_format must be either "png" or "svg"')
|
||||||
|
|
||||||
latex = generate_latex_macro(math, self.builder.config)
|
latex = generate_latex_macro(math, self.builder.config, self.builder.confdir)
|
||||||
|
|
||||||
filename = "%s.%s" % (sha1(latex.encode()).hexdigest(), image_format)
|
filename = "%s.%s" % (sha1(latex.encode()).hexdigest(), image_format)
|
||||||
relfn = posixpath.join(self.builder.imgpath, 'math', filename)
|
relfn = posixpath.join(self.builder.imgpath, 'math', filename)
|
||||||
@ -332,6 +345,15 @@ def html_visit_displaymath(self, node):
|
|||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
|
|
||||||
|
deprecated_alias('sphinx.ext.imgmath',
|
||||||
|
{
|
||||||
|
'DOC_BODY': DOC_BODY,
|
||||||
|
'DOC_BODY_PREVIEW': DOC_BODY_PREVIEW,
|
||||||
|
'DOC_HEAD': DOC_HEAD,
|
||||||
|
},
|
||||||
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
# type: (Sphinx) -> Dict[str, Any]
|
||||||
app.add_html_math_renderer('imgmath',
|
app.add_html_math_renderer('imgmath',
|
||||||
|
18
sphinx/templates/imgmath/preview.tex_t
Normal file
18
sphinx/templates/imgmath/preview.tex_t
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
\documentclass[12pt]{article}
|
||||||
|
\usepackage[utf8x]{inputenc}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\usepackage{amsthm}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{amsfonts}
|
||||||
|
\usepackage{anyfontsize}
|
||||||
|
\usepackage{bm}
|
||||||
|
\pagestyle{empty}
|
||||||
|
<%= preamble %>
|
||||||
|
|
||||||
|
\usepackage[active]{preview}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\begin{preview}
|
||||||
|
\fontsize{<%= fontsize %>}{<%= baselineskip %}}\selectfont <%= math %>
|
||||||
|
\end{preview}
|
||||||
|
\end{document}
|
14
sphinx/templates/imgmath/template.tex_t
Normal file
14
sphinx/templates/imgmath/template.tex_t
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
\documentclass[12pt]{article}
|
||||||
|
\usepackage[utf8x]{inputenc}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\usepackage{amsthm}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{amsfonts}
|
||||||
|
\usepackage{anyfontsize}
|
||||||
|
\usepackage{bm}
|
||||||
|
\pagestyle{empty}
|
||||||
|
<%= preamble %>
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\fontsize{<%= fontsize %>}{<%= baselineskip %>}\selectfont <%= math %>
|
||||||
|
\end{document}
|
@ -67,9 +67,10 @@ class SphinxRenderer(FileRenderer):
|
|||||||
|
|
||||||
|
|
||||||
class LaTeXRenderer(SphinxRenderer):
|
class LaTeXRenderer(SphinxRenderer):
|
||||||
def __init__(self):
|
def __init__(self, template_path=None):
|
||||||
# type: () -> None
|
# type: (str) -> None
|
||||||
template_path = os.path.join(package_dir, 'templates', 'latex')
|
if template_path is None:
|
||||||
|
template_path = os.path.join(package_dir, 'templates', 'latex')
|
||||||
super().__init__(template_path)
|
super().__init__(template_path)
|
||||||
|
|
||||||
# use texescape as escape filter
|
# use texescape as escape filter
|
||||||
|
@ -702,9 +702,9 @@ def test_autodoc_members(app):
|
|||||||
actual = do_autodoc(app, 'class', 'target.Base', options)
|
actual = do_autodoc(app, 'class', 'target.Base', options)
|
||||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||||
'.. py:class:: Base',
|
'.. py:class:: Base',
|
||||||
' .. py:classmethod:: Base.inheritedclassmeth()',
|
' .. py:method:: Base.inheritedclassmeth()',
|
||||||
' .. py:method:: Base.inheritedmeth()',
|
' .. py:method:: Base.inheritedmeth()',
|
||||||
' .. py:staticmethod:: Base.inheritedstaticmeth(cls)'
|
' .. py:method:: Base.inheritedstaticmeth(cls)'
|
||||||
]
|
]
|
||||||
|
|
||||||
# default specific-members
|
# default specific-members
|
||||||
@ -713,7 +713,7 @@ def test_autodoc_members(app):
|
|||||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||||
'.. py:class:: Base',
|
'.. py:class:: Base',
|
||||||
' .. py:method:: Base.inheritedmeth()',
|
' .. py:method:: Base.inheritedmeth()',
|
||||||
' .. py:staticmethod:: Base.inheritedstaticmeth(cls)'
|
' .. py:method:: Base.inheritedstaticmeth(cls)'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -724,7 +724,7 @@ def test_autodoc_exclude_members(app):
|
|||||||
actual = do_autodoc(app, 'class', 'target.Base', options)
|
actual = do_autodoc(app, 'class', 'target.Base', options)
|
||||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||||
'.. py:class:: Base',
|
'.. py:class:: Base',
|
||||||
' .. py:classmethod:: Base.inheritedclassmeth()'
|
' .. py:method:: Base.inheritedclassmeth()'
|
||||||
]
|
]
|
||||||
|
|
||||||
# members vs exclude-members
|
# members vs exclude-members
|
||||||
@ -752,9 +752,9 @@ def test_autodoc_undoc_members(app):
|
|||||||
' .. py:attribute:: Class.inst_attr_string',
|
' .. py:attribute:: Class.inst_attr_string',
|
||||||
' .. py:attribute:: Class.mdocattr',
|
' .. py:attribute:: Class.mdocattr',
|
||||||
' .. py:method:: Class.meth()',
|
' .. py:method:: Class.meth()',
|
||||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
' .. py:method:: Class.moore(a, e, f) -> happiness',
|
||||||
' .. py:attribute:: Class.prop',
|
' .. py:attribute:: Class.prop',
|
||||||
' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
||||||
' .. py:attribute:: Class.skipattr',
|
' .. py:attribute:: Class.skipattr',
|
||||||
' .. py:method:: Class.skipmeth()',
|
' .. py:method:: Class.skipmeth()',
|
||||||
' .. py:attribute:: Class.udocattr',
|
' .. py:attribute:: Class.udocattr',
|
||||||
@ -769,11 +769,11 @@ def test_autodoc_inherited_members(app):
|
|||||||
actual = do_autodoc(app, 'class', 'target.Class', options)
|
actual = do_autodoc(app, 'class', 'target.Class', options)
|
||||||
assert list(filter(lambda l: 'method::' in l, actual)) == [
|
assert list(filter(lambda l: 'method::' in l, actual)) == [
|
||||||
' .. py:method:: Class.excludemeth()',
|
' .. py:method:: Class.excludemeth()',
|
||||||
' .. py:classmethod:: Class.inheritedclassmeth()',
|
' .. py:method:: Class.inheritedclassmeth()',
|
||||||
' .. py:method:: Class.inheritedmeth()',
|
' .. py:method:: Class.inheritedmeth()',
|
||||||
' .. py:staticmethod:: Class.inheritedstaticmeth(cls)',
|
' .. py:method:: Class.inheritedstaticmeth(cls)',
|
||||||
' .. py:method:: Class.meth()',
|
' .. py:method:: Class.meth()',
|
||||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
' .. py:method:: Class.moore(a, e, f) -> happiness',
|
||||||
' .. py:method:: Class.skipmeth()'
|
' .. py:method:: Class.skipmeth()'
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -832,9 +832,9 @@ def test_autodoc_special_members(app):
|
|||||||
' .. py:attribute:: Class.inst_attr_string',
|
' .. py:attribute:: Class.inst_attr_string',
|
||||||
' .. py:attribute:: Class.mdocattr',
|
' .. py:attribute:: Class.mdocattr',
|
||||||
' .. py:method:: Class.meth()',
|
' .. py:method:: Class.meth()',
|
||||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
' .. py:method:: Class.moore(a, e, f) -> happiness',
|
||||||
' .. py:attribute:: Class.prop',
|
' .. py:attribute:: Class.prop',
|
||||||
' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
||||||
' .. py:attribute:: Class.skipattr',
|
' .. py:attribute:: Class.skipattr',
|
||||||
' .. py:method:: Class.skipmeth()',
|
' .. py:method:: Class.skipmeth()',
|
||||||
' .. py:attribute:: Class.udocattr',
|
' .. py:attribute:: Class.udocattr',
|
||||||
@ -952,6 +952,34 @@ def test_autodoc_inner_class(app):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
|
def test_autodoc_classmethod(app):
|
||||||
|
actual = do_autodoc(app, 'method', 'target.Base.inheritedclassmeth')
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:method:: Base.inheritedclassmeth()',
|
||||||
|
' :module: target',
|
||||||
|
' :classmethod:',
|
||||||
|
'',
|
||||||
|
' Inherited class method.',
|
||||||
|
' '
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
|
def test_autodoc_staticmethod(app):
|
||||||
|
actual = do_autodoc(app, 'method', 'target.Base.inheritedstaticmeth')
|
||||||
|
assert list(actual) == [
|
||||||
|
'',
|
||||||
|
'.. py:method:: Base.inheritedstaticmeth(cls)',
|
||||||
|
' :module: target',
|
||||||
|
' :staticmethod:',
|
||||||
|
'',
|
||||||
|
' Inherited static method.',
|
||||||
|
' '
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_autodoc_descriptor(app):
|
def test_autodoc_descriptor(app):
|
||||||
actual = do_autodoc(app, 'attribute', 'target.Class.descr')
|
actual = do_autodoc(app, 'attribute', 'target.Class.descr')
|
||||||
@ -1001,8 +1029,8 @@ def test_autodoc_member_order(app):
|
|||||||
' .. py:attribute:: Class.docattr',
|
' .. py:attribute:: Class.docattr',
|
||||||
' .. py:attribute:: Class.udocattr',
|
' .. py:attribute:: Class.udocattr',
|
||||||
' .. py:attribute:: Class.mdocattr',
|
' .. py:attribute:: Class.mdocattr',
|
||||||
' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
||||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
' .. py:method:: Class.moore(a, e, f) -> happiness',
|
||||||
' .. py:attribute:: Class.inst_attr_inline',
|
' .. py:attribute:: Class.inst_attr_inline',
|
||||||
' .. py:attribute:: Class.inst_attr_comment',
|
' .. py:attribute:: Class.inst_attr_comment',
|
||||||
' .. py:attribute:: Class.inst_attr_string',
|
' .. py:attribute:: Class.inst_attr_string',
|
||||||
@ -1019,8 +1047,8 @@ def test_autodoc_member_order(app):
|
|||||||
'.. py:class:: Class(arg)',
|
'.. py:class:: Class(arg)',
|
||||||
' .. py:method:: Class.excludemeth()',
|
' .. py:method:: Class.excludemeth()',
|
||||||
' .. py:method:: Class.meth()',
|
' .. py:method:: Class.meth()',
|
||||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
' .. py:method:: Class.moore(a, e, f) -> happiness',
|
||||||
' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
||||||
' .. py:method:: Class.skipmeth()',
|
' .. py:method:: Class.skipmeth()',
|
||||||
' .. py:method:: Class.undocmeth()',
|
' .. py:method:: Class.undocmeth()',
|
||||||
' .. py:attribute:: Class._private_inst_attr',
|
' .. py:attribute:: Class._private_inst_attr',
|
||||||
@ -1053,9 +1081,9 @@ def test_autodoc_member_order(app):
|
|||||||
' .. py:attribute:: Class.inst_attr_string',
|
' .. py:attribute:: Class.inst_attr_string',
|
||||||
' .. py:attribute:: Class.mdocattr',
|
' .. py:attribute:: Class.mdocattr',
|
||||||
' .. py:method:: Class.meth()',
|
' .. py:method:: Class.meth()',
|
||||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
' .. py:method:: Class.moore(a, e, f) -> happiness',
|
||||||
' .. py:attribute:: Class.prop',
|
' .. py:attribute:: Class.prop',
|
||||||
' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
|
||||||
' .. py:attribute:: Class.skipattr',
|
' .. py:attribute:: Class.skipattr',
|
||||||
' .. py:method:: Class.skipmeth()',
|
' .. py:method:: Class.skipmeth()',
|
||||||
' .. py:attribute:: Class.udocattr',
|
' .. py:attribute:: Class.udocattr',
|
||||||
@ -1557,6 +1585,8 @@ def test_autodoc_default_options(app):
|
|||||||
assert ' .. py:attribute:: EnumCls.val4' not in actual
|
assert ' .. py:attribute:: EnumCls.val4' not in actual
|
||||||
actual = do_autodoc(app, 'class', 'target.CustomIter')
|
actual = do_autodoc(app, 'class', 'target.CustomIter')
|
||||||
assert ' .. py:method:: target.CustomIter' not in actual
|
assert ' .. py:method:: target.CustomIter' not in actual
|
||||||
|
actual = do_autodoc(app, 'module', 'target')
|
||||||
|
assert '.. py:function:: save_traceback(app)' not in actual
|
||||||
|
|
||||||
# with :members:
|
# with :members:
|
||||||
app.config.autodoc_default_options = {'members': None}
|
app.config.autodoc_default_options = {'members': None}
|
||||||
@ -1620,6 +1650,15 @@ def test_autodoc_default_options(app):
|
|||||||
assert ' .. py:method:: CustomIter.snafucate()' in actual
|
assert ' .. py:method:: CustomIter.snafucate()' in actual
|
||||||
assert ' Makes this snafucated.' in actual
|
assert ' Makes this snafucated.' in actual
|
||||||
|
|
||||||
|
# with :imported-members:
|
||||||
|
app.config.autodoc_default_options = {
|
||||||
|
'members': None,
|
||||||
|
'imported-members': None,
|
||||||
|
'ignore-module-all': None,
|
||||||
|
}
|
||||||
|
actual = do_autodoc(app, 'module', 'target')
|
||||||
|
assert '.. py:function:: save_traceback(app)' in actual
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_autodoc_default_options_with_values(app):
|
def test_autodoc_default_options_with_values(app):
|
||||||
@ -1648,7 +1687,7 @@ def test_autodoc_default_options_with_values(app):
|
|||||||
' .. py:attribute:: Class.docattr',
|
' .. py:attribute:: Class.docattr',
|
||||||
' .. py:attribute:: Class.udocattr',
|
' .. py:attribute:: Class.udocattr',
|
||||||
' .. py:attribute:: Class.mdocattr',
|
' .. py:attribute:: Class.mdocattr',
|
||||||
' .. py:classmethod:: Class.moore(a, e, f) -> happiness',
|
' .. py:method:: Class.moore(a, e, f) -> happiness',
|
||||||
' .. py:attribute:: Class.inst_attr_inline',
|
' .. py:attribute:: Class.inst_attr_inline',
|
||||||
' .. py:attribute:: Class.inst_attr_comment',
|
' .. py:attribute:: Class.inst_attr_comment',
|
||||||
' .. py:attribute:: Class.inst_attr_string',
|
' .. py:attribute:: Class.inst_attr_string',
|
||||||
|
@ -315,25 +315,54 @@ def test_pyfunction(app):
|
|||||||
assert domain.objects['func'] == ('index', 'function')
|
assert domain.objects['func'] == ('index', 'function')
|
||||||
|
|
||||||
|
|
||||||
def test_pymethod(app):
|
def test_pymethod_options(app):
|
||||||
text = (".. py:class:: Class\n"
|
text = (".. py:class:: Class\n"
|
||||||
"\n"
|
"\n"
|
||||||
" .. py:method:: meth\n")
|
" .. py:method:: meth1\n"
|
||||||
|
" .. py:method:: meth2\n"
|
||||||
|
" :classmethod:\n"
|
||||||
|
" .. py:method:: meth3\n"
|
||||||
|
" :staticmethod:\n")
|
||||||
domain = app.env.get_domain('py')
|
domain = app.env.get_domain('py')
|
||||||
doctree = restructuredtext.parse(app, text)
|
doctree = restructuredtext.parse(app, text)
|
||||||
assert_node(doctree, (addnodes.index,
|
assert_node(doctree, (addnodes.index,
|
||||||
[desc, ([desc_signature, ([desc_annotation, "class "],
|
[desc, ([desc_signature, ([desc_annotation, "class "],
|
||||||
[desc_name, "Class"])],
|
[desc_name, "Class"])],
|
||||||
[desc_content, (addnodes.index,
|
[desc_content, (addnodes.index,
|
||||||
|
desc,
|
||||||
|
addnodes.index,
|
||||||
|
desc,
|
||||||
|
addnodes.index,
|
||||||
desc)])]))
|
desc)])]))
|
||||||
|
|
||||||
|
# method
|
||||||
assert_node(doctree[1][1][0], addnodes.index,
|
assert_node(doctree[1][1][0], addnodes.index,
|
||||||
entries=[('single', 'meth() (Class method)', 'Class.meth', '', None)])
|
entries=[('single', 'meth1() (Class method)', 'Class.meth1', '', None)])
|
||||||
assert_node(doctree[1][1][1], ([desc_signature, ([desc_name, "meth"],
|
assert_node(doctree[1][1][1], ([desc_signature, ([desc_name, "meth1"],
|
||||||
[desc_parameterlist, ()])],
|
[desc_parameterlist, ()])],
|
||||||
[desc_content, ()]))
|
[desc_content, ()]))
|
||||||
assert 'Class.meth' in domain.objects
|
assert 'Class.meth1' in domain.objects
|
||||||
assert domain.objects['Class.meth'] == ('index', 'method')
|
assert domain.objects['Class.meth1'] == ('index', 'method')
|
||||||
|
|
||||||
|
# :classmethod:
|
||||||
|
assert_node(doctree[1][1][2], addnodes.index,
|
||||||
|
entries=[('single', 'meth2() (Class class method)', 'Class.meth2', '', None)])
|
||||||
|
assert_node(doctree[1][1][3], ([desc_signature, ([desc_annotation, "classmethod "],
|
||||||
|
[desc_name, "meth2"],
|
||||||
|
[desc_parameterlist, ()])],
|
||||||
|
[desc_content, ()]))
|
||||||
|
assert 'Class.meth2' in domain.objects
|
||||||
|
assert domain.objects['Class.meth2'] == ('index', 'method')
|
||||||
|
|
||||||
|
# :staticmethod:
|
||||||
|
assert_node(doctree[1][1][4], addnodes.index,
|
||||||
|
entries=[('single', 'meth3() (Class static method)', 'Class.meth3', '', None)])
|
||||||
|
assert_node(doctree[1][1][5], ([desc_signature, ([desc_annotation, "static "],
|
||||||
|
[desc_name, "meth3"],
|
||||||
|
[desc_parameterlist, ()])],
|
||||||
|
[desc_content, ()]))
|
||||||
|
assert 'Class.meth3' in domain.objects
|
||||||
|
assert domain.objects['Class.meth3'] == ('index', 'method')
|
||||||
|
|
||||||
|
|
||||||
def test_pyclassmethod(app):
|
def test_pyclassmethod(app):
|
||||||
@ -354,7 +383,7 @@ def test_pyclassmethod(app):
|
|||||||
[desc_parameterlist, ()])],
|
[desc_parameterlist, ()])],
|
||||||
[desc_content, ()]))
|
[desc_content, ()]))
|
||||||
assert 'Class.meth' in domain.objects
|
assert 'Class.meth' in domain.objects
|
||||||
assert domain.objects['Class.meth'] == ('index', 'classmethod')
|
assert domain.objects['Class.meth'] == ('index', 'method')
|
||||||
|
|
||||||
|
|
||||||
def test_pystaticmethod(app):
|
def test_pystaticmethod(app):
|
||||||
@ -375,7 +404,7 @@ def test_pystaticmethod(app):
|
|||||||
[desc_parameterlist, ()])],
|
[desc_parameterlist, ()])],
|
||||||
[desc_content, ()]))
|
[desc_content, ()]))
|
||||||
assert 'Class.meth' in domain.objects
|
assert 'Class.meth' in domain.objects
|
||||||
assert domain.objects['Class.meth'] == ('index', 'staticmethod')
|
assert domain.objects['Class.meth'] == ('index', 'method')
|
||||||
|
|
||||||
|
|
||||||
def test_pyattribute(app):
|
def test_pyattribute(app):
|
||||||
|
Loading…
Reference in New Issue
Block a user