diff --git a/AUTHORS b/AUTHORS
index dbe1082a6..4b6aa8ffb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -85,6 +85,7 @@ Other contributors, listed alphabetically, are:
* Daniel Pizetta -- inheritance diagram improvements
* KINEBUCHI Tomohiko -- typing Sphinx as well as docutils
* Adrián Chaves (Gallaecio) -- coverage builder improvements
+* Lars Hupfeldt Nielsen - OpenSSL FIPS mode md5 bug fix
Many thanks for all contributions!
diff --git a/CHANGES b/CHANGES
index 9bb47a4e7..7d81e3a3e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -64,6 +64,7 @@ Deprecated
generate_autosummary_docs()``
* The ``ignore`` argument of ``sphinx.util.docstring.prepare_docstring()``
* ``sphinx.ext.autosummary.generate.AutosummaryRenderer.exists()``
+* ``sphinx.util.rpartition()``
Features added
--------------
@@ -107,6 +108,7 @@ Features added
* C++, parse trailing return types.
* #7143: py domain: Add ``:final:`` option to :rst:dir:`py:class:`,
:rst:dir:`py:exception:` and :rst:dir:`py:method:` directives
+* #7596: py domain: Change a type annotation for variables to a hyperlink
* #7582: napoleon: a type for attribute are represented like type annotation
Bugs fixed
@@ -121,10 +123,30 @@ Bugs fixed
* #6857: autodoc: failed to detect a classmethod on Enum class
* #7562: autodoc: a typehint contains spaces is wrongly rendered under
autodoc_typehints='description' mode
+* #7551: autodoc: failed to import nested class
+* #7362: autodoc: does not render correct signatures for built-in functions
+* #7654: autodoc: ``Optional[Union[foo, bar]]`` is presented as
+ ``Union[foo, bar, None]``
+* #7629: autodoc: autofunction emits an unfriendly warning if an invalid object
+ specified
+* #7650: autodoc: undecorated signature is shown for decorated functions
+* #7676: autodoc: typo in the default value of autodoc_member_order
+* #7551: autosummary: a nested class is indexed as non-nested class
+* #7661: autosummary: autosummary directive emits warnings twices if failed to
+ import the target module
* #7535: sphinx-autogen: crashes when custom template uses inheritance
* #7536: sphinx-autogen: crashes when template uses i18n feature
+* #7653: sphinx-quickstart: Fix multiple directory creation for nested relpath
* #2785: html: Bad alignment of equation links
* #7581: napoleon: bad parsing of inline code in attribute docstrings
+* #7628: imgconverter: runs imagemagick once unnecessary for builders not
+ supporting images
+* #7610: incorrectly renders consecutive backslashes for docutils-0.16
+* #7646: handle errors on event handlers
+* C++, fix rendering and xrefs in nested names explicitly starting
+ in global scope, e.g., ``::A::B``.
+* C, fix rendering and xrefs in nested names explicitly starting
+ in global scope, e.g., ``.A.B``.
Testing
--------
@@ -148,6 +170,9 @@ Bugs fixed
----------
* #7567: autodoc: parametrized types are shown twice for generic types
+* #7637: autodoc: system defined TypeVars are shown in Python 3.9
+* #7611: md5 fails when OpenSSL FIPS is enabled
+* #7626: release package does not contain ``CODE_OF_CONDUCT``
Testing
--------
@@ -1432,7 +1457,7 @@ Incompatible changes
object. Please use ``config.gettext_compact`` instead.
* The processing order on reading phase is changed. smart_quotes, sphinx
domains, :event:`doctree-read` event and versioning doctrees are invoked
- earlier than so far. For more details, please read a description of
+ earlier than so far. For more details, please read a description of
:py:meth:`.Sphinx.add_transform()`
* #4827: All ``substitution_definition`` nodes are removed from doctree on
reading phase
diff --git a/MANIFEST.in b/MANIFEST.in
index a5699c23c..54da42895 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -3,6 +3,7 @@ include LICENSE
include AUTHORS
include CHANGES
include CHANGES.old
+include CODE_OF_CONDUCT
include CONTRIBUTING.rst
include EXAMPLES
diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst
index 2df82ed5a..b93355860 100644
--- a/doc/extdev/deprecated.rst
+++ b/doc/extdev/deprecated.rst
@@ -108,6 +108,11 @@ The following is a list of deprecated interfaces.
- 5.0
- N/A
+ * - ``sphinx.util.rpartition()``
+ - 3.1
+ - 5.0
+ - ``str.rpartition()``
+
* - ``desc_signature['first']``
-
- 3.0
diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst
index 9b2858497..2618e8629 100644
--- a/doc/usage/configuration.rst
+++ b/doc/usage/configuration.rst
@@ -1384,7 +1384,7 @@ that use Sphinx's HTMLWriter class.
.. versionadded:: 1.3
- .. versionchanged:: 2.4
+ .. versionchanged:: 3.0
It is disabled for images having ``no-scaled-link`` class
diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py
index 42a0faed6..c98cdcbe1 100644
--- a/sphinx/addnodes.py
+++ b/sphinx/addnodes.py
@@ -109,6 +109,13 @@ class desc_signature(nodes.Part, nodes.Inline, nodes.TextElement):
In that case all child nodes must be ``desc_signature_line`` nodes.
"""
+ @property
+ def child_text_separator(self):
+ if self.get('is_multiline'):
+ return ' '
+ else:
+ return super().child_text_separator
+
class desc_signature_line(nodes.Part, nodes.Inline, nodes.FixedTextElement):
"""Node for a line in a multi-line object signatures.
@@ -147,6 +154,9 @@ class desc_parameterlist(nodes.Part, nodes.Inline, nodes.FixedTextElement):
"""Node for a general parameter list."""
child_text_separator = ', '
+ def astext(self):
+ return '({})'.format(super().astext())
+
class desc_parameter(nodes.Part, nodes.Inline, nodes.FixedTextElement):
"""Node for a single parameter."""
diff --git a/sphinx/application.py b/sphinx/application.py
index 04d6dc952..ae98e8f1b 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -200,7 +200,7 @@ class Sphinx:
# notice for parallel build on macOS and py38+
if sys.version_info > (3, 8) and platform.system() == 'Darwin' and parallel > 1:
logger.info(bold(__("For security reason, parallel mode is disabled on macOS and "
- "python3.8 and above. For more details, please read "
+ "python3.8 and above. For more details, please read "
"https://github.com/sphinx-doc/sphinx/issues/6803")))
# status code for command-line application
diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py
index 2a2691851..963a07ece 100644
--- a/sphinx/builders/html/__init__.py
+++ b/sphinx/builders/html/__init__.py
@@ -12,7 +12,6 @@ import html
import posixpath
import re
import sys
-from hashlib import md5
from os import path
from typing import Any, Dict, IO, Iterable, Iterator, List, Set, Tuple, Type
@@ -36,7 +35,7 @@ from sphinx.highlighting import PygmentsBridge
from sphinx.locale import _, __
from sphinx.search import js_index
from sphinx.theming import HTMLThemeFactory
-from sphinx.util import logging, progress_message, status_iterator
+from sphinx.util import logging, progress_message, status_iterator, md5
from sphinx.util.docutils import is_html5_writer_available, new_document
from sphinx.util.fileutil import copy_asset
from sphinx.util.i18n import format_date
diff --git a/sphinx/cmd/build.py b/sphinx/cmd/build.py
index cf50f1730..c4cf11cc4 100644
--- a/sphinx/cmd/build.py
+++ b/sphinx/cmd/build.py
@@ -64,7 +64,7 @@ def handle_exception(app: Sphinx, args: Any, exception: BaseException, stderr: I
print(terminal_safe(str(exception)), file=stderr)
print(file=stderr)
print(__('This can happen with very large or deeply nested source '
- 'files. You can carefully increase the default Python '
+ 'files. You can carefully increase the default Python '
'recursion limit of 1000 in conf.py with e.g.:'), file=stderr)
print(' import sys; sys.setrecursionlimit(1500)', file=stderr)
else:
@@ -107,7 +107,7 @@ Generate documentation from source files.
sphinx-build generates documentation from the files in SOURCEDIR and places it
in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration
-settings. The 'sphinx-quickstart' tool may be used to generate template files,
+settings. The 'sphinx-quickstart' tool may be used to generate template files,
including 'conf.py'
sphinx-build can create documentation in different formats. A format is
diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py
index 802549304..68f8b2a18 100644
--- a/sphinx/cmd/quickstart.py
+++ b/sphinx/cmd/quickstart.py
@@ -237,7 +237,7 @@ def ask_user(d: Dict) -> None:
print(__('Sphinx has the notion of a "version" and a "release" for the\n'
'software. Each version can have multiple releases. For example, for\n'
'Python the version is something like 2.5 or 3.0, while the release is\n'
- 'something like 2.5.1 or 3.0a1. If you don\'t need this dual structure,\n'
+ 'something like 2.5.1 or 3.0a1. If you don\'t need this dual structure,\n'
'just set both to the same value.'))
d['version'] = do_prompt(__('Project version'), '', allow_empty)
if 'release' not in d:
@@ -258,7 +258,7 @@ def ask_user(d: Dict) -> None:
if 'suffix' not in d:
print()
print(__('The file name suffix for source files. Commonly, this is either ".txt"\n'
- 'or ".rst". Only files with this suffix are considered documents.'))
+ 'or ".rst". Only files with this suffix are considered documents.'))
d['suffix'] = do_prompt(__('Source file suffix'), '.rst', suffix)
if 'master' not in d:
@@ -319,6 +319,7 @@ def generate(d: Dict, overwrite: bool = True, silent: bool = False, templatedir:
d.setdefault('extensions', [])
d['copyright'] = time.strftime('%Y') + ', ' + d['author']
+ d["path"] = os.path.abspath(d['path'])
ensuredir(d['path'])
srcdir = path.join(d['path'], 'source') if d['sep'] else d['path']
diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py
index 6e0dc2a54..164a87254 100644
--- a/sphinx/domains/c.py
+++ b/sphinx/domains/c.py
@@ -186,11 +186,17 @@ class ASTNestedName(ASTBase):
# If lastIsName, then wrap all of the prefix in a desc_addname,
# else append directly to signode.
# TODO: also for C?
- # NOTE: Breathe relies on the prefix being in the desc_addname node,
+ # NOTE: Breathe previously relied on the prefix being in the desc_addname node,
# so it can remove it in inner declarations.
dest = signode
if mode == 'lastIsName':
dest = addnodes.desc_addname()
+ if self.rooted:
+ prefix += '.'
+ if mode == 'lastIsName' and len(names) == 0:
+ signode += nodes.Text('.')
+ else:
+ dest += nodes.Text('.')
for i in range(len(names)):
ident = names[i]
if not first:
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 4dc8809ec..b801f4030 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -752,11 +752,17 @@ class ASTNestedName(ASTBase):
names = self.names[:-1] if mode == 'lastIsName' else self.names
# If lastIsName, then wrap all of the prefix in a desc_addname,
# else append directly to signode.
- # NOTE: Breathe relies on the prefix being in the desc_addname node,
+ # NOTE: Breathe previously relied on the prefix being in the desc_addname node,
# so it can remove it in inner declarations.
dest = signode
if mode == 'lastIsName':
dest = addnodes.desc_addname()
+ if self.rooted:
+ prefix += '::'
+ if mode == 'lastIsName' and len(names) == 0:
+ signode += nodes.Text('::')
+ else:
+ dest += nodes.Text('::')
for i in range(len(names)):
nne = names[i]
template = self.templates[i]
@@ -3722,8 +3728,8 @@ class LookupKey:
class Symbol:
debug_indent = 0
debug_indent_string = " "
- debug_lookup = False
- debug_show_tree = False
+ debug_lookup = False # overridden by the corresponding config value
+ debug_show_tree = False # overridden by the corresponding config value
@staticmethod
def debug_print(*args: Any) -> None:
@@ -7383,9 +7389,18 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value("cpp_paren_attributes", [], 'env')
app.add_post_transform(AliasTransform)
+ # debug stuff
+ app.add_config_value("cpp_debug_lookup", False, '')
+ app.add_config_value("cpp_debug_show_tree", False, '')
+
+ def setDebugFlags(app):
+ Symbol.debug_lookup = app.config.cpp_debug_lookup
+ Symbol.debug_show_tree = app.config.cpp_debug_show_tree
+ app.connect("builder-inited", setDebugFlags)
+
return {
'version': 'builtin',
- 'env_version': 2,
+ 'env_version': 3,
'parallel_read_safe': True,
'parallel_write_safe': True,
}
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index 0f3f089a7..f348a6f3a 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -74,17 +74,19 @@ ModuleEntry = NamedTuple('ModuleEntry', [('docname', str),
('deprecated', bool)])
+def type_to_xref(text: str) -> addnodes.pending_xref:
+ """Convert a type string to a cross reference node."""
+ if text == 'None':
+ reftype = 'obj'
+ else:
+ reftype = 'class'
+
+ return pending_xref('', nodes.Text(text),
+ refdomain='py', reftype=reftype, reftarget=text)
+
+
def _parse_annotation(annotation: str) -> List[Node]:
"""Parse type annotation."""
- def make_xref(text: str) -> addnodes.pending_xref:
- if text == 'None':
- reftype = 'obj'
- else:
- reftype = 'class'
-
- return pending_xref('', nodes.Text(text),
- refdomain='py', reftype=reftype, reftarget=text)
-
def unparse(node: ast.AST) -> List[Node]:
if isinstance(node, ast.Attribute):
return [nodes.Text("%s.%s" % (unparse(node.value)[0], node.attr))]
@@ -130,10 +132,10 @@ def _parse_annotation(annotation: str) -> List[Node]:
result = unparse(tree)
for i, node in enumerate(result):
if isinstance(node, nodes.Text):
- result[i] = make_xref(str(node))
+ result[i] = type_to_xref(str(node))
return result
except SyntaxError:
- return [make_xref(annotation)]
+ return [type_to_xref(annotation)]
def _parse_arglist(arglist: str) -> addnodes.desc_parameterlist:
@@ -590,7 +592,7 @@ class PyVariable(PyObject):
typ = self.options.get('type')
if typ:
- signode += addnodes.desc_annotation(typ, ': ' + typ)
+ signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), type_to_xref(typ))
value = self.options.get('value')
if value:
@@ -750,7 +752,7 @@ class PyAttribute(PyObject):
typ = self.options.get('type')
if typ:
- signode += addnodes.desc_annotation(typ, ': ' + typ)
+ signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), type_to_xref(typ))
value = self.options.get('value')
if value:
diff --git a/sphinx/events.py b/sphinx/events.py
index 4673fddd8..fae870b4b 100644
--- a/sphinx/events.py
+++ b/sphinx/events.py
@@ -15,7 +15,7 @@ from operator import attrgetter
from typing import Any, Callable, Dict, List, NamedTuple
from typing import TYPE_CHECKING
-from sphinx.errors import ExtensionError
+from sphinx.errors import ExtensionError, SphinxError
from sphinx.locale import __
from sphinx.util import logging
@@ -95,7 +95,13 @@ class EventManager:
results = []
listeners = sorted(self.listeners[name], key=attrgetter("priority"))
for listener in listeners:
- results.append(listener.handler(self.app, *args))
+ try:
+ results.append(listener.handler(self.app, *args))
+ except SphinxError:
+ raise
+ except Exception as exc:
+ raise ExtensionError(__("Handler %r for event %r threw an exception") %
+ (listener.handler, name)) from exc
return results
def emit_firstresult(self, name: str, *args: Any) -> Any:
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index e18dc47b9..98a3cc85d 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -17,13 +17,12 @@ from inspect import Parameter
from types import ModuleType
from typing import Any, Callable, Dict, Iterator, List, Sequence, Set, Tuple, Type, Union
from typing import TYPE_CHECKING
-from unittest.mock import patch
from docutils.statemachine import StringList
import sphinx
from sphinx.application import Sphinx
-from sphinx.config import ENUM
+from sphinx.config import Config, ENUM
from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.environment import BuildEnvironment
from sphinx.ext.autodoc.importer import import_object, get_module_members, get_object_members
@@ -32,7 +31,7 @@ from sphinx.locale import _, __
from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.util import inspect
from sphinx.util import logging
-from sphinx.util import rpartition
+from sphinx.util import split_full_qualified_name
from sphinx.util.docstrings import extract_metadata, prepare_docstring
from sphinx.util.inspect import getdoc, object_description, safe_getattr, stringify_signature
from sphinx.util.typing import stringify as stringify_typehint
@@ -311,7 +310,8 @@ class Documenter:
modname = None
parents = []
- self.modname, self.objpath = self.resolve_name(modname, parents, path, base)
+ with mock(self.env.config.autodoc_mock_imports):
+ self.modname, self.objpath = self.resolve_name(modname, parents, path, base)
if not self.modname:
return False
@@ -419,8 +419,15 @@ class Documenter:
directive = getattr(self, 'directivetype', self.objtype)
name = self.format_name()
sourcename = self.get_sourcename()
- self.add_line('.. %s:%s:: %s%s' % (domain, directive, name, sig),
- sourcename)
+
+ # one signature per line, indented by column
+ prefix = '.. %s:%s:: ' % (domain, directive)
+ for i, sig_line in enumerate(sig.split("\n")):
+ self.add_line('%s%s%s' % (prefix, name, sig_line),
+ sourcename)
+ if i == 0:
+ prefix = " " * len(prefix)
+
if self.options.noindex:
self.add_line(' :noindex:', sourcename)
if self.objpath:
@@ -893,8 +900,14 @@ class ModuleLevelDocumenter(Documenter):
) -> Tuple[str, List[str]]:
if modname is None:
if path:
- modname = path.rstrip('.')
- else:
+ stripped = path.rstrip('.')
+ modname, qualname = split_full_qualified_name(stripped)
+ if qualname:
+ parents = qualname.split(".")
+ else:
+ parents = []
+
+ if modname is None:
# if documenting a toplevel object without explicit module,
# it can be contained in another auto directive ...
modname = self.env.temp_data.get('autodoc:module')
@@ -927,8 +940,13 @@ class ClassLevelDocumenter(Documenter):
# ... if still None, there's no way to know
if mod_cls is None:
return None, []
- modname, cls = rpartition(mod_cls, '.')
- parents = [cls]
+
+ try:
+ modname, qualname = split_full_qualified_name(mod_cls)
+ parents = qualname.split(".") if qualname else []
+ except ImportError:
+ parents = mod_cls.split(".")
+
# if the module name is still missing, get it like above
if not modname:
modname = self.env.temp_data.get('autodoc:module')
@@ -1026,43 +1044,19 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
if self.env.config.autodoc_typehints in ('none', 'description'):
kwargs.setdefault('show_annotation', False)
- unwrapped = inspect.unwrap(self.object)
- if ((inspect.isbuiltin(unwrapped) or inspect.ismethoddescriptor(unwrapped)) and
- not inspect.is_cython_function_or_method(unwrapped)):
- # cannot introspect arguments of a C function or method
- return None
try:
- if (not inspect.isfunction(unwrapped) and
- not inspect.ismethod(unwrapped) and
- not inspect.isbuiltin(unwrapped) and
- not inspect.is_cython_function_or_method(unwrapped) and
- not inspect.isclass(unwrapped) and
- hasattr(unwrapped, '__call__')):
- self.env.app.emit('autodoc-before-process-signature',
- unwrapped.__call__, False)
- sig = inspect.signature(unwrapped.__call__)
+ self.env.app.emit('autodoc-before-process-signature', self.object, False)
+ if inspect.is_singledispatch_function(self.object):
+ sig = inspect.signature(self.object, follow_wrapped=True)
else:
- self.env.app.emit('autodoc-before-process-signature', unwrapped, False)
- sig = inspect.signature(unwrapped)
+ sig = inspect.signature(self.object)
args = stringify_signature(sig, **kwargs)
- except TypeError:
- if (inspect.is_builtin_class_method(unwrapped, '__new__') and
- inspect.is_builtin_class_method(unwrapped, '__init__')):
- raise TypeError('%r is a builtin class' % unwrapped)
-
- # if a class should be documented as function (yay duck
- # typing) we try to use the constructor signature as function
- # signature without the first argument.
- try:
- self.env.app.emit('autodoc-before-process-signature',
- unwrapped.__new__, True)
- sig = inspect.signature(unwrapped.__new__, bound_method=True)
- args = stringify_signature(sig, show_return_annotation=False, **kwargs)
- except TypeError:
- self.env.app.emit('autodoc-before-process-signature',
- unwrapped.__init__, True)
- sig = inspect.signature(unwrapped.__init__, bound_method=True)
- args = stringify_signature(sig, show_return_annotation=False, **kwargs)
+ except TypeError as exc:
+ logger.warning(__("Failed to get a function signature for %s: %s"),
+ self.fullname, exc)
+ return None
+ except ValueError:
+ args = ''
if self.env.config.strip_signature_backslash:
# escape backslashes for reST
@@ -1074,41 +1068,28 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
def add_directive_header(self, sig: str) -> None:
sourcename = self.get_sourcename()
- if inspect.is_singledispatch_function(self.object):
- self.add_singledispatch_directive_header(sig)
- else:
- super().add_directive_header(sig)
+ super().add_directive_header(sig)
if inspect.iscoroutinefunction(self.object):
self.add_line(' :async:', sourcename)
- def add_singledispatch_directive_header(self, sig: str) -> None:
- sourcename = self.get_sourcename()
+ def format_signature(self, **kwargs: Any) -> str:
+ sig = super().format_signature(**kwargs)
+ sigs = [sig]
- # intercept generated directive headers
- # TODO: It is very hacky to use mock to intercept header generation
- with patch.object(self, 'add_line') as add_line:
- super().add_directive_header(sig)
+ if inspect.is_singledispatch_function(self.object):
+ # append signature of singledispatch'ed functions
+ for typ, func in self.object.registry.items():
+ if typ is object:
+ pass # default implementation. skipped.
+ else:
+ self.annotate_to_first_argument(func, typ)
- # output first line of header
- self.add_line(*add_line.call_args_list[0][0])
+ documenter = FunctionDocumenter(self.directive, '')
+ documenter.object = func
+ sigs.append(documenter.format_signature())
- # inserts signature of singledispatch'ed functions
- for typ, func in self.object.registry.items():
- if typ is object:
- pass # default implementation. skipped.
- else:
- self.annotate_to_first_argument(func, typ)
-
- documenter = FunctionDocumenter(self.directive, '')
- documenter.object = func
- self.add_line(' %s%s' % (self.format_name(),
- documenter.format_signature()),
- sourcename)
-
- # output remains of directive header
- for call in add_line.call_args_list[1:]:
- self.add_line(*call[0])
+ return "\n".join(sigs)
def annotate_to_first_argument(self, func: Callable, typ: Type) -> None:
"""Annotate type hint to the first argument of function if needed."""
@@ -1448,18 +1429,33 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
if self.env.config.autodoc_typehints in ('none', 'description'):
kwargs.setdefault('show_annotation', False)
- unwrapped = inspect.unwrap(self.object)
- if ((inspect.isbuiltin(unwrapped) or inspect.ismethoddescriptor(unwrapped)) and
- not inspect.is_cython_function_or_method(unwrapped)):
- # can never get arguments of a C function or method
+ try:
+ if self.object == object.__init__ and self.parent != object:
+ # Classes not having own __init__() method are shown as no arguments.
+ #
+ # Note: The signature of object.__init__() is (self, /, *args, **kwargs).
+ # But it makes users confused.
+ args = '()'
+ else:
+ if inspect.isstaticmethod(self.object, cls=self.parent, name=self.object_name):
+ self.env.app.emit('autodoc-before-process-signature', self.object, False)
+ sig = inspect.signature(self.object, bound_method=False)
+ else:
+ self.env.app.emit('autodoc-before-process-signature', self.object, True)
+
+ meth = self.parent.__dict__.get(self.objpath[-1], None)
+ if meth and inspect.is_singledispatch_method(meth):
+ sig = inspect.signature(self.object, bound_method=True,
+ follow_wrapped=True)
+ else:
+ sig = inspect.signature(self.object, bound_method=True)
+ args = stringify_signature(sig, **kwargs)
+ except TypeError as exc:
+ logger.warning(__("Failed to get a method signature for %s: %s"),
+ self.fullname, exc)
return None
- if inspect.isstaticmethod(unwrapped, cls=self.parent, name=self.object_name):
- self.env.app.emit('autodoc-before-process-signature', unwrapped, False)
- sig = inspect.signature(unwrapped, bound_method=False)
- else:
- self.env.app.emit('autodoc-before-process-signature', unwrapped, True)
- sig = inspect.signature(unwrapped, bound_method=True)
- args = stringify_signature(sig, **kwargs)
+ except ValueError:
+ args = ''
if self.env.config.strip_signature_backslash:
# escape backslashes for reST
@@ -1467,11 +1463,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
return args
def add_directive_header(self, sig: str) -> None:
- meth = self.parent.__dict__.get(self.objpath[-1])
- if inspect.is_singledispatch_method(meth):
- self.add_singledispatch_directive_header(sig)
- else:
- super().add_directive_header(sig)
+ super().add_directive_header(sig)
sourcename = self.get_sourcename()
obj = self.parent.__dict__.get(self.object_name, self.object)
@@ -1489,34 +1481,26 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
def document_members(self, all_members: bool = False) -> None:
pass
- def add_singledispatch_directive_header(self, sig: str) -> None:
- sourcename = self.get_sourcename()
+ def format_signature(self, **kwargs: Any) -> str:
+ sig = super().format_signature(**kwargs)
+ sigs = [sig]
- # intercept generated directive headers
- # TODO: It is very hacky to use mock to intercept header generation
- with patch.object(self, 'add_line') as add_line:
- super().add_directive_header(sig)
-
- # output first line of header
- self.add_line(*add_line.call_args_list[0][0])
-
- # inserts signature of singledispatch'ed functions
meth = self.parent.__dict__.get(self.objpath[-1])
- for typ, func in meth.dispatcher.registry.items():
- if typ is object:
- pass # default implementation. skipped.
- else:
- self.annotate_to_first_argument(func, typ)
+ if inspect.is_singledispatch_method(meth):
+ # append signature of singledispatch'ed functions
+ for typ, func in meth.dispatcher.registry.items():
+ if typ is object:
+ pass # default implementation. skipped.
+ else:
+ self.annotate_to_first_argument(func, typ)
- documenter = MethodDocumenter(self.directive, '')
- documenter.object = func
- self.add_line(' %s%s' % (self.format_name(),
- documenter.format_signature()),
- sourcename)
+ documenter = MethodDocumenter(self.directive, '')
+ documenter.parent = self.parent
+ documenter.object = func
+ documenter.objpath = [None]
+ sigs.append(documenter.format_signature())
- # output remains of directive header
- for call in add_line.call_args_list[1:]:
- self.add_line(*call[0])
+ return "\n".join(sigs)
def annotate_to_first_argument(self, func: Callable, typ: Type) -> None:
"""Annotate type hint to the first argument of function if needed."""
@@ -1753,6 +1737,14 @@ def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs: Any) -> Any:
return safe_getattr(obj, name, *defargs)
+def migrate_autodoc_member_order(app: Sphinx, config: Config) -> None:
+ if config.autodoc_member_order == 'alphabetic':
+ # RemovedInSphinx50Warning
+ logger.warning(__('autodoc_member_order now accepts "alphabetical" '
+ 'instead of "alphabetic". Please update your setting.'))
+ config.autodoc_member_order = 'alphabetical' # type: ignore
+
+
def setup(app: Sphinx) -> Dict[str, Any]:
app.add_autodocumenter(ModuleDocumenter)
app.add_autodocumenter(ClassDocumenter)
@@ -1768,7 +1760,8 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_autodocumenter(SlotsAttributeDocumenter)
app.add_config_value('autoclass_content', 'class', True, ENUM('both', 'class', 'init'))
- app.add_config_value('autodoc_member_order', 'alphabetic', True)
+ app.add_config_value('autodoc_member_order', 'alphabetical', True,
+ ENUM('alphabetic', 'alphabetical', 'bysource', 'groupwise'))
app.add_config_value('autodoc_default_options', {}, True)
app.add_config_value('autodoc_docstring_signature', True, True)
app.add_config_value('autodoc_mock_imports', [], True)
@@ -1781,6 +1774,8 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member')
+ app.connect('config-inited', migrate_autodoc_member_order)
+
app.setup_extension('sphinx.ext.autodoc.type_comment')
app.setup_extension('sphinx.ext.autodoc.typehints')
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index 861b1e6b0..de493f4cf 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -298,8 +298,7 @@ class Autosummary(SphinxDirective):
with mock(self.config.autosummary_mock_imports):
real_name, obj, parent, modname = import_by_name(name, prefixes=prefixes)
except ImportError:
- logger.warning(__('failed to import %s'), name)
- items.append((name, '', '', name))
+ logger.warning(__('autosummary: failed to import %s'), name)
continue
self.bridge.result = StringList() # initialize for each documenter
diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py
index b2eb33db7..2faa7f4a1 100644
--- a/sphinx/ext/autosummary/generate.py
+++ b/sphinx/ext/autosummary/generate.py
@@ -45,6 +45,7 @@ from sphinx.locale import __
from sphinx.registry import SphinxComponentRegistry
from sphinx.util import logging
from sphinx.util import rst
+from sphinx.util import split_full_qualified_name
from sphinx.util.inspect import safe_getattr
from sphinx.util.osutil import ensuredir
from sphinx.util.template import SphinxTemplateLoader
@@ -244,19 +245,19 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
ns['attributes'], ns['all_attributes'] = \
get_members(obj, {'attribute', 'property'})
- parts = name.split('.')
+ modname, qualname = split_full_qualified_name(name)
if doc.objtype in ('method', 'attribute', 'property'):
- mod_name = '.'.join(parts[:-2])
- cls_name = parts[-2]
- obj_name = '.'.join(parts[-2:])
- ns['class'] = cls_name
+ ns['class'] = qualname.rsplit(".", 1)[0]
+
+ if doc.objtype in ('class',):
+ shortname = qualname
else:
- mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]
+ shortname = qualname.rsplit(".", 1)[-1]
ns['fullname'] = name
- ns['module'] = mod_name
- ns['objname'] = obj_name
- ns['name'] = parts[-1]
+ ns['module'] = modname
+ ns['objname'] = qualname
+ ns['name'] = shortname
ns['objtype'] = doc.objtype
ns['underline'] = len(name) * '='
diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py
index 27b64fbce..c21868a6f 100644
--- a/sphinx/ext/graphviz.py
+++ b/sphinx/ext/graphviz.py
@@ -12,7 +12,6 @@
import posixpath
import re
import subprocess
-from hashlib import sha1
from os import path
from subprocess import CalledProcessError, PIPE
from typing import Any, Dict, List, Tuple
@@ -25,7 +24,7 @@ import sphinx
from sphinx.application import Sphinx
from sphinx.errors import SphinxError
from sphinx.locale import _, __
-from sphinx.util import logging
+from sphinx.util import logging, sha1
from sphinx.util.docutils import SphinxDirective, SphinxTranslator
from sphinx.util.fileutil import copy_asset
from sphinx.util.i18n import search_image_for_language
diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py
index 90271a6ee..65f281223 100644
--- a/sphinx/ext/imgmath.py
+++ b/sphinx/ext/imgmath.py
@@ -14,7 +14,6 @@ import shutil
import subprocess
import sys
import tempfile
-from hashlib import sha1
from os import path
from subprocess import CalledProcessError, PIPE
from typing import Any, Dict, List, Tuple
@@ -29,7 +28,7 @@ from sphinx.builders import Builder
from sphinx.config import Config
from sphinx.errors import SphinxError
from sphinx.locale import _, __
-from sphinx.util import logging
+from sphinx.util import logging, sha1
from sphinx.util.math import get_node_equation_number, wrap_displaymath
from sphinx.util.osutil import ensuredir
from sphinx.util.png import read_png_depth, write_png_depth
diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py
index db2a15b14..7b2383fca 100644
--- a/sphinx/ext/inheritance_diagram.py
+++ b/sphinx/ext/inheritance_diagram.py
@@ -38,7 +38,6 @@ r"""
import builtins
import inspect
import re
-from hashlib import md5
from importlib import import_module
from typing import Any, Dict, Iterable, List, Tuple
from typing import cast
@@ -55,6 +54,7 @@ from sphinx.ext.graphviz import (
graphviz, figure_wrapper,
render_dot_html, render_dot_latex, render_dot_texinfo
)
+from sphinx.util import md5
from sphinx.util.docutils import SphinxDirective
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator
diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py
index dc24a1993..a2eeb7891 100644
--- a/sphinx/ext/viewcode.py
+++ b/sphinx/ext/viewcode.py
@@ -131,8 +131,10 @@ def env_merge_info(app: Sphinx, env: BuildEnvironment, docnames: Iterable[str],
def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnode: Node
) -> Node:
- # resolve our "viewcode" reference nodes -- they need special treatment
- if node['reftype'] == 'viewcode':
+ if app.builder.format != 'html':
+ return None
+ elif node['reftype'] == 'viewcode':
+ # resolve our "viewcode" reference nodes -- they need special treatment
return make_refnode(app.builder, node['refdoc'], node['reftarget'],
node['refid'], contnode)
diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py
index 91adfef7c..385ca3566 100644
--- a/sphinx/locale/__init__.py
+++ b/sphinx/locale/__init__.py
@@ -17,7 +17,7 @@ from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
class _TranslationProxy(UserString):
"""
- Class for proxy strings from gettext translations. This is a helper for the
+ Class for proxy strings from gettext translations. This is a helper for the
lazy_* functions from this module.
The proxy implementation attempts to be as complete as possible, so that
@@ -109,7 +109,7 @@ translators = defaultdict(NullTranslations) # type: Dict[Tuple[str, str], NullT
def init(locale_dirs: List[str], language: str,
catalog: str = 'sphinx', namespace: str = 'general') -> Tuple[NullTranslations, bool]:
"""Look for message catalogs in `locale_dirs` and *ensure* that there is at
- least a NullTranslations catalog set in `translators`. If called multiple
+ least a NullTranslations catalog set in `translators`. If called multiple
times or if several ``.mo`` files are found, their contents are merged
together (thus making ``init`` reentrant).
"""
diff --git a/sphinx/locale/ar/LC_MESSAGES/sphinx.po b/sphinx/locale/ar/LC_MESSAGES/sphinx.po
index 7c5e68004..bd69d2aeb 100644
--- a/sphinx/locale/ar/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ar/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr "تشغيل Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/bg/LC_MESSAGES/sphinx.po b/sphinx/locale/bg/LC_MESSAGES/sphinx.po
index 0f59aac78..79329a57a 100644
--- a/sphinx/locale/bg/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/bg/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/bn/LC_MESSAGES/sphinx.po b/sphinx/locale/bn/LC_MESSAGES/sphinx.po
index c4c4fbc53..63aae6877 100644
--- a/sphinx/locale/bn/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/bn/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/ca/LC_MESSAGES/sphinx.po b/sphinx/locale/ca/LC_MESSAGES/sphinx.po
index 08d882a09..6a8e317b1 100644
--- a/sphinx/locale/ca/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ca/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/cak/LC_MESSAGES/sphinx.po b/sphinx/locale/cak/LC_MESSAGES/sphinx.po
index 0fb5d1b93..b729d5f1f 100644
--- a/sphinx/locale/cak/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/cak/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr "Rusachoj kamulunem:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr "Ruch'ab'äl samaj"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.po b/sphinx/locale/cs/LC_MESSAGES/sphinx.po
index 1f6ec0753..8952713e1 100644
--- a/sphinx/locale/cs/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/cs/LC_MESSAGES/sphinx.po
@@ -42,7 +42,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1132,7 +1132,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1169,7 +1169,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1456,7 +1456,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1485,7 +1485,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/cy/LC_MESSAGES/sphinx.po b/sphinx/locale/cy/LC_MESSAGES/sphinx.po
index 6830334d8..12f2aecd2 100644
--- a/sphinx/locale/cy/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/cy/LC_MESSAGES/sphinx.po
@@ -42,7 +42,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1132,7 +1132,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1169,7 +1169,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1456,7 +1456,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1485,7 +1485,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/da/LC_MESSAGES/sphinx.po b/sphinx/locale/da/LC_MESSAGES/sphinx.po
index 1948fa632..317b832d2 100644
--- a/sphinx/locale/da/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/da/LC_MESSAGES/sphinx.po
@@ -43,7 +43,7 @@ msgstr "Kører Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1133,7 +1133,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1170,7 +1170,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1457,7 +1457,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1486,7 +1486,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/de/LC_MESSAGES/sphinx.po b/sphinx/locale/de/LC_MESSAGES/sphinx.po
index da1d031bd..8d5cd4e43 100644
--- a/sphinx/locale/de/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/de/LC_MESSAGES/sphinx.po
@@ -44,7 +44,7 @@ msgstr "Sphinx v%s in Verwendung"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1134,7 +1134,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1171,7 +1171,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1458,7 +1458,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1487,7 +1487,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/el/LC_MESSAGES/sphinx.mo b/sphinx/locale/el/LC_MESSAGES/sphinx.mo
index e1d1d4a21..d40fcac72 100644
Binary files a/sphinx/locale/el/LC_MESSAGES/sphinx.mo and b/sphinx/locale/el/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/el/LC_MESSAGES/sphinx.po b/sphinx/locale/el/LC_MESSAGES/sphinx.po
index 7555009b1..54eb341ec 100644
--- a/sphinx/locale/el/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/el/LC_MESSAGES/sphinx.po
@@ -42,7 +42,7 @@ msgstr "Εκτέλεση Sphinx έκδοση %s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1132,7 +1132,7 @@ msgstr "Σφάλμα αναδρομής:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "Αυτό μπορεί να συμβεί με πολύ μεγάλα ή βαθιά εμφωλιασμένα αρχεία πηγής. Μπορείτε προσεκτικά να αυξήσετε την προεπιλεγμένη τιμή αναδρομικότητας Python στο conf.py με π.χ.:"
@@ -1169,7 +1169,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1456,7 +1456,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1485,7 +1485,7 @@ msgstr "Γλώσσα έργου"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
@@ -2447,7 +2447,7 @@ msgstr "τοποθέτηση βιβλιογραφίας δομοστοιχείο
msgid ""
"interpret module paths according to PEP-0420 implicit namespaces "
"specification"
-msgstr "ερμηνεία μονοπατιών δομοστοιχείων σύμφωνα με την προδιαγραφή POP-0420 αυτονόητων namespaces"
+msgstr "ερμηνεία μονοπατιών δομοστοιχείων σύμφωνα με την προδιαγραφή POP-0420 αυτονόητων namespaces"
#: sphinx/ext/apidoc.py:411
msgid "file suffix (default: rst)"
diff --git a/sphinx/locale/eo/LC_MESSAGES/sphinx.po b/sphinx/locale/eo/LC_MESSAGES/sphinx.po
index 32bc8114a..6c94360c6 100644
--- a/sphinx/locale/eo/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/eo/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/es/LC_MESSAGES/sphinx.mo b/sphinx/locale/es/LC_MESSAGES/sphinx.mo
index 05ac10c87..bd4be1841 100644
Binary files a/sphinx/locale/es/LC_MESSAGES/sphinx.mo and b/sphinx/locale/es/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/es/LC_MESSAGES/sphinx.po b/sphinx/locale/es/LC_MESSAGES/sphinx.po
index 5153023e5..be149e88a 100644
--- a/sphinx/locale/es/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/es/LC_MESSAGES/sphinx.po
@@ -47,7 +47,7 @@ msgstr "Ejecutando Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr "Por razones de seguridad, el modo paralelo está deshabilitado en macOS y python3.8 y superior. Para más detalles, lea https://github.com/sphinx-doc/sphinx/issues/6803"
@@ -154,7 +154,7 @@ msgid ""
"the %s extension does not declare if it is safe for parallel reading, "
"assuming it isn't - please ask the extension author to check and make it "
"explicit"
-msgstr "la extensión de %s no declara si es seguro para la lectura en paralelo, asumiendo que no es - consulte con el autor de la extensión para comprobar y hacer explícito"
+msgstr "la extensión de %s no declara si es seguro para la lectura en paralelo, asumiendo que no es - consulte con el autor de la extensión para comprobar y hacer explícito"
#: sphinx/application.py:1128
#, python-format
@@ -1137,7 +1137,7 @@ msgstr "Error de recursión:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "Esto puede suceder con archivos fuente muy grandes o profundamente anidados. Puede aumentar cuidadosamente el límite de recursión de Python predeterminado de 1000 en el archivo conf.py con, por ejemplo:"
@@ -1174,7 +1174,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1184,7 +1184,7 @@ msgid ""
"\n"
"By default, everything that is outdated is built. Output only for selected\n"
"files can be built by specifying individual filenames.\n"
-msgstr "\nGenerar documentación a partir de archivos fuente.\n\nsphinx-build genera documentación de los archivos en SOURCEDIR y la coloca\nen OUTPUTDIR. Busca el archivo 'conf.py' en SOURCEDIR para los ajustes de la \nconfiguración. La herramienta 'sphinx-quickstart' puede usarse para generar archivos de plantilla,\nincluyendo el archivo 'conf.py'\n\nsphinx-build puede crear documentación en diferentes formatos. Un formato es\nseleccionado especificando el nombre del constructor en la línea de comando; por defecto es\nHTML. Los constructores también pueden realizar otras tareas relacionadas con la\ndocumentación.\n\nPor defecto, todo lo que está desactualizado está construido. Salida solo para los archivos\nseleccionados se pueden construir especificando nombres de archivo individuales.\n"
+msgstr "\nGenerar documentación a partir de archivos fuente.\n\nsphinx-build genera documentación de los archivos en SOURCEDIR y la coloca\nen OUTPUTDIR. Busca el archivo 'conf.py' en SOURCEDIR para los ajustes de la \nconfiguración. La herramienta 'sphinx-quickstart' puede usarse para generar archivos de plantilla,\nincluyendo el archivo 'conf.py'\n\nsphinx-build puede crear documentación en diferentes formatos. Un formato es\nseleccionado especificando el nombre del constructor en la línea de comando; por defecto es\nHTML. Los constructores también pueden realizar otras tareas relacionadas con la\ndocumentación.\n\nPor defecto, todo lo que está desactualizado está construido. Salida solo para los archivos\nseleccionados se pueden construir especificando nombres de archivo individuales.\n"
#: sphinx/cmd/build.py:122
msgid "path to documentation source files"
@@ -1461,7 +1461,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr "Sphinx tiene la noción de una \"version\" y un \"release\" para el\nsoftware. Cada versión puede tener múltiples versiones. Por ejemplo, para\nPython la versión es algo así como 2.5 o 3.0, mientras que el lanzamiento es\nalgo así como 2.5.1 o 3.0a1. Si no necesita esta estructura dual,\nsolo establezca ambos en el mismo valor."
@@ -1490,7 +1490,7 @@ msgstr "Lenguaje del proyecto"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr "El sufijo del nombre de archivo para los archivos de origen. Comúnmente, esto es \".txt\"\no \".rst\". Solo los archivos con este sufijo se consideran documentos."
#: sphinx/cmd/quickstart.py:300
@@ -2617,7 +2617,7 @@ msgstr "[gráfica]"
#: sphinx/ext/imgconverter.py:41 sphinx/ext/imgconverter.py:65
#, python-format
msgid "convert command %r cannot be run, check the image_converter setting"
-msgstr "el comando convert %r no puede ejecutar, compruebe el valor de configuración image_converter"
+msgstr "el comando convert %r no puede ejecutar, compruebe el valor de configuración image_converter"
#: sphinx/ext/imgconverter.py:46 sphinx/ext/imgconverter.py:70
#, python-format
diff --git a/sphinx/locale/et/LC_MESSAGES/sphinx.mo b/sphinx/locale/et/LC_MESSAGES/sphinx.mo
index 0a01f5047..b5d83dbf8 100644
Binary files a/sphinx/locale/et/LC_MESSAGES/sphinx.mo and b/sphinx/locale/et/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/et/LC_MESSAGES/sphinx.po b/sphinx/locale/et/LC_MESSAGES/sphinx.po
index def0d2e34..a87de4d11 100644
--- a/sphinx/locale/et/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/et/LC_MESSAGES/sphinx.po
@@ -44,7 +44,7 @@ msgstr "Sphinx v%s käitamine"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1134,7 +1134,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1171,7 +1171,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1458,7 +1458,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1487,7 +1487,7 @@ msgstr "Projekti keel"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/eu/LC_MESSAGES/sphinx.po b/sphinx/locale/eu/LC_MESSAGES/sphinx.po
index a72468c9a..80dbae5a3 100644
--- a/sphinx/locale/eu/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/eu/LC_MESSAGES/sphinx.po
@@ -42,7 +42,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1132,7 +1132,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1169,7 +1169,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1456,7 +1456,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1485,7 +1485,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/fa/LC_MESSAGES/sphinx.po b/sphinx/locale/fa/LC_MESSAGES/sphinx.po
index 6f1c35df2..ddca8112c 100644
--- a/sphinx/locale/fa/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/fa/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/fi/LC_MESSAGES/sphinx.po b/sphinx/locale/fi/LC_MESSAGES/sphinx.po
index 3d004d801..19233894d 100644
--- a/sphinx/locale/fi/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/fi/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/fr/LC_MESSAGES/sphinx.mo b/sphinx/locale/fr/LC_MESSAGES/sphinx.mo
index 848d762c8..25bdd0d82 100644
Binary files a/sphinx/locale/fr/LC_MESSAGES/sphinx.mo and b/sphinx/locale/fr/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/fr/LC_MESSAGES/sphinx.po b/sphinx/locale/fr/LC_MESSAGES/sphinx.po
index 2252e8a19..b01d956c0 100644
--- a/sphinx/locale/fr/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/fr/LC_MESSAGES/sphinx.po
@@ -61,7 +61,7 @@ msgstr "Sphinx v%s en cours d'exécution"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -321,7 +321,7 @@ msgstr "Nom d'évènement inconnu : %s"
msgid ""
"The %s extension is required by needs_extensions settings, but it is not "
"loaded."
-msgstr "L'extension %s est exigée par le paramètre needs_extensions, mais n'est pas chargée."
+msgstr "L'extension %s est exigée par le paramètre needs_extensions, mais n'est pas chargée."
#: sphinx/extension.py:56
#, python-format
@@ -1151,7 +1151,7 @@ msgstr "Erreur de récursion :"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "Cela peut se produire avec des fichiers sources très volumineux ou profondément imbriqués. Vous pouvez soigneusement augmenter la limite de récursivité par défaut de Python de 1000 dans conf.py avec p. ex. :"
@@ -1188,7 +1188,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1475,7 +1475,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1504,7 +1504,7 @@ msgstr "Langue du projet"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
@@ -2611,7 +2611,7 @@ msgstr "dot a terminé avec une erreur :\n[stderr]\n%r\n[stdout]\n%r"
#: sphinx/ext/graphviz.py:269
#, python-format
msgid "graphviz_output_format must be one of 'png', 'svg', but is %r"
-msgstr "graphviz_output_format doit être « png » ou « svg », mais est %r"
+msgstr "graphviz_output_format doit être « png » ou « svg », mais est %r"
#: sphinx/ext/graphviz.py:273 sphinx/ext/graphviz.py:324
#: sphinx/ext/graphviz.py:361
diff --git a/sphinx/locale/he/LC_MESSAGES/sphinx.po b/sphinx/locale/he/LC_MESSAGES/sphinx.po
index 159c60070..7332af27f 100644
--- a/sphinx/locale/he/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/he/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/hi/LC_MESSAGES/sphinx.mo b/sphinx/locale/hi/LC_MESSAGES/sphinx.mo
index 56881c96f..d93d5cf7d 100644
Binary files a/sphinx/locale/hi/LC_MESSAGES/sphinx.mo and b/sphinx/locale/hi/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/hi/LC_MESSAGES/sphinx.po b/sphinx/locale/hi/LC_MESSAGES/sphinx.po
index 6409fb8a6..7fd40316b 100644
--- a/sphinx/locale/hi/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/hi/LC_MESSAGES/sphinx.po
@@ -44,7 +44,7 @@ msgstr "स्फिंक्स %s संस्करण चल रहा ह
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr "सुरक्षा कारण वर्ष macOS तथा python 3.8 और अधिक, के साथ समानांतर कार्य शैली कि सुविधा उपलब्ध नहीं हैं | अधिक जानकारी के लिए, कृपया \"https://github.com/sphinx-doc/sphinx/issues/6803\" पढ़े |"
@@ -1134,7 +1134,7 @@ msgstr "पुनरावर्तन त्रुटि:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "ऐसा बहुत बड़ी अथवा गहरे स्तर तक गई स्रोत फाइलों से संभव है. आप स्वतः मानक पाइथन पुनरावर्तन सीमा 1000 को conf.py में बाधा सकते हैं. जैसे कि:"
@@ -1171,7 +1171,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1458,7 +1458,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr "स्फिंक्स सॉफ्टवेयर के लिए संस्करण और आवृत्ति को मान्यता देता है.\nहर संस्करण की कई आवृत्तियाँ हो सकती हैं. उदाहरण के लिए,\nपाइथन संस्करण 2.5 अथवा 3.0 आदि हैं, और आवृत्ति\n2.5.1 अथवा 3.0a1 आदि हैं. यदि आपको इसे दो स्तर पर रखना नहीं चाहिए\nतो दोनों मान एक ही रख दें."
@@ -1487,7 +1487,7 @@ msgstr "परियोजना की भाषा"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
@@ -2789,7 +2789,7 @@ msgstr "स्वतः-प्रभाग %s के लिए हस्ता
msgid ""
"__all__ should be a list of strings, not %r (in module %s) -- ignoring "
"__all__"
-msgstr "__all__ अंतिम अक्षरमाला होनी चाहिए, न कि %r (%s प्रभाग में) -- __all__ की उपेक्षा की जाएगी"
+msgstr "__all__ अंतिम अक्षरमाला होनी चाहिए, न कि %r (%s प्रभाग में) -- __all__ की उपेक्षा की जाएगी"
#: sphinx/ext/autodoc/__init__.py:852
#, python-format
diff --git a/sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po b/sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po
index 11a951750..78f66e29e 100644
--- a/sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/hr/LC_MESSAGES/sphinx.mo b/sphinx/locale/hr/LC_MESSAGES/sphinx.mo
index 999b8cada..777096ba6 100644
Binary files a/sphinx/locale/hr/LC_MESSAGES/sphinx.mo and b/sphinx/locale/hr/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/hr/LC_MESSAGES/sphinx.po b/sphinx/locale/hr/LC_MESSAGES/sphinx.po
index 81e7e9bf3..c1f1d4be0 100644
--- a/sphinx/locale/hr/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/hr/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr "Izrada pomoću Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -449,7 +449,7 @@ msgstr "%s proširenje traži Sphinx verzije v%s; stoga projekt ne može biti iz
msgid ""
"extension %r returned an unsupported object from its setup() function; it "
"should return None or a metadata dictionary"
-msgstr "proširenje %r vratio je nepodržan objekt iz setup() funkcije; rezultat treba biti None ili riječnik metapodataka"
+msgstr "proširenje %r vratio je nepodržan objekt iz setup() funkcije; rezultat treba biti None ili riječnik metapodataka"
#: sphinx/roles.py:221 sphinx/roles.py:271
#, python-format
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/hu/LC_MESSAGES/sphinx.po b/sphinx/locale/hu/LC_MESSAGES/sphinx.po
index e9e7a5291..fe58d1895 100644
--- a/sphinx/locale/hu/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/hu/LC_MESSAGES/sphinx.po
@@ -45,7 +45,7 @@ msgstr "Sphinx %s verzió futtatása"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1135,7 +1135,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1172,7 +1172,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1459,7 +1459,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1488,7 +1488,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/id/LC_MESSAGES/sphinx.mo b/sphinx/locale/id/LC_MESSAGES/sphinx.mo
index cdc79da48..01095a9db 100644
Binary files a/sphinx/locale/id/LC_MESSAGES/sphinx.mo and b/sphinx/locale/id/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/id/LC_MESSAGES/sphinx.po b/sphinx/locale/id/LC_MESSAGES/sphinx.po
index ce2847c33..d11a59d35 100644
--- a/sphinx/locale/id/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/id/LC_MESSAGES/sphinx.po
@@ -45,9 +45,9 @@ msgstr "Menjalankan Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
-msgstr "Untuk alasan keamanan, mode paralel dinonaktifkan di macOS dan python3.8 dan di atasnya. Untuk detail lebih lanjut, silakan baca https://github.com/sphinx-doc/sphinx/issues/6803"
+msgstr "Untuk alasan keamanan, mode paralel dinonaktifkan di macOS dan python3.8 dan di atasnya. Untuk detail lebih lanjut, silakan baca https://github.com/sphinx-doc/sphinx/issues/6803"
#: sphinx/application.py:226
#, python-format
@@ -1135,7 +1135,7 @@ msgstr "Kesalahan rekursi:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "Hal ini dapat terjadi dengan berkas sumber yang besar atau sangat dalam bertingkat. Anda dapat secara hati-hati meningkatkan batas standar recursi Python dari 1000 di conf.py contohnya:"
@@ -1172,7 +1172,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1182,7 +1182,7 @@ msgid ""
"\n"
"By default, everything that is outdated is built. Output only for selected\n"
"files can be built by specifying individual filenames.\n"
-msgstr "\nMenghasilkan dokumentasi ari berkas sumber.\n\nsphinx-build menghasilkan dokumentasi dari berkas-berkas di SOURCEDIR dan menyimpannya\ndi OUTPUTDIR. Program tersebut mencari berkas 'conf.py' di SOURCEDIR untuk pengaturan\nkonfigurasinya. Alat 'sphinx-quickstart' dapat digunakan untuk menghasilkan berkas templat,\ntermasuk 'conf.py'\n\nsphinx-build dapat membuat dokumentasi dalam beragam format. Sebuah format\ndipilih berdasarkan nama builder pada command line; standarnya\nHTML. Builders pun dapat menjalankan tugas lainnya berhubungan dengan pemrosesan\ndocumentasi.\n\nSecara umum, semua yang usang akan dibuat. Output hanya untuk berkas\npilihan dapat dibuat dengan menentukan berkas satuan.\n"
+msgstr "\nMenghasilkan dokumentasi ari berkas sumber.\n\nsphinx-build menghasilkan dokumentasi dari berkas-berkas di SOURCEDIR dan menyimpannya\ndi OUTPUTDIR. Program tersebut mencari berkas 'conf.py' di SOURCEDIR untuk pengaturan\nkonfigurasinya. Alat 'sphinx-quickstart' dapat digunakan untuk menghasilkan berkas templat,\ntermasuk 'conf.py'\n\nsphinx-build dapat membuat dokumentasi dalam beragam format. Sebuah format\ndipilih berdasarkan nama builder pada command line; standarnya\nHTML. Builders pun dapat menjalankan tugas lainnya berhubungan dengan pemrosesan\ndocumentasi.\n\nSecara umum, semua yang usang akan dibuat. Output hanya untuk berkas\npilihan dapat dibuat dengan menentukan berkas satuan.\n"
#: sphinx/cmd/build.py:122
msgid "path to documentation source files"
@@ -1459,7 +1459,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1488,7 +1488,7 @@ msgstr "Bahasa proyek"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/it/LC_MESSAGES/sphinx.po b/sphinx/locale/it/LC_MESSAGES/sphinx.po
index bf9e5c33b..9c871d0d2 100644
--- a/sphinx/locale/it/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/it/LC_MESSAGES/sphinx.po
@@ -45,7 +45,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1135,7 +1135,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1172,7 +1172,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1459,7 +1459,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1488,7 +1488,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.mo b/sphinx/locale/ja/LC_MESSAGES/sphinx.mo
index 58ac45caa..6d27b0775 100644
Binary files a/sphinx/locale/ja/LC_MESSAGES/sphinx.mo and b/sphinx/locale/ja/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.po b/sphinx/locale/ja/LC_MESSAGES/sphinx.po
index bec0732d3..d9299e58c 100644
--- a/sphinx/locale/ja/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ja/LC_MESSAGES/sphinx.po
@@ -55,7 +55,7 @@ msgstr "Sphinx v%s を実行中"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr "セキュリティ上の理由から、macOSおよびpython3.8以降では並列モードが無効になっています。 詳細については https://github.com/sphinx-doc/sphinx/issues/6803 をご覧ください。"
@@ -1145,7 +1145,7 @@ msgstr "再起呼び出しエラー:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "この例外エラーは、非常に大きな、または深くネストされたソースファイルで発生する可能性があります。再帰処理の呼び出しの上限値 1000 は conf.py で変更できますが、慎重に行ってください。"
@@ -1182,7 +1182,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1469,7 +1469,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr "Sphinx には、ソフトウェアに対して \"バージョン\" と \"リリース\" という概念が\nあります。各バージョンは複数のリリースを持つことができます。\n例えば、Python だとバージョンが 2.5 や 3.0 のように分かれているように、\nリリースも 2.5.1 や 3.0a1 のように分けて持つことができます。もしこのような多重構成が必要ない場合は、\n両方を同じ値に設定するだけです。"
@@ -1498,7 +1498,7 @@ msgstr "プロジェクトの言語"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr "拡張子の名前はソースファイルに使います。\n通常は \".txt\" または \".rst\" です。これらの拡張子を持つファイルのみがドキュメントと見なされます。"
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/ko/LC_MESSAGES/sphinx.mo b/sphinx/locale/ko/LC_MESSAGES/sphinx.mo
index a9573bea1..baf3b48ca 100644
Binary files a/sphinx/locale/ko/LC_MESSAGES/sphinx.mo and b/sphinx/locale/ko/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/ko/LC_MESSAGES/sphinx.po b/sphinx/locale/ko/LC_MESSAGES/sphinx.po
index 93c285e9b..bf3bbe78e 100644
--- a/sphinx/locale/ko/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ko/LC_MESSAGES/sphinx.po
@@ -42,7 +42,7 @@ msgstr "Sphinx 버전 %s 실행 중"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1132,7 +1132,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1169,7 +1169,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1456,7 +1456,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1485,7 +1485,7 @@ msgstr "프로젝트 언어"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/lt/LC_MESSAGES/sphinx.po b/sphinx/locale/lt/LC_MESSAGES/sphinx.po
index 75f4f340f..fbf5b0a1d 100644
--- a/sphinx/locale/lt/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/lt/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/lv/LC_MESSAGES/sphinx.po b/sphinx/locale/lv/LC_MESSAGES/sphinx.po
index 83edbcbfc..a3968756d 100644
--- a/sphinx/locale/lv/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/lv/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/mk/LC_MESSAGES/sphinx.po b/sphinx/locale/mk/LC_MESSAGES/sphinx.po
index 7ca7371a7..5543d45fd 100644
--- a/sphinx/locale/mk/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/mk/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po
index d91029b1a..b061b0361 100644
--- a/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/ne/LC_MESSAGES/sphinx.po b/sphinx/locale/ne/LC_MESSAGES/sphinx.po
index 41c06cd81..46590097d 100644
--- a/sphinx/locale/ne/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ne/LC_MESSAGES/sphinx.po
@@ -42,7 +42,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1132,7 +1132,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1169,7 +1169,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1456,7 +1456,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1485,7 +1485,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/nl/LC_MESSAGES/sphinx.po b/sphinx/locale/nl/LC_MESSAGES/sphinx.po
index fab7b5cbf..d5eb16c6f 100644
--- a/sphinx/locale/nl/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/nl/LC_MESSAGES/sphinx.po
@@ -46,7 +46,7 @@ msgstr "Sphinx v%s start op"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1136,7 +1136,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1173,7 +1173,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1460,7 +1460,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1489,7 +1489,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/pl/LC_MESSAGES/sphinx.po b/sphinx/locale/pl/LC_MESSAGES/sphinx.po
index 97762625f..ac8488a45 100644
--- a/sphinx/locale/pl/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/pl/LC_MESSAGES/sphinx.po
@@ -44,7 +44,7 @@ msgstr "Uruchamianie Sphinksa v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1134,7 +1134,7 @@ msgstr "Błąd rekursji:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1171,7 +1171,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1458,7 +1458,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1487,7 +1487,7 @@ msgstr "Język projektu"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/pt/LC_MESSAGES/sphinx.po b/sphinx/locale/pt/LC_MESSAGES/sphinx.po
index f8d4c9538..4b0c30cb7 100644
--- a/sphinx/locale/pt/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/pt/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo
index 2dbc5028b..7cfa989d3 100644
Binary files a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo and b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po
index eaed82dc2..dba58f93e 100644
--- a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po
@@ -46,7 +46,7 @@ msgstr "Executando Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr "Por motivos de segurança, o modo paralelo está desativado no macOS e python3.8 e superior. Para mais detalhes, leia https://github.com/sphinx-doc/sphinx/issues/6803"
@@ -1136,7 +1136,7 @@ msgstr "Erro de recursão:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "Isso pode acontecer com arquivos-fonte muito grandes ou profundamente aninhados. Você pode aumentar cuidadosamente o limite de recursão padrão do Python de 1000 em conf.py, p.ex.:"
@@ -1173,7 +1173,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1460,7 +1460,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr "Sphinx tem a noção de uma \"versão\" e uma \"lançamento\" para o software.\nCada versão pode ter vários lançamentos. Por exemplo, para Python, a\nversão é algo como 2.5 ou 3.0, enquanto o lançamento é algo como 2.5.1\nou 3.0a1. Se você não precisar dessa estrutura dupla, basta definir as\nduas para o mesmo valor."
@@ -1489,7 +1489,7 @@ msgstr "Idioma do projeto"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr "O sufixo do nome do arquivo para os arquivos-fonte. Geralmente ele é\n\".txt\" ou \".rst\". Somente arquivos com esse sufixo são considerados\ndocumentos."
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po b/sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po
index 397e8eba6..7d219561a 100644
--- a/sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po
@@ -42,7 +42,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1132,7 +1132,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1169,7 +1169,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1456,7 +1456,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1485,7 +1485,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/ro/LC_MESSAGES/sphinx.po b/sphinx/locale/ro/LC_MESSAGES/sphinx.po
index 01d623736..6a4591643 100644
--- a/sphinx/locale/ro/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ro/LC_MESSAGES/sphinx.po
@@ -42,7 +42,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1132,7 +1132,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1169,7 +1169,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1456,7 +1456,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1485,7 +1485,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/ru/LC_MESSAGES/sphinx.po b/sphinx/locale/ru/LC_MESSAGES/sphinx.po
index 525962670..e69207f4e 100644
--- a/sphinx/locale/ru/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ru/LC_MESSAGES/sphinx.po
@@ -46,7 +46,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1136,7 +1136,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1173,7 +1173,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1460,7 +1460,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1489,7 +1489,7 @@ msgstr "Язык проекта"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/si/LC_MESSAGES/sphinx.po b/sphinx/locale/si/LC_MESSAGES/sphinx.po
index 7f74034fd..a257711c5 100644
--- a/sphinx/locale/si/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/si/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/sk/LC_MESSAGES/sphinx.po b/sphinx/locale/sk/LC_MESSAGES/sphinx.po
index 4e64c80a8..7d4bb2118 100644
--- a/sphinx/locale/sk/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/sk/LC_MESSAGES/sphinx.po
@@ -43,7 +43,7 @@ msgstr "Spúšťanie Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1133,7 +1133,7 @@ msgstr "Chyba rekurzie:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1170,7 +1170,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1457,7 +1457,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1486,7 +1486,7 @@ msgstr "Jazyk projektu"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/sl/LC_MESSAGES/sphinx.po b/sphinx/locale/sl/LC_MESSAGES/sphinx.po
index 3989e7f3e..80dde8bd0 100644
--- a/sphinx/locale/sl/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/sl/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/sphinx.pot b/sphinx/locale/sphinx.pot
index 39ed7ccca..4c47a9fb9 100644
--- a/sphinx/locale/sphinx.pot
+++ b/sphinx/locale/sphinx.pot
@@ -1136,7 +1136,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1174,7 +1174,7 @@ msgid ""
"sphinx-build generates documentation from the files in SOURCEDIR and "
"places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template "
+"settings. The 'sphinx-quickstart' tool may be used to generate template "
"files,\n"
"including 'conf.py'\n"
"\n"
@@ -1467,7 +1467,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
diff --git a/sphinx/locale/sq/LC_MESSAGES/sphinx.mo b/sphinx/locale/sq/LC_MESSAGES/sphinx.mo
index 5c0fa25ac..a3d4b12a9 100644
Binary files a/sphinx/locale/sq/LC_MESSAGES/sphinx.mo and b/sphinx/locale/sq/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/sq/LC_MESSAGES/sphinx.po b/sphinx/locale/sq/LC_MESSAGES/sphinx.po
index 8d432f7ba..bf21f378d 100644
--- a/sphinx/locale/sq/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/sq/LC_MESSAGES/sphinx.po
@@ -40,9 +40,9 @@ msgstr "Po xhirohet Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
-msgstr "Për arsye sigurie, mënyra paralele është e çaktivizuar në macOS dhe python3.8 dhe më sipër. Për më tepër hollësi, ju lutemi, lexoni https://github.com/sphinx-doc/sphinx/issues/6803"
+msgstr "Për arsye sigurie, mënyra paralele është e çaktivizuar në macOS dhe python3.8 dhe më sipër. Për më tepër hollësi, ju lutemi, lexoni https://github.com/sphinx-doc/sphinx/issues/6803"
#: sphinx/application.py:226
#, python-format
@@ -1130,10 +1130,10 @@ msgstr "Gabim përsëritje:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
-msgstr "Kjo mund të ndodhë me kartela burim shumë të mëdha ose të futura thellë brenda njëra-tjetrës. Mund të rrisni me kujdes kufirin parazgjedhje për ripërsëritje Python prej 1000 te conf.py me p.sh.:"
+msgstr "Kjo mund të ndodhë me kartela burim shumë të mëdha ose të futura thellë brenda njëra-tjetrës. Mund të rrisni me kujdes kufirin parazgjedhje për ripërsëritje Python prej 1000 te conf.py me p.sh.:"
#: sphinx/cmd/build.py:67
msgid "Exception occurred:"
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,9 +1454,9 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
-msgstr "Sphinx-i përdor nocionet e një \"versioni\" dhe një \"hedhjeje në qarkullim\" për\nsoftware-in. Çdo version mund të ketë hedhje të shumta në qarkullim. Bie\nfjala, për Python-in versionet ngjajnë me 2.5 ose 3.0, teksa hedhja në\nqarkullim ngjan me 2.5.1 ose 3.0a1. Nëse s’ju hyn në punë kjo strukturë\nduale, thjesht vëruni të dyjave të njëjtën vlerë."
+msgstr "Sphinx-i përdor nocionet e një \"versioni\" dhe një \"hedhjeje në qarkullim\" për\nsoftware-in. Çdo version mund të ketë hedhje të shumta në qarkullim. Bie\nfjala, për Python-in versionet ngjajnë me 2.5 ose 3.0, teksa hedhja në\nqarkullim ngjan me 2.5.1 ose 3.0a1. Nëse s’ju hyn në punë kjo strukturë\nduale, thjesht vëruni të dyjave të njëjtën vlerë."
#: sphinx/cmd/quickstart.py:280
msgid "Project version"
@@ -1483,8 +1483,8 @@ msgstr "Gjuhë projekti"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
-msgstr "Prapashtesa e emrave të kartelave për kartela burim. Zakonisht, kjo\nështë ose \".txt\", ose \".rst\". Vetëm kartelat me këtë prapashtesë\nmerren si dokumente."
+"or \".rst\". Only files with this suffix are considered documents."
+msgstr "Prapashtesa e emrave të kartelave për kartela burim. Zakonisht, kjo\nështë ose \".txt\", ose \".rst\". Vetëm kartelat me këtë prapashtesë\nmerren si dokumente."
#: sphinx/cmd/quickstart.py:300
msgid "Source file suffix"
diff --git a/sphinx/locale/sr/LC_MESSAGES/sphinx.po b/sphinx/locale/sr/LC_MESSAGES/sphinx.po
index 0aa8cef91..1df55881c 100644
--- a/sphinx/locale/sr/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/sr/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr "Покрећем Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po b/sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po
index 4b92f65f2..a7b82e633 100644
--- a/sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po b/sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po
index 1def1329a..dad4f3542 100644
--- a/sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/sv/LC_MESSAGES/sphinx.po b/sphinx/locale/sv/LC_MESSAGES/sphinx.po
index 32a761254..bbf5e5ff1 100644
--- a/sphinx/locale/sv/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/sv/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/ta/LC_MESSAGES/sphinx.po b/sphinx/locale/ta/LC_MESSAGES/sphinx.po
index 1cab45ce5..bb1c77f28 100644
--- a/sphinx/locale/ta/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ta/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/te/LC_MESSAGES/sphinx.po b/sphinx/locale/te/LC_MESSAGES/sphinx.po
index e96c8859c..c6c3c45f1 100644
--- a/sphinx/locale/te/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/te/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/tr/LC_MESSAGES/sphinx.mo b/sphinx/locale/tr/LC_MESSAGES/sphinx.mo
index 1147c43f3..f8d5ed28d 100644
Binary files a/sphinx/locale/tr/LC_MESSAGES/sphinx.mo and b/sphinx/locale/tr/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/tr/LC_MESSAGES/sphinx.po b/sphinx/locale/tr/LC_MESSAGES/sphinx.po
index 2acf25505..996d6e67c 100644
--- a/sphinx/locale/tr/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/tr/LC_MESSAGES/sphinx.po
@@ -43,7 +43,7 @@ msgstr "Sphinx s%s çalışıyor"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr "Güvenlik nedeni ile macOS ve python 3.8 ve üzerinde paralel kip etkisizleştirildi. Daha fazla bilgi için lütfen https://github.com/sphinx-doc/sphinx/issues/6803 adresindekileri okuyun"
@@ -1133,7 +1133,7 @@ msgstr "Tekrarlama hatası:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "Bu, çok büyük veya çok fazla iç içe girmiş kaynak dosyaları ile olabilir. Varsayılan Python tekrarlama sınırını conf.py dosyasında şu örnekle 1000'e kadar dikkatlice artırabilirsiniz:"
@@ -1170,7 +1170,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1457,7 +1457,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr "Sphinx, yazılım için bir \"sürüm\" ve bir \"yayım\" kavramına sahiptir.\nHer sürümün birden çok yayımı olabilir. Örneğin, Python için\nsürüm 2.5 veya 3.0 gibi bir şeydir, yayım ise 2.5.1 veya 3.0a1 gibi\nbir şeydir. Eğer bu çift yapıya ihtiyacınız yoksa, her ikisini de aynı\ndeğere ayarlayın."
@@ -1486,7 +1486,7 @@ msgstr "Proje dili"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr "Kaynak dosyalar için dosya adı soneki. Genellikle, bu ya \".txt\" ya da\n\".rst\"dir. Sadece bu soneki içeren dosyalar belgeler olarak kabul edilir."
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po b/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po
index 050a1a5af..2b43faa32 100644
--- a/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/ur/LC_MESSAGES/sphinx.po b/sphinx/locale/ur/LC_MESSAGES/sphinx.po
index b4a3e3ba3..c674b9283 100644
--- a/sphinx/locale/ur/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/ur/LC_MESSAGES/sphinx.po
@@ -40,7 +40,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1130,7 +1130,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1167,7 +1167,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1454,7 +1454,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1483,7 +1483,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/vi/LC_MESSAGES/sphinx.po b/sphinx/locale/vi/LC_MESSAGES/sphinx.po
index 0e2821a5e..83b579ea4 100644
--- a/sphinx/locale/vi/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/vi/LC_MESSAGES/sphinx.po
@@ -41,7 +41,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1131,7 +1131,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1168,7 +1168,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1455,7 +1455,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1484,7 +1484,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo
index 1a6476dcd..33222138a 100644
Binary files a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo and b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo differ
diff --git a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po
index 22fd15f9b..47cb76210 100644
--- a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po
@@ -52,7 +52,7 @@ msgstr "正在运行 Sphinx v%s"
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -495,7 +495,7 @@ msgstr "不支持的主题选项 %r"
#: sphinx/theming.py:228
#, python-format
msgid "file %r on theme path is not a valid zipfile or contains no theme"
-msgstr "主题路径指定的文件 %r 是一个无效的或不包含主题的 zip 文件"
+msgstr "主题路径指定的文件 %r 是一个无效的或不包含主题的 zip 文件"
#: sphinx/theming.py:243
msgid ""
@@ -1142,7 +1142,7 @@ msgstr "递归错误:"
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr "在源文件过大或嵌套层数过深时会出现此错误。你可以在 conf.py 中增大默认的Python 递归 1000 层限制,像这样:"
@@ -1179,7 +1179,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1466,7 +1466,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1495,7 +1495,7 @@ msgstr "项目语种"
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po
index fc603b6db..67b4d2b81 100644
--- a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po
+++ b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po
@@ -46,7 +46,7 @@ msgstr ""
#: sphinx/application.py:202
msgid ""
"For security reason, parallel mode is disabled on macOS and python3.8 and "
-"above. For more details, please read https://github.com/sphinx-"
+"above. For more details, please read https://github.com/sphinx-"
"doc/sphinx/issues/6803"
msgstr ""
@@ -1136,7 +1136,7 @@ msgstr ""
#: sphinx/cmd/build.py:62
msgid ""
-"This can happen with very large or deeply nested source files. You can "
+"This can happen with very large or deeply nested source files. You can "
"carefully increase the default Python recursion limit of 1000 in conf.py "
"with e.g.:"
msgstr ""
@@ -1173,7 +1173,7 @@ msgid ""
"\n"
"sphinx-build generates documentation from the files in SOURCEDIR and places it\n"
"in OUTPUTDIR. It looks for 'conf.py' in SOURCEDIR for the configuration\n"
-"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
+"settings. The 'sphinx-quickstart' tool may be used to generate template files,\n"
"including 'conf.py'\n"
"\n"
"sphinx-build can create documentation in different formats. A format is\n"
@@ -1460,7 +1460,7 @@ msgid ""
"Sphinx has the notion of a \"version\" and a \"release\" for the\n"
"software. Each version can have multiple releases. For example, for\n"
"Python the version is something like 2.5 or 3.0, while the release is\n"
-"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
+"something like 2.5.1 or 3.0a1. If you don't need this dual structure,\n"
"just set both to the same value."
msgstr ""
@@ -1489,7 +1489,7 @@ msgstr ""
#: sphinx/cmd/quickstart.py:298
msgid ""
"The file name suffix for source files. Commonly, this is either \".txt\"\n"
-"or \".rst\". Only files with this suffix are considered documents."
+"or \".rst\". Only files with this suffix are considered documents."
msgstr ""
#: sphinx/cmd/quickstart.py:300
diff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py
index 3f4717f45..0b403b61e 100644
--- a/sphinx/pycode/ast.py
+++ b/sphinx/pycode/ast.py
@@ -75,113 +75,142 @@ def unparse(node: Optional[ast.AST]) -> Optional[str]:
return None
elif isinstance(node, str):
return node
- elif node.__class__ in OPERATORS:
+ return _UnparseVisitor().visit(node)
+
+
+# a greatly cut-down version of `ast._Unparser`
+class _UnparseVisitor(ast.NodeVisitor):
+
+ def _visit_op(self, node: ast.AST) -> str:
return OPERATORS[node.__class__]
- elif isinstance(node, ast.arg):
+ for _op in OPERATORS:
+ locals()['visit_{}'.format(_op.__name__)] = _visit_op
+
+ def visit_arg(self, node: ast.arg) -> str:
if node.annotation:
- return "%s: %s" % (node.arg, unparse(node.annotation))
+ return "%s: %s" % (node.arg, self.visit(node.annotation))
else:
return node.arg
- elif isinstance(node, ast.arguments):
- return unparse_arguments(node)
- elif isinstance(node, ast.Attribute):
- return "%s.%s" % (unparse(node.value), node.attr)
- elif isinstance(node, ast.BinOp):
- return " ".join(unparse(e) for e in [node.left, node.op, node.right])
- elif isinstance(node, ast.BoolOp):
- op = " %s " % unparse(node.op)
- return op.join(unparse(e) for e in node.values)
- elif isinstance(node, ast.Bytes):
- return repr(node.s)
- elif isinstance(node, ast.Call):
- args = ([unparse(e) for e in node.args] +
- ["%s=%s" % (k.arg, unparse(k.value)) for k in node.keywords])
- return "%s(%s)" % (unparse(node.func), ", ".join(args))
- elif isinstance(node, ast.Dict):
- keys = (unparse(k) for k in node.keys)
- values = (unparse(v) for v in node.values)
+
+ def _visit_arg_with_default(self, arg: ast.arg, default: Optional[ast.AST]) -> str:
+ """Unparse a single argument to a string."""
+ name = self.visit(arg)
+ if default:
+ if arg.annotation:
+ name += " = %s" % self.visit(default)
+ else:
+ name += "=%s" % self.visit(default)
+ return name
+
+ def visit_arguments(self, node: ast.arguments) -> str:
+ defaults = list(node.defaults)
+ positionals = len(node.args)
+ posonlyargs = 0
+ if hasattr(node, "posonlyargs"): # for py38+
+ posonlyargs += len(node.posonlyargs) # type:ignore
+ positionals += posonlyargs
+ for _ in range(len(defaults), positionals):
+ defaults.insert(0, None)
+
+ kw_defaults = list(node.kw_defaults)
+ for _ in range(len(kw_defaults), len(node.kwonlyargs)):
+ kw_defaults.insert(0, None)
+
+ args = [] # type: List[str]
+ if hasattr(node, "posonlyargs"): # for py38+
+ for i, arg in enumerate(node.posonlyargs): # type: ignore
+ args.append(self._visit_arg_with_default(arg, defaults[i]))
+
+ if node.posonlyargs: # type: ignore
+ args.append('/')
+
+ for i, arg in enumerate(node.args):
+ args.append(self._visit_arg_with_default(arg, defaults[i + posonlyargs]))
+
+ if node.vararg:
+ args.append("*" + self.visit(node.vararg))
+
+ if node.kwonlyargs and not node.vararg:
+ args.append('*')
+ for i, arg in enumerate(node.kwonlyargs):
+ args.append(self._visit_arg_with_default(arg, kw_defaults[i]))
+
+ if node.kwarg:
+ args.append("**" + self.visit(node.kwarg))
+
+ return ", ".join(args)
+
+ def visit_Attribute(self, node: ast.Attribute) -> str:
+ return "%s.%s" % (self.visit(node.value), node.attr)
+
+ def visit_BinOp(self, node: ast.BinOp) -> str:
+ return " ".join(self.visit(e) for e in [node.left, node.op, node.right])
+
+ def visit_BoolOp(self, node: ast.BoolOp) -> str:
+ op = " %s " % self.visit(node.op)
+ return op.join(self.visit(e) for e in node.values)
+
+ def visit_Call(self, node: ast.Call) -> str:
+ args = ([self.visit(e) for e in node.args] +
+ ["%s=%s" % (k.arg, self.visit(k.value)) for k in node.keywords])
+ return "%s(%s)" % (self.visit(node.func), ", ".join(args))
+
+ def visit_Dict(self, node: ast.Dict) -> str:
+ keys = (self.visit(k) for k in node.keys)
+ values = (self.visit(v) for v in node.values)
items = (k + ": " + v for k, v in zip(keys, values))
return "{" + ", ".join(items) + "}"
- elif isinstance(node, ast.Ellipsis):
- return "..."
- elif isinstance(node, ast.Index):
- return unparse(node.value)
- elif isinstance(node, ast.Lambda):
- return "lambda %s: ..." % unparse(node.args)
- elif isinstance(node, ast.List):
- return "[" + ", ".join(unparse(e) for e in node.elts) + "]"
- elif isinstance(node, ast.Name):
+
+ def visit_Index(self, node: ast.Index) -> str:
+ return self.visit(node.value)
+
+ def visit_Lambda(self, node: ast.Lambda) -> str:
+ return "lambda %s: ..." % self.visit(node.args)
+
+ def visit_List(self, node: ast.List) -> str:
+ return "[" + ", ".join(self.visit(e) for e in node.elts) + "]"
+
+ def visit_Name(self, node: ast.Name) -> str:
return node.id
- elif isinstance(node, ast.NameConstant):
- return repr(node.value)
- elif isinstance(node, ast.Num):
- return repr(node.n)
- elif isinstance(node, ast.Set):
- return "{" + ", ".join(unparse(e) for e in node.elts) + "}"
- elif isinstance(node, ast.Str):
- return repr(node.s)
- elif isinstance(node, ast.Subscript):
- return "%s[%s]" % (unparse(node.value), unparse(node.slice))
- elif isinstance(node, ast.UnaryOp):
- return "%s %s" % (unparse(node.op), unparse(node.operand))
- elif isinstance(node, ast.Tuple):
+
+ def visit_Set(self, node: ast.Set) -> str:
+ return "{" + ", ".join(self.visit(e) for e in node.elts) + "}"
+
+ def visit_Subscript(self, node: ast.Subscript) -> str:
+ return "%s[%s]" % (self.visit(node.value), self.visit(node.slice))
+
+ def visit_UnaryOp(self, node: ast.UnaryOp) -> str:
+ return "%s %s" % (self.visit(node.op), self.visit(node.operand))
+
+ def visit_Tuple(self, node: ast.Tuple) -> str:
if node.elts:
- return ", ".join(unparse(e) for e in node.elts)
+ return ", ".join(self.visit(e) for e in node.elts)
else:
return "()"
- elif sys.version_info > (3, 6) and isinstance(node, ast.Constant):
- # this branch should be placed at last
- return repr(node.value)
- else:
+
+ if sys.version_info >= (3, 6):
+ def visit_Constant(self, node: ast.Constant) -> str:
+ if node.value is Ellipsis:
+ return "..."
+ else:
+ return repr(node.value)
+
+ if sys.version_info < (3, 8):
+ # these ast nodes were deprecated in python 3.8
+ def visit_Bytes(self, node: ast.Bytes) -> str:
+ return repr(node.s)
+
+ def visit_Ellipsis(self, node: ast.Ellipsis) -> str:
+ return "..."
+
+ def visit_NameConstant(self, node: ast.NameConstant) -> str:
+ return repr(node.value)
+
+ def visit_Num(self, node: ast.Num) -> str:
+ return repr(node.n)
+
+ def visit_Str(self, node: ast.Str) -> str:
+ return repr(node.s)
+
+ def generic_visit(self, node):
raise NotImplementedError('Unable to parse %s object' % type(node).__name__)
-
-
-def _unparse_arg(arg: ast.arg, default: Optional[ast.AST]) -> str:
- """Unparse a single argument to a string."""
- name = unparse(arg)
- if default:
- if arg.annotation:
- name += " = %s" % unparse(default)
- else:
- name += "=%s" % unparse(default)
- return name
-
-
-def unparse_arguments(node: ast.arguments) -> str:
- """Unparse an arguments to string."""
- defaults = list(node.defaults) # type: List[Optional[ast.AST]]
- positionals = len(node.args)
- posonlyargs = 0
- if hasattr(node, "posonlyargs"): # for py38+
- posonlyargs += len(node.posonlyargs) # type:ignore
- positionals += posonlyargs
- for _ in range(len(defaults), positionals):
- defaults.insert(0, None)
-
- kw_defaults = list(node.kw_defaults) # type: List[Optional[ast.AST]]
- for _ in range(len(kw_defaults), len(node.kwonlyargs)):
- kw_defaults.insert(0, None)
-
- args = [] # type: List[str]
- if hasattr(node, "posonlyargs"): # for py38+
- for i, arg in enumerate(node.posonlyargs): # type: ignore
- args.append(_unparse_arg(arg, defaults[i]))
-
- if node.posonlyargs: # type: ignore
- args.append('/')
-
- for i, arg in enumerate(node.args):
- args.append(_unparse_arg(arg, defaults[i + posonlyargs]))
-
- if node.vararg:
- args.append("*" + unparse(node.vararg))
-
- if node.kwonlyargs and not node.vararg:
- args.append('*')
- for i, arg in enumerate(node.kwonlyargs):
- args.append(_unparse_arg(arg, kw_defaults[i]))
-
- if node.kwarg:
- args.append("**" + unparse(node.kwarg))
-
- return ", ".join(args)
diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py
index 68850a557..16b41291d 100644
--- a/sphinx/search/__init__.py
+++ b/sphinx/search/__init__.py
@@ -22,7 +22,7 @@ from sphinx import addnodes
from sphinx import package_dir
from sphinx.environment import BuildEnvironment
from sphinx.search.jssplitter import splitter_code
-from sphinx.util import jsdump, rpartition
+from sphinx.util import jsdump
class SearchLanguage:
@@ -324,7 +324,7 @@ class IndexBuilder:
continue
fullname = html.escape(fullname)
dispname = html.escape(dispname)
- prefix, name = rpartition(dispname, '.')
+ prefix, _, name = dispname.rpartition('.')
pdict = rv.setdefault(prefix, {})
try:
typeindex = otypes[domainname, type]
diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py
index 1e9abced1..43ea64de8 100644
--- a/sphinx/transforms/__init__.py
+++ b/sphinx/transforms/__init__.py
@@ -23,6 +23,7 @@ from docutils.utils.smartquotes import smartchars
from sphinx import addnodes
from sphinx.config import Config
from sphinx.locale import _, __
+from sphinx.util import docutils
from sphinx.util import logging
from sphinx.util.docutils import new_document
from sphinx.util.i18n import format_date
@@ -359,12 +360,18 @@ class SphinxSmartQuotes(SmartQuotes, SphinxTransform):
def get_tokens(self, txtnodes: List[Text]) -> Generator[Tuple[str, str], None, None]:
# A generator that yields ``(texttype, nodetext)`` tuples for a list
# of "Text" nodes (interface to ``smartquotes.educate_tokens()``).
-
- texttype = {True: 'literal', # "literal" text is not changed:
- False: 'plain'}
for txtnode in txtnodes:
- notsmartquotable = not is_smartquotable(txtnode)
- yield (texttype[notsmartquotable], txtnode.astext())
+ if is_smartquotable(txtnode):
+ if docutils.__version_info__ >= (0, 16):
+ # SmartQuotes uses backslash escapes instead of null-escapes
+ text = re.sub(r'(?<=\x00)([-\\\'".`])', r'\\\1', str(txtnode))
+ else:
+ text = txtnode.astext()
+
+ yield ('plain', text)
+ else:
+ # skip smart quotes
+ yield ('literal', txtnode.astext())
class DoctreeReadEvent(SphinxTransform):
diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py
index d1b513b27..f2cacac3c 100644
--- a/sphinx/transforms/post_transforms/images.py
+++ b/sphinx/transforms/post_transforms/images.py
@@ -10,7 +10,6 @@
import os
import re
-from hashlib import sha1
from math import ceil
from typing import Any, Dict, List, Tuple
@@ -19,7 +18,7 @@ from docutils import nodes
from sphinx.application import Sphinx
from sphinx.locale import __
from sphinx.transforms import SphinxTransform
-from sphinx.util import epoch_to_rfc1123, rfc1123_to_epoch
+from sphinx.util import epoch_to_rfc1123, rfc1123_to_epoch, sha1
from sphinx.util import logging, requests
from sphinx.util.images import guess_mimetype, get_image_extension, parse_data_uri
from sphinx.util.osutil import ensuredir, movefile
@@ -194,7 +193,9 @@ class ImageConverter(BaseImageConverter):
super().__init__(*args, **kwargs)
def match(self, node: nodes.image) -> bool:
- if self.available is None:
+ if not self.app.builder.supported_image_types:
+ return False
+ elif self.available is None:
self.available = self.is_available()
if not self.available:
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 9a1887759..f3659cc4c 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -9,15 +9,16 @@
"""
import functools
+import hashlib
import os
import posixpath
import re
import sys
import tempfile
import traceback
+import warnings
import unicodedata
from datetime import datetime
-from hashlib import md5
from importlib import import_module
from os import path
from time import mktime, strptime
@@ -25,6 +26,7 @@ from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Pattern, S
from typing import TYPE_CHECKING
from urllib.parse import urlsplit, urlunsplit, quote_plus, parse_qsl, urlencode
+from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.errors import SphinxParallelError, ExtensionError, FiletypeNotFoundError
from sphinx.locale import __
from sphinx.util import logging
@@ -145,6 +147,36 @@ class FilenameUniqDict(dict):
self._existing = state
+def md5(data=b'', **kwargs):
+ """Wrapper around hashlib.md5
+
+ Attempt call with 'usedforsecurity=False' if we get a ValueError, which happens when
+ OpenSSL FIPS mode is enabled:
+ ValueError: error:060800A3:digital envelope routines:EVP_DigestInit_ex:disabled for fips
+
+ See: https://github.com/sphinx-doc/sphinx/issues/7611
+ """
+
+ try:
+ return hashlib.md5(data, **kwargs) # type: ignore
+ except ValueError:
+ return hashlib.md5(data, **kwargs, usedforsecurity=False) # type: ignore
+
+
+def sha1(data=b'', **kwargs):
+ """Wrapper around hashlib.sha1
+
+ Attempt call with 'usedforsecurity=False' if we get a ValueError
+
+ See: https://github.com/sphinx-doc/sphinx/issues/7611
+ """
+
+ try:
+ return hashlib.sha1(data, **kwargs) # type: ignore
+ except ValueError:
+ return hashlib.sha1(data, **kwargs, usedforsecurity=False) # type: ignore
+
+
class DownloadFiles(dict):
"""A special dictionary for download files.
@@ -310,6 +342,7 @@ def parselinenos(spec: str, total: int) -> List[int]:
def rpartition(s: str, t: str) -> Tuple[str, str]:
"""Similar to str.rpartition from 2.5, but doesn't return the separator."""
+ warnings.warn('rpartition() is now deprecated.', RemovedInSphinx50Warning, stacklevel=2)
i = s.rfind(t)
if i != -1:
return s[:i], s[i + len(t):]
@@ -378,6 +411,31 @@ def import_object(objname: str, source: str = None) -> Any:
raise ExtensionError('Could not import %s' % objname, exc)
+def split_full_qualified_name(name: str) -> Tuple[str, str]:
+ """Split full qualified name to a pair of modname and qualname.
+
+ A qualname is an abbreviation for "Qualified name" introduced at PEP-3155
+ (https://www.python.org/dev/peps/pep-3155/). It is a dotted path name
+ from the module top-level.
+
+ A "full" qualified name means a string containing both module name and
+ qualified name.
+
+ .. note:: This function imports module actually to check the exisitence.
+ Therefore you need to mock 3rd party modules if needed before
+ calling this function.
+ """
+ parts = name.split('.')
+ for i, part in enumerate(parts, 1):
+ try:
+ modname = ".".join(parts[:i])
+ import_module(modname)
+ except ImportError:
+ return ".".join(parts[:i - 1]), ".".join(parts[i - 1:])
+
+ return name, ""
+
+
def encode_uri(uri: str) -> str:
split = list(urlsplit(uri))
split[1] = split[1].encode('idna').decode('ascii')
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 5118ee98c..79efbeaf7 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -372,27 +372,39 @@ def is_builtin_class_method(obj: Any, attr_name: str) -> bool:
Why this function needed? CPython implements int.__init__ by Descriptor
but PyPy implements it by pure Python code.
"""
- classes = [c for c in inspect.getmro(obj) if attr_name in c.__dict__]
- cls = classes[0] if classes else object
-
- if not hasattr(builtins, safe_getattr(cls, '__name__', '')):
+ try:
+ mro = inspect.getmro(obj)
+ except AttributeError:
+ # no __mro__, assume the object has no methods as we know them
return False
- return getattr(builtins, safe_getattr(cls, '__name__', '')) is cls
+
+ try:
+ cls = next(c for c in mro if attr_name in safe_getattr(c, '__dict__', {}))
+ except StopIteration:
+ return False
+
+ try:
+ name = safe_getattr(cls, '__name__')
+ except AttributeError:
+ return False
+
+ return getattr(builtins, name, None) is cls
-def signature(subject: Callable, bound_method: bool = False) -> inspect.Signature:
+def signature(subject: Callable, bound_method: bool = False, follow_wrapped: bool = False
+ ) -> inspect.Signature:
"""Return a Signature object for the given *subject*.
:param bound_method: Specify *subject* is a bound method or not
+ :param follow_wrapped: Same as ``inspect.signature()``.
+ Defaults to ``False`` (get a signature of *subject*).
"""
- # check subject is not a built-in class (ex. int, str)
- if (isinstance(subject, type) and
- is_builtin_class_method(subject, "__new__") and
- is_builtin_class_method(subject, "__init__")):
- raise TypeError("can't compute signature for built-in type {}".format(subject))
-
try:
- signature = inspect.signature(subject)
+ try:
+ signature = inspect.signature(subject, follow_wrapped=follow_wrapped)
+ except ValueError:
+ # follow built-in wrappers up (ex. functools.lru_cache)
+ signature = inspect.signature(subject)
parameters = list(signature.parameters.values())
return_annotation = signature.return_annotation
except IndexError:
diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py
index 72da10dd1..8ad8bf75d 100644
--- a/sphinx/util/typing.py
+++ b/sphinx/util/typing.py
@@ -39,6 +39,12 @@ TitleGetter = Callable[[nodes.Node], str]
Inventory = Dict[str, Dict[str, Tuple[str, str, str, str]]]
+def is_system_TypeVar(typ: Any) -> bool:
+ """Check *typ* is system defined TypeVar."""
+ modname = getattr(typ, '__module__', '')
+ return modname == 'typing' and isinstance(typ, TypeVar) # type: ignore
+
+
def stringify(annotation: Any) -> str:
"""Stringify type annotation object."""
if isinstance(annotation, str):
@@ -85,18 +91,23 @@ def _stringify_py37(annotation: Any) -> str:
if getattr(annotation, '__args__', None):
if qualname == 'Union':
- if len(annotation.__args__) == 2 and annotation.__args__[1] is NoneType: # type: ignore # NOQA
- return 'Optional[%s]' % stringify(annotation.__args__[0])
+ if len(annotation.__args__) > 1 and annotation.__args__[-1] is NoneType: # type: ignore # NOQA
+ if len(annotation.__args__) > 2:
+ args = ', '.join(stringify(a) for a in annotation.__args__[:-1])
+ return 'Optional[Union[%s]]' % args
+ else:
+ return 'Optional[%s]' % stringify(annotation.__args__[0])
else:
args = ', '.join(stringify(a) for a in annotation.__args__)
- return '%s[%s]' % (qualname, args)
+ return 'Union[%s]' % args
elif qualname == 'Callable':
args = ', '.join(stringify(a) for a in annotation.__args__[:-1])
returns = stringify(annotation.__args__[-1])
return '%s[[%s], %s]' % (qualname, args, returns)
elif str(annotation).startswith('typing.Annotated'): # for py39+
return stringify(annotation.__args__[0])
- elif getattr(annotation, '_special', False):
+ elif all(is_system_TypeVar(a) for a in annotation.__args__):
+ # Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT])
return qualname
else:
args = ', '.join(stringify(a) for a in annotation.__args__)
@@ -148,8 +159,12 @@ def _stringify_py36(annotation: Any) -> str:
annotation.__origin__ is typing.Union):
params = annotation.__args__
if params is not None:
- if len(params) == 2 and params[1] is NoneType: # type: ignore
- return 'Optional[%s]' % stringify(params[0])
+ if len(params) > 1 and params[-1] is NoneType: # type: ignore
+ if len(params) > 2:
+ param_str = ", ".join(stringify(p) for p in params[:-1])
+ return 'Optional[Union[%s]]' % param_str
+ else:
+ return 'Optional[%s]' % stringify(params[0])
else:
param_str = ', '.join(stringify(p) for p in params)
return 'Union[%s]' % param_str
diff --git a/tests/roots/test-ext-autodoc/target/classes.py b/tests/roots/test-ext-autodoc/target/classes.py
new file mode 100644
index 000000000..dc471a6f3
--- /dev/null
+++ b/tests/roots/test-ext-autodoc/target/classes.py
@@ -0,0 +1,12 @@
+class Foo:
+ pass
+
+
+class Bar:
+ def __init__(self, x, y):
+ pass
+
+
+class Baz:
+ def __new__(cls, x, y):
+ pass
diff --git a/tests/roots/test-ext-autodoc/target/decorator.py b/tests/roots/test-ext-autodoc/target/decorator.py
index 4ccfedf28..61398b324 100644
--- a/tests/roots/test-ext-autodoc/target/decorator.py
+++ b/tests/roots/test-ext-autodoc/target/decorator.py
@@ -1,5 +1,9 @@
+from functools import wraps
+
+
def deco1(func):
"""docstring for deco1"""
+ @wraps(func)
def wrapper():
return func()
@@ -14,3 +18,14 @@ def deco2(condition, message):
return wrapper
return decorator
+
+
+@deco1
+def foo(name=None, age=None):
+ pass
+
+
+class Bar:
+ @deco1
+ def meth(self, name=None, age=None):
+ pass
diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_module.py
index 02e6c0e7d..ffd381f51 100644
--- a/tests/roots/test-ext-autosummary/autosummary_dummy_module.py
+++ b/tests/roots/test-ext-autosummary/autosummary_dummy_module.py
@@ -3,6 +3,9 @@ from typing import Union
class Foo:
+ class Bar:
+ pass
+
def __init__(self):
pass
diff --git a/tests/roots/test-ext-autosummary/index.rst b/tests/roots/test-ext-autosummary/index.rst
index 2dc90b538..bc3f80234 100644
--- a/tests/roots/test-ext-autosummary/index.rst
+++ b/tests/roots/test-ext-autosummary/index.rst
@@ -9,5 +9,6 @@
autosummary_dummy_module
autosummary_dummy_module.Foo
+ autosummary_dummy_module.Foo.Bar
autosummary_dummy_module.bar
autosummary_importfail
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
deleted file mode 100644
index c2271b60a..000000000
--- a/tests/test_autodoc.py
+++ /dev/null
@@ -1,1736 +0,0 @@
-"""
- test_autodoc
- ~~~~~~~~~~~~
-
- Test the autodoc extension. This tests mainly the Documenters; the auto
- directives are tested in a test source file translated by test_build.
-
- :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
- :license: BSD, see LICENSE for details.
-"""
-
-import sys
-from unittest.mock import Mock
-from warnings import catch_warnings
-
-import pytest
-from docutils.statemachine import ViewList
-
-from sphinx.ext.autodoc import ModuleLevelDocumenter, ALL, Options
-from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options
-from sphinx.testing.util import SphinxTestApp, Struct # NOQA
-from sphinx.util import logging
-from sphinx.util.docutils import LoggingReporter
-
-try:
- # Enable pyximport to test cython module
- import pyximport
- pyximport.install()
-except ImportError:
- pyximport = None
-
-app = None
-
-
-def do_autodoc(app, objtype, name, options=None):
- if options is None:
- options = {}
- app.env.temp_data.setdefault('docname', 'index') # set dummy docname
- doccls = app.registry.documenters[objtype]
- docoptions = process_documenter_options(doccls, app.config, options)
- state = Mock()
- state.document.settings.tab_width = 8
- bridge = DocumenterBridge(app.env, LoggingReporter(''), docoptions, 1, state)
- documenter = doccls(bridge, name)
- documenter.generate()
-
- return bridge.result
-
-
-@pytest.fixture(scope='module', autouse=True)
-def setup_module(rootdir, sphinx_test_tempdir):
- try:
- global app
- srcdir = sphinx_test_tempdir / 'autodoc-root'
- if not srcdir.exists():
- (rootdir / 'test-root').copytree(srcdir)
- testroot = rootdir / 'test-ext-autodoc'
- sys.path.append(testroot)
- app = SphinxTestApp(srcdir=srcdir)
- app.builder.env.app = app
- app.builder.env.temp_data['docname'] = 'dummy'
- app.connect('autodoc-process-signature', process_signature)
- app.connect('autodoc-skip-member', skip_member)
- yield
- finally:
- app.cleanup()
- sys.path.remove(testroot)
-
-
-directive = options = None
-
-
-@pytest.fixture
-def setup_test():
- global options, directive
- global processed_signatures
-
- options = Options(
- inherited_members = False,
- undoc_members = False,
- private_members = False,
- special_members = False,
- imported_members = False,
- show_inheritance = False,
- noindex = False,
- annotation = None,
- synopsis = '',
- platform = '',
- deprecated = False,
- members = [],
- member_order = 'alphabetic',
- exclude_members = set(),
- ignore_module_all = False,
- )
-
- directive = Struct(
- env = app.builder.env,
- genopt = options,
- result = ViewList(),
- filename_set = set(),
- state = Mock(),
- )
- directive.state.document.settings.tab_width = 8
-
- processed_signatures = []
-
- app._status.truncate(0)
- app._warning.truncate(0)
-
- yield
-
- app.registry.autodoc_attrgettrs.clear()
-
-
-processed_signatures = []
-
-
-def process_signature(app, what, name, obj, options, args, retann):
- processed_signatures.append((what, name))
- if name == 'bar':
- return '42', None
-
-
-def skip_member(app, what, name, obj, skip, options):
- if name in ('__special1__', '__special2__'):
- return skip
- if name.startswith('__'):
- return True
- if name == 'skipmeth':
- return True
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_parse_name():
- logging.setup(app, app._status, app._warning)
-
- def verify(objtype, name, result):
- inst = app.registry.documenters[objtype](directive, name)
- assert inst.parse_name()
- assert (inst.modname, inst.objpath, inst.args, inst.retann) == result
-
- # for modules
- verify('module', 'test_autodoc', ('test_autodoc', [], None, None))
- verify('module', 'test.test_autodoc', ('test.test_autodoc', [], None, None))
- verify('module', 'test(arg)', ('test', [], 'arg', None))
- assert 'signature arguments' in app._warning.getvalue()
-
- # for functions/classes
- verify('function', 'test_autodoc.raises',
- ('test_autodoc', ['raises'], None, None))
- verify('function', 'test_autodoc.raises(exc) -> None',
- ('test_autodoc', ['raises'], 'exc', 'None'))
- directive.env.temp_data['autodoc:module'] = 'test_autodoc'
- verify('function', 'raises', ('test_autodoc', ['raises'], None, None))
- del directive.env.temp_data['autodoc:module']
- directive.env.ref_context['py:module'] = 'test_autodoc'
- verify('function', 'raises', ('test_autodoc', ['raises'], None, None))
- verify('class', 'Base', ('test_autodoc', ['Base'], None, None))
-
- # for members
- directive.env.ref_context['py:module'] = 'foo'
- verify('method', 'util.SphinxTestApp.cleanup',
- ('util', ['SphinxTestApp', 'cleanup'], None, None))
- directive.env.ref_context['py:module'] = 'util'
- directive.env.ref_context['py:class'] = 'Foo'
- directive.env.temp_data['autodoc:class'] = 'SphinxTestApp'
- verify('method', 'cleanup', ('util', ['SphinxTestApp', 'cleanup'], None, None))
- verify('method', 'SphinxTestApp.cleanup',
- ('util', ['SphinxTestApp', 'cleanup'], None, None))
-
- # and clean up
- del directive.env.ref_context['py:module']
- del directive.env.ref_context['py:class']
- del directive.env.temp_data['autodoc:class']
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_format_signature():
- def formatsig(objtype, name, obj, args, retann):
- inst = app.registry.documenters[objtype](directive, name)
- inst.fullname = name
- inst.doc_as_attr = False # for class objtype
- inst.object = obj
- inst.objpath = [name]
- inst.args = args
- inst.retann = retann
- res = inst.format_signature()
- print(res)
- return res
-
- # no signatures for modules
- assert formatsig('module', 'test', None, None, None) == ''
-
- # test for functions
- def f(a, b, c=1, **d):
- pass
-
- def g(a='\n'):
- pass
- assert formatsig('function', 'f', f, None, None) == '(a, b, c=1, **d)'
- assert formatsig('function', 'f', f, 'a, b, c, d', None) == '(a, b, c, d)'
- assert formatsig('function', 'f', f, None, 'None') == '(a, b, c=1, **d) -> None'
- assert formatsig('function', 'g', g, None, None) == r"(a='\n')"
-
- # test for classes
- class D:
- pass
-
- class E:
- pass
- # no signature for classes without __init__
- for C in (D, E):
- assert formatsig('class', 'D', C, None, None) == ''
-
- class F:
- def __init__(self, a, b=None):
- pass
-
- class G(F):
- pass
- for C in (F, G):
- assert formatsig('class', 'C', C, None, None) == '(a, b=None)'
- assert formatsig('class', 'C', D, 'a, b', 'X') == '(a, b) -> X'
-
- # __init__ have signature at first line of docstring
- directive.env.config.autoclass_content = 'both'
-
- class F2:
- '''some docstring for F2.'''
- def __init__(self, *args, **kw):
- '''
- __init__(a1, a2, kw1=True, kw2=False)
-
- some docstring for __init__.
- '''
- class G2(F2):
- pass
-
- assert formatsig('class', 'F2', F2, None, None) == \
- '(a1, a2, kw1=True, kw2=False)'
- assert formatsig('class', 'G2', G2, None, None) == \
- '(a1, a2, kw1=True, kw2=False)'
-
- # test for methods
- class H:
- def foo1(self, b, *c):
- pass
-
- def foo2(b, *c):
- pass
-
- def foo3(self, d='\n'):
- pass
- assert formatsig('method', 'H.foo', H.foo1, None, None) == '(b, *c)'
- assert formatsig('method', 'H.foo', H.foo1, 'a', None) == '(a)'
- assert formatsig('method', 'H.foo', H.foo2, None, None) == '(*c)'
- assert formatsig('method', 'H.foo', H.foo3, None, None) == r"(d='\n')"
-
- # test bound methods interpreted as functions
- assert formatsig('function', 'foo', H().foo1, None, None) == '(b, *c)'
- assert formatsig('function', 'foo', H().foo2, None, None) == '(*c)'
- assert formatsig('function', 'foo', H().foo3, None, None) == r"(d='\n')"
-
- # test exception handling (exception is caught and args is '')
- directive.env.config.autodoc_docstring_signature = False
- assert formatsig('function', 'int', int, None, None) == ''
-
- # test processing by event handler
- assert formatsig('method', 'bar', H.foo1, None, None) == '42'
-
- # test functions created via functools.partial
- from functools import partial
- curried1 = partial(lambda a, b, c: None, 'A')
- assert formatsig('function', 'curried1', curried1, None, None) == \
- '(b, c)'
- curried2 = partial(lambda a, b, c=42: None, 'A')
- assert formatsig('function', 'curried2', curried2, None, None) == \
- '(b, c=42)'
- curried3 = partial(lambda a, b, *c: None, 'A')
- assert formatsig('function', 'curried3', curried3, None, None) == \
- '(b, *c)'
- curried4 = partial(lambda a, b, c=42, *d, **e: None, 'A')
- assert formatsig('function', 'curried4', curried4, None, None) == \
- '(b, c=42, *d, **e)'
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_get_doc():
- def getdocl(objtype, obj):
- inst = app.registry.documenters[objtype](directive, 'tmp')
- inst.object = obj
- inst.objpath = [obj.__name__]
- inst.doc_as_attr = False
- inst.format_signature() # handle docstring signatures!
- ds = inst.get_doc()
- # for testing purposes, concat them and strip the empty line at the end
- res = sum(ds, [])[:-1]
- print(res)
- return res
-
- # objects without docstring
- def f():
- pass
- assert getdocl('function', f) == []
-
- # standard function, diverse docstring styles...
- def f():
- """Docstring"""
- def g():
- """
- Docstring
- """
- for func in (f, g):
- assert getdocl('function', func) == ['Docstring']
-
- # first line vs. other lines indentation
- def f():
- """First line
-
- Other
- lines
- """
- assert getdocl('function', f) == ['First line', '', 'Other', ' lines']
-
- # charset guessing (this module is encoded in utf-8)
- def f():
- """Döcstring"""
- assert getdocl('function', f) == ['Döcstring']
-
- # already-unicode docstrings must be taken literally
- def f():
- """Döcstring"""
- assert getdocl('function', f) == ['Döcstring']
-
- # verify that method docstrings get extracted in both normal case
- # and in case of bound method posing as a function
- class J: # NOQA
- def foo(self):
- """Method docstring"""
- assert getdocl('method', J.foo) == ['Method docstring']
- assert getdocl('function', J().foo) == ['Method docstring']
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_new_documenter(app):
- class MyDocumenter(ModuleLevelDocumenter):
- objtype = 'integer'
- directivetype = 'integer'
- priority = 100
-
- @classmethod
- def can_document_member(cls, member, membername, isattr, parent):
- return isinstance(member, int)
-
- def document_members(self, all_members=False):
- return
-
- app.add_autodocumenter(MyDocumenter)
-
- options = {"members": 'integer'}
- actual = do_autodoc(app, 'module', 'target', options)
- assert list(actual) == [
- '',
- '.. py:module:: target',
- '',
- '',
- '.. py:integer:: integer',
- ' :module: target',
- '',
- ' documentation for the integer',
- '',
- ]
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_attrgetter_using():
- from target import Class
- from target.inheritance import Derived
-
- def assert_getter_works(objtype, name, obj, attrs=[], **kw):
- getattr_spy = []
-
- def special_getattr(obj, name, *defargs):
- if name in attrs:
- getattr_spy.append((obj, name))
- return None
- return getattr(obj, name, *defargs)
- app.add_autodoc_attrgetter(type, special_getattr)
-
- del getattr_spy[:]
- inst = app.registry.documenters[objtype](directive, name)
- inst.generate(**kw)
-
- hooked_members = [s[1] for s in getattr_spy]
- documented_members = [s[1] for s in processed_signatures]
- for attr in attrs:
- fullname = '.'.join((name, attr))
- assert attr in hooked_members
- assert fullname not in documented_members, \
- '%r was not hooked by special_attrgetter function' % fullname
-
- with catch_warnings(record=True):
- options.members = ALL
- options.inherited_members = False
- assert_getter_works('class', 'target.Class', Class, ['meth'])
-
- options.inherited_members = True
- assert_getter_works('class', 'target.inheritance.Derived', Derived, ['inheritedmeth'])
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_py_module(app, warning):
- # without py:module
- actual = do_autodoc(app, 'method', 'Class.meth')
- assert list(actual) == []
- assert ("don't know which module to import for autodocumenting 'Class.meth'"
- in warning.getvalue())
-
- # with py:module
- app.env.ref_context['py:module'] = 'target'
- warning.truncate(0)
-
- actual = do_autodoc(app, 'method', 'Class.meth')
- assert list(actual) == [
- '',
- '.. py:method:: Class.meth()',
- ' :module: target',
- '',
- ' Function.',
- '',
- ]
- assert ("don't know which module to import for autodocumenting 'Class.meth'"
- not in warning.getvalue())
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_decorator(app):
- actual = do_autodoc(app, 'decorator', 'target.decorator.deco1')
- assert list(actual) == [
- '',
- '.. py:decorator:: deco1',
- ' :module: target.decorator',
- '',
- ' docstring for deco1',
- '',
- ]
-
- actual = do_autodoc(app, 'decorator', 'target.decorator.deco2')
- assert list(actual) == [
- '',
- '.. py:decorator:: deco2(condition, message)',
- ' :module: target.decorator',
- '',
- ' docstring for deco2',
- '',
- ]
-
-
-@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.',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_warnings(app, warning):
- app.env.temp_data['docname'] = 'dummy'
-
- # can't import module
- do_autodoc(app, 'module', 'unknown')
- assert "failed to import module 'unknown'" in warning.getvalue()
-
- # 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.inheritance.Base')
- assert list(filter(lambda l: '::' in l, actual)) == [
- '.. py:class:: Base',
- ]
-
- # default ALL-members
- options = {"members": None}
- actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
- assert list(filter(lambda l: '::' in l, actual)) == [
- '.. py:class:: Base',
- ' .. py:method:: Base.inheritedclassmeth()',
- ' .. py:method:: Base.inheritedmeth()',
- ' .. py:method:: Base.inheritedstaticmeth(cls)'
- ]
-
- # default specific-members
- options = {"members": "inheritedmeth,inheritedstaticmeth"}
- actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
- assert list(filter(lambda l: '::' in l, actual)) == [
- '.. py:class:: Base',
- ' .. py:method:: Base.inheritedmeth()',
- ' .. py:method:: 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.inheritance.Base', options)
- assert list(filter(lambda l: '::' in l, actual)) == [
- '.. py:class:: Base',
- ' .. py:method:: Base.inheritedclassmeth()'
- ]
-
- # members vs exclude-members
- options = {"members": "inheritedmeth",
- "exclude-members": "inheritedmeth"}
- actual = do_autodoc(app, 'class', 'target.inheritance.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.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:method:: Class.moore(a, e, f) -> happiness',
- ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
- ' .. 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.inheritance.Derived', options)
- assert list(filter(lambda l: 'method::' in l, actual)) == [
- ' .. py:method:: Derived.inheritedclassmeth()',
- ' .. py:method:: Derived.inheritedmeth()',
- ' .. py:method:: Derived.inheritedstaticmeth(cls)',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_inherited_members_Base(app):
- options = {"members": None,
- "inherited-members": "Base",
- "special-members": None}
-
- # check methods for object class are shown
- actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
- assert ' .. py:method:: Derived.inheritedmeth()' in actual
- assert ' .. py:method:: Derived.inheritedclassmeth' not in actual
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_inherited_members_None(app):
- options = {"members": None,
- "inherited-members": "None",
- "special-members": None}
-
- # check methods for object class are shown
- actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
- assert ' .. py:method:: Derived.__init__' in actual
- assert ' .. py:method:: Derived.__str__' in actual
-
-
-@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:: save_traceback(app: Sphinx) -> str' in actual
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-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
- 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:attribute:: Class.__dict__',
- ' .. py:method:: Class.__init__(arg)',
- ' .. py:attribute:: Class.__module__',
- ' .. py:method:: Class.__special1__()',
- ' .. py:method:: Class.__special2__()',
- ' .. py:attribute:: Class.__weakref__',
- ' .. py:attribute:: Class.attr',
- ' .. 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:method:: Class.moore(a, e, f) -> happiness',
- ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
- ' .. 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:: CustomDict',
- '.. py:class:: InnerChild',
- '.. py:class:: InstAttCls()',
- '.. py:class:: Outer',
- ' .. py:class:: Outer.Inner',
- '.. py:class:: StrRepr'
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_noindex(app):
- options = {"noindex": True}
- actual = do_autodoc(app, 'module', 'target', options)
- assert list(actual) == [
- '',
- '.. py:module:: target',
- ' :noindex:',
- ''
- ]
-
- # TODO: :noindex: should be propagated to children of target item.
-
- actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
- assert list(actual) == [
- '',
- '.. py:class:: Base',
- ' :noindex:',
- ' :module: target.inheritance',
- ''
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_subclass_of_builtin_class(app):
- options = {"members": None}
- actual = do_autodoc(app, 'class', 'target.CustomDict', options)
- assert list(actual) == [
- '',
- '.. py:class:: CustomDict',
- ' :module: target',
- '',
- ' Docstring.',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_inner_class(app):
- options = {"members": None}
- actual = do_autodoc(app, 'class', 'target.Outer', options)
- assert list(actual) == [
- '',
- '.. py:class:: Outer',
- ' :module: target',
- '',
- ' Foo',
- '',
- '',
- ' .. py:class:: Outer.Inner',
- ' :module: target',
- '',
- ' Foo',
- '',
- '',
- ' .. py:method:: Outer.Inner.meth()',
- ' :module: target',
- '',
- ' Foo',
- '',
- '',
- ' .. py:attribute:: Outer.factory',
- ' :module: target',
- '',
- ' alias of :class:`builtins.dict`'
- ]
-
- actual = do_autodoc(app, 'class', 'target.Outer.Inner', options)
- assert list(actual) == [
- '',
- '.. py:class:: Inner',
- ' :module: target.Outer',
- '',
- ' Foo',
- '',
- '',
- ' .. py:method:: Inner.meth()',
- ' :module: target.Outer',
- '',
- ' Foo',
- '',
- ]
-
- options['show-inheritance'] = True
- actual = do_autodoc(app, 'class', 'target.InnerChild', options)
- assert list(actual) == [
- '',
- '.. py:class:: InnerChild',
- ' :module: target', '',
- ' Bases: :class:`target.Outer.Inner`',
- '',
- ' InnerChild docstring',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_classmethod(app):
- actual = do_autodoc(app, 'method', 'target.inheritance.Base.inheritedclassmeth')
- assert list(actual) == [
- '',
- '.. py:method:: Base.inheritedclassmeth()',
- ' :module: target.inheritance',
- ' :classmethod:',
- '',
- ' Inherited class method.',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_staticmethod(app):
- actual = do_autodoc(app, 'method', 'target.inheritance.Base.inheritedstaticmeth')
- assert list(actual) == [
- '',
- '.. py:method:: Base.inheritedstaticmeth(cls)',
- ' :module: target.inheritance',
- ' :staticmethod:',
- '',
- ' Inherited static method.',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_descriptor(app):
- options = {"members": None,
- "undoc-members": True}
- actual = do_autodoc(app, 'class', 'target.descriptor.Class', options)
- assert list(actual) == [
- '',
- '.. py:class:: Class',
- ' :module: target.descriptor',
- '',
- '',
- ' .. py:attribute:: Class.descr',
- ' :module: target.descriptor',
- '',
- ' Descriptor instance docstring.',
- '',
- '',
- ' .. py:method:: Class.prop',
- ' :module: target.descriptor',
- ' :property:',
- '',
- ' Property.',
- ''
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_c_module(app):
- actual = do_autodoc(app, 'function', 'time.asctime')
- assert list(actual) == [
- '',
- '.. py:function:: asctime([tuple]) -> string',
- ' :module: time',
- '',
- " Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.",
- ' When the time tuple is not present, current time as returned by localtime()',
- ' is used.',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_member_order(app):
- # case member-order='bysource'
- options = {"members": None,
- 'member-order': 'bysource',
- "undoc-members": True,
- 'private-members': True}
- actual = do_autodoc(app, 'class', 'target.Class', options)
- assert list(filter(lambda l: '::' in l, actual)) == [
- '.. py:class:: Class(arg)',
- ' .. py:method:: Class.meth()',
- ' .. py:method:: Class.undocmeth()',
- ' .. py:method:: Class.skipmeth()',
- ' .. py:method:: Class.excludemeth()',
- ' .. py:attribute:: Class.skipattr',
- ' .. py:attribute:: Class.attr',
- ' .. py:attribute:: Class.docattr',
- ' .. py:attribute:: Class.udocattr',
- ' .. py:attribute:: Class.mdocattr',
- ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
- ' .. py:method:: Class.moore(a, e, f) -> happiness',
- ' .. py:attribute:: Class.inst_attr_inline',
- ' .. py:attribute:: Class.inst_attr_comment',
- ' .. py:attribute:: Class.inst_attr_string',
- ' .. py:attribute:: Class._private_inst_attr'
- ]
-
- # case member-order='groupwise'
- options = {"members": None,
- 'member-order': 'groupwise',
- "undoc-members": True,
- 'private-members': True}
- actual = do_autodoc(app, 'class', 'target.Class', options)
- assert list(filter(lambda l: '::' in l, actual)) == [
- '.. py:class:: Class(arg)',
- ' .. py:method:: Class.excludemeth()',
- ' .. py:method:: Class.meth()',
- ' .. py:method:: Class.moore(a, e, f) -> happiness',
- ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
- ' .. py:method:: Class.skipmeth()',
- ' .. py:method:: Class.undocmeth()',
- ' .. py:attribute:: Class._private_inst_attr',
- ' .. py:attribute:: Class.attr',
- ' .. py:attribute:: Class.docattr',
- ' .. py:attribute:: Class.inst_attr_comment',
- ' .. py:attribute:: Class.inst_attr_inline',
- ' .. py:attribute:: Class.inst_attr_string',
- ' .. py:attribute:: Class.mdocattr',
- ' .. py:attribute:: Class.skipattr',
- ' .. py:attribute:: Class.udocattr'
- ]
-
- # case member-order=None
- options = {"members": None,
- "undoc-members": True,
- 'private-members': True}
- actual = do_autodoc(app, 'class', 'target.Class', options)
- assert list(filter(lambda l: '::' in l, actual)) == [
- '.. py:class:: Class(arg)',
- ' .. py:attribute:: Class._private_inst_attr',
- ' .. py:attribute:: Class.attr',
- ' .. 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:method:: Class.moore(a, e, f) -> happiness',
- ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
- ' .. 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_module_scope(app):
- app.env.temp_data['autodoc:module'] = 'target'
- actual = do_autodoc(app, 'attribute', 'Class.mdocattr')
- assert list(actual) == [
- '',
- '.. py:attribute:: Class.mdocattr',
- ' :module: target',
- ' :value: <_io.StringIO object>',
- '',
- ' should be documented as well - süß',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_class_scope(app):
- app.env.temp_data['autodoc:module'] = 'target'
- app.env.temp_data['autodoc:class'] = 'Class'
- actual = do_autodoc(app, 'attribute', 'mdocattr')
- assert list(actual) == [
- '',
- '.. py:attribute:: Class.mdocattr',
- ' :module: target',
- ' :value: <_io.StringIO object>',
- '',
- ' should be documented as well - süß',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_class_attributes(app):
- options = {"members": None,
- "undoc-members": True}
- actual = do_autodoc(app, 'class', 'target.AttCls', options)
- assert list(actual) == [
- '',
- '.. py:class:: AttCls',
- ' :module: target',
- '',
- '',
- ' .. py:attribute:: AttCls.a1',
- ' :module: target',
- ' :value: hello world',
- '',
- '',
- ' .. py:attribute:: AttCls.a2',
- ' :module: target',
- ' :value: None',
- ''
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_instance_attributes(app):
- options = {"members": None}
- actual = do_autodoc(app, 'class', 'target.InstAttCls', options)
- assert list(actual) == [
- '',
- '.. py:class:: InstAttCls()',
- ' :module: target',
- '',
- ' Class with documented class and instance attributes.',
- '',
- '',
- ' .. py:attribute:: InstAttCls.ca1',
- ' :module: target',
- " :value: 'a'",
- '',
- ' Doc comment for class attribute InstAttCls.ca1.',
- ' It can have multiple lines.',
- '',
- '',
- ' .. py:attribute:: InstAttCls.ca2',
- ' :module: target',
- " :value: 'b'",
- '',
- ' Doc comment for InstAttCls.ca2. One line only.',
- '',
- '',
- ' .. py:attribute:: InstAttCls.ca3',
- ' :module: target',
- " :value: 'c'",
- '',
- ' Docstring for class attribute InstAttCls.ca3.',
- '',
- '',
- ' .. py:attribute:: InstAttCls.ia1',
- ' :module: target',
- '',
- ' Doc comment for instance attribute InstAttCls.ia1',
- '',
- '',
- ' .. py:attribute:: InstAttCls.ia2',
- ' :module: target',
- '',
- ' Docstring for instance attribute InstAttCls.ia2.',
- ''
- ]
-
- # pick up arbitrary attributes
- options = {"members": 'ca1,ia1'}
- actual = do_autodoc(app, 'class', 'target.InstAttCls', options)
- assert list(actual) == [
- '',
- '.. py:class:: InstAttCls()',
- ' :module: target',
- '',
- ' Class with documented class and instance attributes.',
- '',
- '',
- ' .. py:attribute:: InstAttCls.ca1',
- ' :module: target',
- " :value: 'a'",
- '',
- ' Doc comment for class attribute InstAttCls.ca1.',
- ' It can have multiple lines.',
- '',
- '',
- ' .. py:attribute:: InstAttCls.ia1',
- ' :module: target',
- '',
- ' Doc comment for instance attribute InstAttCls.ia1',
- ''
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_slots(app):
- options = {"members": None,
- "undoc-members": True}
- actual = do_autodoc(app, 'module', 'target.slots', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.slots',
- '',
- '',
- '.. py:class:: Bar()',
- ' :module: target.slots',
- '',
- '',
- ' .. py:attribute:: Bar.attr1',
- ' :module: target.slots',
- '',
- ' docstring of attr1',
- '',
- '',
- ' .. py:attribute:: Bar.attr2',
- ' :module: target.slots',
- '',
- ' docstring of instance attr2',
- '',
- '',
- ' .. py:attribute:: Bar.attr3',
- ' :module: target.slots',
- '',
- '',
- '.. py:class:: Foo',
- ' :module: target.slots',
- '',
- '',
- ' .. py:attribute:: Foo.attr',
- ' :module: target.slots',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_enum_class(app):
- options = {"members": None}
- actual = do_autodoc(app, 'class', 'target.enum.EnumCls', options)
- assert list(actual) == [
- '',
- '.. py:class:: EnumCls',
- ' :module: target.enum',
- '',
- ' this is enum class',
- '',
- '',
- ' .. py:method:: EnumCls.say_goodbye()',
- ' :module: target.enum',
- ' :classmethod:',
- '',
- ' a classmethod says good-bye to you.',
- '',
- '',
- ' .. py:method:: EnumCls.say_hello()',
- ' :module: target.enum',
- '',
- ' a method says hello to you.',
- '',
- '',
- ' .. py:attribute:: EnumCls.val1',
- ' :module: target.enum',
- ' :value: 12',
- '',
- ' doc for val1',
- '',
- '',
- ' .. py:attribute:: EnumCls.val2',
- ' :module: target.enum',
- ' :value: 23',
- '',
- ' doc for val2',
- '',
- '',
- ' .. py:attribute:: EnumCls.val3',
- ' :module: target.enum',
- ' :value: 34',
- '',
- ' doc for val3',
- '',
- ]
-
- # checks for an attribute of EnumClass
- actual = do_autodoc(app, 'attribute', 'target.enum.EnumCls.val1')
- assert list(actual) == [
- '',
- '.. py:attribute:: EnumCls.val1',
- ' :module: target.enum',
- ' :value: 12',
- '',
- ' doc for val1',
- ''
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_descriptor_class(app):
- options = {"members": 'CustomDataDescriptor,CustomDataDescriptor2'}
- actual = do_autodoc(app, 'module', 'target.descriptor', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.descriptor',
- '',
- '',
- '.. py:class:: CustomDataDescriptor(doc)',
- ' :module: target.descriptor',
- '',
- ' Descriptor class docstring.',
- '',
- '',
- ' .. py:method:: CustomDataDescriptor.meth()',
- ' :module: target.descriptor',
- '',
- ' Function.',
- '',
- '',
- '.. py:class:: CustomDataDescriptor2(doc)',
- ' :module: target.descriptor',
- '',
- ' Descriptor class with custom metaclass docstring.',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autofunction_for_callable(app):
- actual = do_autodoc(app, 'function', 'target.callable.function')
- assert list(actual) == [
- '',
- '.. py:function:: function(arg1, arg2, **kwargs)',
- ' :module: target.callable',
- '',
- ' A callable object that behaves like a function.',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autofunction_for_method(app):
- actual = do_autodoc(app, 'function', 'target.callable.method')
- assert list(actual) == [
- '',
- '.. py:function:: method(arg1, arg2)',
- ' :module: target.callable',
- '',
- ' docstring of Callable.method().',
- '',
- ]
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_abstractmethods():
- options = {"members": None,
- "undoc-members": None}
- actual = do_autodoc(app, 'module', 'target.abstractmethods', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.abstractmethods',
- '',
- '',
- '.. py:class:: Base',
- ' :module: target.abstractmethods',
- '',
- '',
- ' .. py:method:: Base.abstractmeth()',
- ' :module: target.abstractmethods',
- ' :abstractmethod:',
- '',
- '',
- ' .. py:method:: Base.classmeth()',
- ' :module: target.abstractmethods',
- ' :abstractmethod:',
- ' :classmethod:',
- '',
- '',
- ' .. py:method:: Base.coroutinemeth()',
- ' :module: target.abstractmethods',
- ' :abstractmethod:',
- ' :async:',
- '',
- '',
- ' .. py:method:: Base.meth()',
- ' :module: target.abstractmethods',
- '',
- '',
- ' .. py:method:: Base.prop',
- ' :module: target.abstractmethods',
- ' :abstractmethod:',
- ' :property:',
- '',
- '',
- ' .. py:method:: Base.staticmeth()',
- ' :module: target.abstractmethods',
- ' :abstractmethod:',
- ' :staticmethod:',
- '',
- ]
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_partialfunction():
- options = {"members": None}
- actual = do_autodoc(app, 'module', 'target.partialfunction', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.partialfunction',
- '',
- '',
- '.. py:function:: func1(a, b, c)',
- ' :module: target.partialfunction',
- '',
- ' docstring of func1',
- '',
- '',
- '.. py:function:: func2(b, c)',
- ' :module: target.partialfunction',
- '',
- ' docstring of func1',
- '',
- '',
- '.. py:function:: func3(c)',
- ' :module: target.partialfunction',
- '',
- ' docstring of func3',
- '',
- '',
- '.. py:function:: func4()',
- ' :module: target.partialfunction',
- '',
- ' docstring of func3',
- '',
- ]
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_imported_partialfunction_should_not_shown_without_imported_members():
- options = {"members": None}
- actual = do_autodoc(app, 'module', 'target.imported_members', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.imported_members',
- ''
- ]
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_bound_method():
- options = {"members": None}
- actual = do_autodoc(app, 'module', 'target.bound_method', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.bound_method',
- '',
- '',
- '.. py:function:: bound_method()',
- ' :module: target.bound_method',
- '',
- ' Method docstring',
- '',
- ]
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_coroutine():
- actual = do_autodoc(app, 'function', 'target.functions.coroutinefunc')
- assert list(actual) == [
- '',
- '.. py:function:: coroutinefunc()',
- ' :module: target.functions',
- ' :async:',
- '',
- ]
-
- options = {"members": None}
- actual = do_autodoc(app, 'class', 'target.coroutine.AsyncClass', options)
- assert list(actual) == [
- '',
- '.. py:class:: AsyncClass',
- ' :module: target.coroutine',
- '',
- '',
- ' .. py:method:: AsyncClass.do_coroutine()',
- ' :module: target.coroutine',
- ' :async:',
- '',
- ' A documented coroutine function',
- '',
- '',
- ' .. py:method:: AsyncClass.do_coroutine2()',
- ' :module: target.coroutine',
- ' :async:',
- ' :classmethod:',
- '',
- ' A documented coroutine classmethod',
- '',
- '',
- ' .. py:method:: AsyncClass.do_coroutine3()',
- ' :module: target.coroutine',
- ' :async:',
- ' :staticmethod:',
- '',
- ' A documented coroutine staticmethod',
- '',
- ]
-
- # force-synchronized wrapper
- actual = do_autodoc(app, 'function', 'target.coroutine.sync_func')
- assert list(actual) == [
- '',
- '.. py:function:: sync_func()',
- ' :module: target.coroutine',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_partialmethod(app):
- expected = [
- '',
- '.. py:class:: Cell',
- ' :module: target.partialmethod',
- '',
- ' An example for partialmethod.',
- '',
- ' refs: https://docs.python.jp/3/library/functools.html#functools.partialmethod',
- '',
- '',
- ' .. py:method:: Cell.set_alive()',
- ' :module: target.partialmethod',
- '',
- ' Make a cell alive.',
- '',
- '',
- ' .. py:method:: Cell.set_state(state)',
- ' :module: target.partialmethod',
- '',
- ' Update state of cell to *state*.',
- '',
- ]
-
- options = {"members": None}
- actual = do_autodoc(app, 'class', 'target.partialmethod.Cell', options)
- assert list(actual) == expected
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_wrappedfunction(app):
- actual = do_autodoc(app, 'function', 'target.wrappedfunction.slow_function')
- assert list(actual) == [
- '',
- '.. py:function:: slow_function(message, timeout)',
- ' :module: target.wrappedfunction',
- '',
- ' This function is slow.',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_partialmethod_undoc_members(app):
- expected = [
- '',
- '.. py:class:: Cell',
- ' :module: target.partialmethod',
- '',
- ' An example for partialmethod.',
- '',
- ' refs: https://docs.python.jp/3/library/functools.html#functools.partialmethod',
- '',
- '',
- ' .. py:method:: Cell.set_alive()',
- ' :module: target.partialmethod',
- '',
- ' Make a cell alive.',
- '',
- '',
- ' .. py:method:: Cell.set_dead()',
- ' :module: target.partialmethod',
- '',
- '',
- ' .. py:method:: Cell.set_state(state)',
- ' :module: target.partialmethod',
- '',
- ' Update state of cell to *state*.',
- '',
- ]
-
- options = {"members": None,
- "undoc-members": None}
- actual = do_autodoc(app, 'class', 'target.partialmethod.Cell', options)
- assert list(actual) == expected
-
-
-@pytest.mark.skipif(sys.version_info < (3, 6), reason='py36+ is available since python3.6.')
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_typed_instance_variables(app):
- options = {"members": None,
- "undoc-members": True}
- actual = do_autodoc(app, 'module', 'target.typed_vars', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.typed_vars',
- '',
- '',
- '.. py:class:: Class()',
- ' :module: target.typed_vars',
- '',
- '',
- ' .. py:attribute:: Class.attr1',
- ' :module: target.typed_vars',
- ' :type: int',
- ' :value: 0',
- '',
- '',
- ' .. py:attribute:: Class.attr2',
- ' :module: target.typed_vars',
- ' :type: int',
- '',
- '',
- ' .. py:attribute:: Class.attr3',
- ' :module: target.typed_vars',
- ' :type: int',
- ' :value: 0',
- '',
- '',
- ' .. py:attribute:: Class.attr4',
- ' :module: target.typed_vars',
- ' :type: int',
- '',
- ' attr4',
- '',
- '',
- ' .. py:attribute:: Class.attr5',
- ' :module: target.typed_vars',
- ' :type: int',
- '',
- ' attr5',
- '',
- '',
- ' .. py:attribute:: Class.attr6',
- ' :module: target.typed_vars',
- ' :type: int',
- '',
- ' attr6',
- '',
- '',
- ' .. py:attribute:: Class.descr4',
- ' :module: target.typed_vars',
- ' :type: int',
- '',
- ' This is descr4',
- '',
- '',
- '.. py:data:: attr1',
- ' :module: target.typed_vars',
- ' :type: str',
- " :value: ''",
- '',
- ' attr1',
- '',
- '',
- '.. py:data:: attr2',
- ' :module: target.typed_vars',
- ' :type: str',
- '',
- ' attr2',
- '',
- '',
- '.. py:data:: attr3',
- ' :module: target.typed_vars',
- ' :type: str',
- " :value: ''",
- '',
- ' attr3',
- '',
- ]
-
-
-@pytest.mark.skipif(sys.version_info < (3, 9), reason='py39+ is required.')
-@pytest.mark.sphinx('html', testroot='ext-autodoc')
-def test_autodoc_Annotated(app):
- options = {"members": None}
- actual = do_autodoc(app, 'module', 'target.annotated', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.annotated',
- '',
- '',
- '.. py:function:: hello(name: str) -> None',
- ' :module: target.annotated',
- '',
- ' docstring',
- '',
- ]
-
-
-@pytest.mark.sphinx('html', testroot='pycode-egg')
-def test_autodoc_for_egged_code(app):
- options = {"members": None,
- "undoc-members": None}
- actual = do_autodoc(app, 'module', 'sample', options)
- assert list(actual) == [
- '',
- '.. py:module:: sample',
- '',
- '',
- '.. py:data:: CONSTANT',
- ' :module: sample',
- ' :value: 1',
- '',
- ' constant on sample.py',
- '',
- '',
- '.. py:function:: hello(s)',
- ' :module: sample',
- ''
- ]
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_singledispatch():
- options = {"members": None}
- actual = do_autodoc(app, 'module', 'target.singledispatch', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.singledispatch',
- '',
- '',
- '.. py:function:: func(arg, kwarg=None)',
- ' func(arg: int, kwarg=None)',
- ' func(arg: str, kwarg=None)',
- ' :module: target.singledispatch',
- '',
- ' A function for general use.',
- '',
- ]
-
-
-@pytest.mark.usefixtures('setup_test')
-def test_singledispatch_autofunction():
- options = {}
- actual = do_autodoc(app, 'function', 'target.singledispatch.func', options)
- assert list(actual) == [
- '',
- '.. py:function:: func(arg, kwarg=None)',
- ' func(arg: int, kwarg=None)',
- ' func(arg: str, kwarg=None)',
- ' :module: target.singledispatch',
- '',
- ' A function for general use.',
- '',
- ]
-
-@pytest.mark.skipif(sys.version_info < (3, 8),
- reason='singledispatchmethod is available since python3.8')
-@pytest.mark.usefixtures('setup_test')
-def test_singledispatchmethod():
- options = {"members": None}
- actual = do_autodoc(app, 'module', 'target.singledispatchmethod', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.singledispatchmethod',
- '',
- '',
- '.. py:class:: Foo',
- ' :module: target.singledispatchmethod',
- '',
- ' docstring',
- '',
- '',
- ' .. py:method:: Foo.meth(arg, kwarg=None)',
- ' Foo.meth(arg: int, kwarg=None)',
- ' Foo.meth(arg: str, kwarg=None)',
- ' :module: target.singledispatchmethod',
- '',
- ' A method for general use.',
- '',
- ]
-
-
-@pytest.mark.skipif(sys.version_info < (3, 8),
- reason='singledispatchmethod is available since python3.8')
-@pytest.mark.usefixtures('setup_test')
-def test_singledispatchmethod_automethod():
- options = {}
- actual = do_autodoc(app, 'method', 'target.singledispatchmethod.Foo.meth', options)
- assert list(actual) == [
- '',
- '.. py:method:: Foo.meth(arg, kwarg=None)',
- ' Foo.meth(arg: int, kwarg=None)',
- ' Foo.meth(arg: str, kwarg=None)',
- ' :module: target.singledispatchmethod',
- '',
- ' A method for general use.',
- '',
- ]
-
-@pytest.mark.usefixtures('setup_test')
-@pytest.mark.skipif(pyximport is None, reason='cython is not installed')
-def test_cython():
- options = {"members": None,
- "undoc-members": None}
- actual = do_autodoc(app, 'module', 'target.cython', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.cython',
- '',
- '',
- '.. py:class:: Class',
- ' :module: target.cython',
- '',
- ' Docstring.',
- '',
- '',
- ' .. py:method:: Class.meth(name: str, age: int = 0) -> None',
- ' :module: target.cython',
- '',
- ' Docstring.',
- '',
- '',
- '.. py:function:: foo(x: int, *args, y: str, **kwargs)',
- ' :module: target.cython',
- '',
- ' Docstring.',
- '',
- ]
-
-
-@pytest.mark.skipif(sys.version_info < (3, 8),
- reason='typing.final is available since python3.8')
-@pytest.mark.usefixtures('setup_test')
-def test_final():
- options = {"members": None}
- actual = do_autodoc(app, 'module', 'target.final', options)
- assert list(actual) == [
- '',
- '.. py:module:: target.final',
- '',
- '',
- '.. py:class:: Class',
- ' :module: target.final',
- ' :final:',
- '',
- ' docstring',
- '',
- '',
- ' .. py:method:: Class.meth1()',
- ' :module: target.final',
- ' :final:',
- '',
- ' docstring',
- '',
- '',
- ' .. py:method:: Class.meth2()',
- ' :module: target.final',
- '',
- ' docstring',
- '',
- ]
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index 11fb20414..6888fc52a 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -10,7 +10,6 @@
import os
import re
-from hashlib import md5
from itertools import cycle, chain
import pytest
@@ -19,6 +18,7 @@ from html5lib import HTMLParser
from sphinx.builders.html import validate_html_extra_path, validate_html_static_path
from sphinx.errors import ConfigError
from sphinx.testing.util import strip_escseq
+from sphinx.util import md5
from sphinx.util.inventory import InventoryFile
diff --git a/tests/test_domain_c.py b/tests/test_domain_c.py
index 237519fcc..795e8ed37 100644
--- a/tests/test_domain_c.py
+++ b/tests/test_domain_c.py
@@ -27,15 +27,29 @@ def parse(name, string):
return ast
-def _check(name, input, idDict, output):
+def _check(name, input, idDict, output, key, asTextOutput):
+ if key is None:
+ key = name
+ key += ' '
+ if name in ('function', 'member'):
+ inputActual = input
+ outputAst = output
+ outputAsText = output
+ else:
+ inputActual = input.format(key='')
+ outputAst = output.format(key='')
+ outputAsText = output.format(key=key)
+ if asTextOutput is not None:
+ outputAsText = asTextOutput
+
# first a simple check of the AST
- ast = parse(name, input)
+ ast = parse(name, inputActual)
res = str(ast)
- if res != output:
+ if res != outputAst:
print("")
print("Input: ", input)
print("Result: ", res)
- print("Expected: ", output)
+ print("Expected: ", outputAst)
raise DefinitionError("")
rootSymbol = Symbol(None, None, None, None)
symbol = rootSymbol.add_declaration(ast, docname="TestDoc")
@@ -43,6 +57,13 @@ def _check(name, input, idDict, output):
signode = addnodes.desc_signature(input, '')
parentNode += signode
ast.describe_signature(signode, 'lastIsName', symbol, options={})
+ resAsText = parentNode.astext()
+ if resAsText != outputAsText:
+ print("")
+ print("Input: ", input)
+ print("astext(): ", resAsText)
+ print("Expected: ", outputAsText)
+ raise DefinitionError("")
idExpected = [None]
for i in range(1, _max_id + 1):
@@ -75,14 +96,15 @@ def _check(name, input, idDict, output):
raise DefinitionError("")
-def check(name, input, idDict, output=None):
+def check(name, input, idDict, output=None, key=None, asTextOutput=None):
if output is None:
output = input
# First, check without semicolon
- _check(name, input, idDict, output)
+ _check(name, input, idDict, output, key, asTextOutput)
if name != 'macro':
# Second, check with semicolon
- _check(name, input + ' ;', idDict, output + ';')
+ _check(name, input + ' ;', idDict, output + ';', key,
+ asTextOutput + ';' if asTextOutput is not None else None)
def test_expressions():
@@ -234,24 +256,24 @@ def test_expressions():
def test_type_definitions():
- check('type', "T", {1: "T"})
+ check('type', "{key}T", {1: "T"})
- check('type', "bool *b", {1: 'b'})
- check('type', "bool *const b", {1: 'b'})
- check('type', "bool *const *b", {1: 'b'})
- check('type', "bool *volatile *b", {1: 'b'})
- check('type', "bool *restrict *b", {1: 'b'})
- check('type', "bool *volatile const b", {1: 'b'})
- check('type', "bool *volatile const b", {1: 'b'})
- check('type', "bool *volatile const *b", {1: 'b'})
- check('type', "bool b[]", {1: 'b'})
- check('type', "long long int foo", {1: 'foo'})
+ check('type', "{key}bool *b", {1: 'b'}, key='typedef')
+ check('type', "{key}bool *const b", {1: 'b'}, key='typedef')
+ check('type', "{key}bool *const *b", {1: 'b'}, key='typedef')
+ check('type', "{key}bool *volatile *b", {1: 'b'}, key='typedef')
+ check('type', "{key}bool *restrict *b", {1: 'b'}, key='typedef')
+ check('type', "{key}bool *volatile const b", {1: 'b'}, key='typedef')
+ check('type', "{key}bool *volatile const b", {1: 'b'}, key='typedef')
+ check('type', "{key}bool *volatile const *b", {1: 'b'}, key='typedef')
+ check('type', "{key}bool b[]", {1: 'b'}, key='typedef')
+ check('type', "{key}long long int foo", {1: 'foo'}, key='typedef')
# test decl specs on right
- check('type', "bool const b", {1: 'b'})
+ check('type', "{key}bool const b", {1: 'b'}, key='typedef')
# from breathe#267 (named function parameters for function pointers
- check('type', 'void (*gpio_callback_t)(struct device *port, uint32_t pin)',
- {1: 'gpio_callback_t'})
+ check('type', '{key}void (*gpio_callback_t)(struct device *port, uint32_t pin)',
+ {1: 'gpio_callback_t'}, key='typedef')
def test_macro_definitions():
@@ -378,28 +400,34 @@ def test_function_definitions():
output='void f(int arr[static volatile const 42])')
-def test_union_definitions():
- check('struct', 'A', {1: 'A'})
+class test_nested_name():
+ check('struct', '{key}.A', {1: "A"})
+ check('struct', '{key}.A.B', {1: "A.B"})
+ check('function', 'void f(.A a)', {1: "f"})
+ check('function', 'void f(.A.B a)', {1: "f"})
def test_union_definitions():
- check('union', 'A', {1: 'A'})
+ check('struct', '{key}A', {1: 'A'})
+
+
+def test_union_definitions():
+ check('union', '{key}A', {1: 'A'})
def test_enum_definitions():
- check('enum', 'A', {1: 'A'})
+ check('enum', '{key}A', {1: 'A'})
- check('enumerator', 'A', {1: 'A'})
- check('enumerator', 'A = 42', {1: 'A'})
+ check('enumerator', '{key}A', {1: 'A'})
+ check('enumerator', '{key}A = 42', {1: 'A'})
def test_anon_definitions():
- return # TODO
- check('class', '@a', {3: "Ut1_a"})
- check('union', '@a', {3: "Ut1_a"})
- check('enum', '@a', {3: "Ut1_a"})
- check('class', '@1', {3: "Ut1_1"})
- check('class', '@a::A', {3: "NUt1_a1AE"})
+ check('struct', '@a', {1: "@a"}, asTextOutput='struct [anonymous]')
+ check('union', '@a', {1: "@a"}, asTextOutput='union [anonymous]')
+ check('enum', '@a', {1: "@a"}, asTextOutput='enum [anonymous]')
+ check('struct', '@1', {1: "@1"}, asTextOutput='struct [anonymous]')
+ check('struct', '@a.A', {1: "@a.A"}, asTextOutput='struct [anonymous].A')
def test_initializers():
diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py
index 87b08e8ab..4de08030c 100644
--- a/tests/test_domain_cpp.py
+++ b/tests/test_domain_cpp.py
@@ -32,15 +32,29 @@ def parse(name, string):
return ast
-def _check(name, input, idDict, output):
+def _check(name, input, idDict, output, key, asTextOutput):
+ if key is None:
+ key = name
+ key += ' '
+ if name in ('function', 'member'):
+ inputActual = input
+ outputAst = output
+ outputAsText = output
+ else:
+ inputActual = input.format(key='')
+ outputAst = output.format(key='')
+ outputAsText = output.format(key=key)
+ if asTextOutput is not None:
+ outputAsText = asTextOutput
+
# first a simple check of the AST
- ast = parse(name, input)
+ ast = parse(name, inputActual)
res = str(ast)
- if res != output:
+ if res != outputAst:
print("")
print("Input: ", input)
print("Result: ", res)
- print("Expected: ", output)
+ print("Expected: ", outputAst)
raise DefinitionError("")
rootSymbol = Symbol(None, None, None, None, None, None)
symbol = rootSymbol.add_declaration(ast, docname="TestDoc")
@@ -48,6 +62,13 @@ def _check(name, input, idDict, output):
signode = addnodes.desc_signature(input, '')
parentNode += signode
ast.describe_signature(signode, 'lastIsName', symbol, options={})
+ resAsText = parentNode.astext()
+ if resAsText != outputAsText:
+ print("")
+ print("Input: ", input)
+ print("astext(): ", resAsText)
+ print("Expected: ", outputAsText)
+ raise DefinitionError("")
idExpected = [None]
for i in range(1, _max_id + 1):
@@ -80,13 +101,14 @@ def _check(name, input, idDict, output):
raise DefinitionError("")
-def check(name, input, idDict, output=None):
+def check(name, input, idDict, output=None, key=None, asTextOutput=None):
if output is None:
output = input
# First, check without semicolon
- _check(name, input, idDict, output)
+ _check(name, input, idDict, output, key, asTextOutput)
# Second, check with semicolon
- _check(name, input + ' ;', idDict, output + ';')
+ _check(name, input + ' ;', idDict, output + ';', key,
+ asTextOutput + ';' if asTextOutput is not None else None)
def test_fundamental_types():
@@ -112,10 +134,11 @@ def test_fundamental_types():
def test_expressions():
def exprCheck(expr, id, id4=None):
ids = 'IE1CIA%s_1aE'
- idDict = {2: ids % expr, 3: ids % id}
+ # call .format() on the expr to unescape double curly braces
+ idDict = {2: ids % expr.format(), 3: ids % id}
if id4 is not None:
idDict[4] = ids % id4
- check('class', 'template<> C' % expr, idDict)
+ check('class', 'template<> {key}C' % expr, idDict)
class Config:
cpp_id_attributes = ["id_attr"]
@@ -228,8 +251,8 @@ def test_expressions():
exprCheck('new int()', 'nw_ipiE')
exprCheck('new int(5, 42)', 'nw_ipiL5EL42EE')
exprCheck('::new int', 'nw_iE')
- exprCheck('new int{}', 'nw_iilE')
- exprCheck('new int{5, 42}', 'nw_iilL5EL42EE')
+ exprCheck('new int{{}}', 'nw_iilE')
+ exprCheck('new int{{5, 42}}', 'nw_iilL5EL42EE')
# delete-expression
exprCheck('delete p', 'dl1p')
exprCheck('delete [] p', 'da1p')
@@ -290,7 +313,7 @@ def test_expressions():
exprCheck('a xor_eq 5', 'eO1aL5E')
exprCheck('a |= 5', 'oR1aL5E')
exprCheck('a or_eq 5', 'oR1aL5E')
- exprCheck('a = {1, 2, 3}', 'aS1ailL1EL2EL3EE')
+ exprCheck('a = {{1, 2, 3}}', 'aS1ailL1EL2EL3EE')
# comma operator
exprCheck('a, 5', 'cm1aL5E')
@@ -300,8 +323,8 @@ def test_expressions():
check('function', 'template<> void f(A &v)',
{2: "IE1fR1AI1BX2EE", 3: "IE1fR1AI1BXL2EEE", 4: "IE1fvR1AI1BXL2EEE"})
exprCheck('A<1>::value', 'N1AIXL1EEE5valueE')
- check('class', "template A", {2: "I_iE1A"})
- check('enumerator', 'A = std::numeric_limits::max()', {2: "1A"})
+ check('class', "template {key}A", {2: "I_iE1A"})
+ check('enumerator', '{key}A = std::numeric_limits::max()', {2: "1A"})
exprCheck('operator()()', 'clclE')
exprCheck('operator()()', 'clclIiEE')
@@ -311,58 +334,59 @@ def test_expressions():
def test_type_definitions():
- check("type", "public bool b", {1: "b", 2: "1b"}, "bool b")
- check("type", "bool A::b", {1: "A::b", 2: "N1A1bE"})
- check("type", "bool *b", {1: "b", 2: "1b"})
- check("type", "bool *const b", {1: "b", 2: "1b"})
- check("type", "bool *volatile const b", {1: "b", 2: "1b"})
- check("type", "bool *volatile const b", {1: "b", 2: "1b"})
- check("type", "bool *volatile const *b", {1: "b", 2: "1b"})
- check("type", "bool &b", {1: "b", 2: "1b"})
- check("type", "bool b[]", {1: "b", 2: "1b"})
- check("type", "std::pair coord", {1: "coord", 2: "5coord"})
- check("type", "long long int foo", {1: "foo", 2: "3foo"})
- check("type", 'std::vector> module::blah',
- {1: "module::blah", 2: "N6module4blahE"})
- check("type", "std::function F", {1: "F", 2: "1F"})
- check("type", "std::function F", {1: "F", 2: "1F"})
- check("type", "std::function F", {1: "F", 2: "1F"})
- check("type", "std::function F", {1: "F", 2: "1F"})
- check("type", "MyContainer::const_iterator",
+ check("type", "public bool b", {1: "b", 2: "1b"}, "{key}bool b", key='typedef')
+ check("type", "{key}bool A::b", {1: "A::b", 2: "N1A1bE"}, key='typedef')
+ check("type", "{key}bool *b", {1: "b", 2: "1b"}, key='typedef')
+ check("type", "{key}bool *const b", {1: "b", 2: "1b"}, key='typedef')
+ check("type", "{key}bool *volatile const b", {1: "b", 2: "1b"}, key='typedef')
+ check("type", "{key}bool *volatile const b", {1: "b", 2: "1b"}, key='typedef')
+ check("type", "{key}bool *volatile const *b", {1: "b", 2: "1b"}, key='typedef')
+ check("type", "{key}bool &b", {1: "b", 2: "1b"}, key='typedef')
+ check("type", "{key}bool b[]", {1: "b", 2: "1b"}, key='typedef')
+ check("type", "{key}std::pair coord", {1: "coord", 2: "5coord"}, key='typedef')
+ check("type", "{key}long long int foo", {1: "foo", 2: "3foo"}, key='typedef')
+ check("type", '{key}std::vector> module::blah',
+ {1: "module::blah", 2: "N6module4blahE"}, key='typedef')
+ check("type", "{key}std::function F", {1: "F", 2: "1F"}, key='typedef')
+ check("type", "{key}std::function F", {1: "F", 2: "1F"}, key='typedef')
+ check("type", "{key}std::function F", {1: "F", 2: "1F"}, key='typedef')
+ check("type", "{key}std::function F", {1: "F", 2: "1F"}, key='typedef')
+ check("type", "{key}MyContainer::const_iterator",
{1: "MyContainer::const_iterator", 2: "N11MyContainer14const_iteratorE"})
check("type",
"public MyContainer::const_iterator",
{1: "MyContainer::const_iterator", 2: "N11MyContainer14const_iteratorE"},
- output="MyContainer::const_iterator")
+ output="{key}MyContainer::const_iterator")
# test decl specs on right
- check("type", "bool const b", {1: "b", 2: "1b"})
+ check("type", "{key}bool const b", {1: "b", 2: "1b"}, key='typedef')
# test name in global scope
- check("type", "bool ::B::b", {1: "B::b", 2: "N1B1bE"})
+ check("type", "{key}bool ::B::b", {1: "B::b", 2: "N1B1bE"}, key='typedef')
- check('type', 'A = B', {2: '1A'})
- check('type', 'A = decltype(b)', {2: '1A'})
+ check('type', '{key}A = B', {2: '1A'}, key='using')
+ check('type', '{key}A = decltype(b)', {2: '1A'}, key='using')
# from breathe#267 (named function parameters for function pointers
- check('type', 'void (*gpio_callback_t)(struct device *port, uint32_t pin)',
- {1: 'gpio_callback_t', 2: '15gpio_callback_t'})
- check('type', 'void (*f)(std::function g)', {1: 'f', 2: '1f'})
+ check('type', '{key}void (*gpio_callback_t)(struct device *port, uint32_t pin)',
+ {1: 'gpio_callback_t', 2: '15gpio_callback_t'}, key='typedef')
+ check('type', '{key}void (*f)(std::function g)', {1: 'f', 2: '1f'},
+ key='typedef')
- check('type', 'T = A::template B::template C', {2: '1T'})
+ check('type', '{key}T = A::template B::template C', {2: '1T'}, key='using')
- check('type', 'T = Q', {2: '1T'})
- check('type', 'T = Q>', {2: '1T'})
- check('type', 'T = Q', {2: '1T'})
+ check('type', '{key}T = Q', {2: '1T'}, key='using')
+ check('type', '{key}T = Q>', {2: '1T'}, key='using')
+ check('type', '{key}T = Q', {2: '1T'}, key='using')
def test_concept_definitions():
- check('concept', 'template A::B::Concept',
+ check('concept', 'template {key}A::B::Concept',
{2: 'I0EN1A1B7ConceptE'})
- check('concept', 'template Foo',
+ check('concept', 'template {key}Foo',
{2: 'I00DpE3Foo'})
with pytest.raises(DefinitionError):
- parse('concept', 'Foo')
+ parse('concept', '{key}Foo')
with pytest.raises(DefinitionError):
- parse('concept', 'template template Foo')
+ parse('concept', 'template template {key}Foo')
def test_member_definitions():
@@ -638,95 +662,102 @@ def test_operators():
check('function', 'void operator[]()', {1: "subscript-operator", 2: "ixv"})
+class test_nested_name():
+ check('class', '{key}::A', {1: "A", 2: "1A"})
+ check('class', '{key}::A::B', {1: "A::B", 2: "N1A1BE"})
+ check('function', 'void f(::A a)', {1: "f__A", 2: "1f1A"})
+ check('function', 'void f(::A::B a)', {1: "f__A::B", 2: "1fN1A1BE"})
+
+
def test_class_definitions():
- check('class', 'public A', {1: "A", 2: "1A"}, output='A')
- check('class', 'private A', {1: "A", 2: "1A"})
- check('class', 'A final', {1: 'A', 2: '1A'})
+ check('class', 'public A', {1: "A", 2: "1A"}, output='{key}A')
+ check('class', 'private {key}A', {1: "A", 2: "1A"})
+ check('class', '{key}A final', {1: 'A', 2: '1A'})
# test bases
- check('class', 'A', {1: "A", 2: "1A"})
- check('class', 'A::B::C', {1: "A::B::C", 2: "N1A1B1CE"})
- check('class', 'A : B', {1: "A", 2: "1A"})
- check('class', 'A : private B', {1: "A", 2: "1A"})
- check('class', 'A : public B', {1: "A", 2: "1A"})
- check('class', 'A : B, C', {1: "A", 2: "1A"})
- check('class', 'A : B, protected C, D', {1: "A", 2: "1A"})
- check('class', 'A : virtual private B', {1: 'A', 2: '1A'}, output='A : private virtual B')
- check('class', 'A : private virtual B', {1: 'A', 2: '1A'})
- check('class', 'A : B, virtual C', {1: 'A', 2: '1A'})
- check('class', 'A : public virtual B', {1: 'A', 2: '1A'})
- check('class', 'A : B, C...', {1: 'A', 2: '1A'})
- check('class', 'A : B..., C', {1: 'A', 2: '1A'})
+ check('class', '{key}A', {1: "A", 2: "1A"})
+ check('class', '{key}A::B::C', {1: "A::B::C", 2: "N1A1B1CE"})
+ check('class', '{key}A : B', {1: "A", 2: "1A"})
+ check('class', '{key}A : private B', {1: "A", 2: "1A"})
+ check('class', '{key}A : public B', {1: "A", 2: "1A"})
+ check('class', '{key}A : B, C', {1: "A", 2: "1A"})
+ check('class', '{key}A : B, protected C, D', {1: "A", 2: "1A"})
+ check('class', 'A : virtual private B', {1: 'A', 2: '1A'}, output='{key}A : private virtual B')
+ check('class', '{key}A : private virtual B', {1: 'A', 2: '1A'})
+ check('class', '{key}A : B, virtual C', {1: 'A', 2: '1A'})
+ check('class', '{key}A : public virtual B', {1: 'A', 2: '1A'})
+ check('class', '{key}A : B, C...', {1: 'A', 2: '1A'})
+ check('class', '{key}A : B..., C', {1: 'A', 2: '1A'})
# from #4094
- check('class', 'template> has_var', {2: 'I00E7has_var'})
- check('class', 'template has_var>',
+ check('class', 'template> {key}has_var', {2: 'I00E7has_var'})
+ check('class', 'template {key}has_var>',
{2: 'I0E7has_varI1TNSt6void_tIDTadN1T3varEEEEE'})
- check('class', 'template T',
+ check('class', 'template {key}T',
{2: 'IDpE1TIJPFi2TsEEE'})
- check('class', 'template T<(Is)...>',
+ check('class', 'template {key}T<(Is)...>',
{2: 'I_DpiE1TIJX(Is)EEE', 3: 'I_DpiE1TIJX2IsEEE'})
def test_union_definitions():
- check('union', 'A', {2: "1A"})
+ check('union', '{key}A', {2: "1A"})
def test_enum_definitions():
- check('enum', 'A', {2: "1A"})
- check('enum', 'A : std::underlying_type::type', {2: "1A"})
- check('enum', 'A : unsigned int', {2: "1A"})
- check('enum', 'public A', {2: "1A"}, output='A')
- check('enum', 'private A', {2: "1A"})
+ check('enum', '{key}A', {2: "1A"})
+ check('enum', '{key}A : std::underlying_type::type', {2: "1A"})
+ check('enum', '{key}A : unsigned int', {2: "1A"})
+ check('enum', 'public A', {2: "1A"}, output='{key}A')
+ check('enum', 'private {key}A', {2: "1A"})
- check('enumerator', 'A', {2: "1A"})
- check('enumerator', 'A = std::numeric_limits::max()', {2: "1A"})
+ check('enumerator', '{key}A', {2: "1A"})
+ check('enumerator', '{key}A = std::numeric_limits::max()', {2: "1A"})
def test_anon_definitions():
- check('class', '@a', {3: "Ut1_a"})
- check('union', '@a', {3: "Ut1_a"})
- check('enum', '@a', {3: "Ut1_a"})
- check('class', '@1', {3: "Ut1_1"})
- check('class', '@a::A', {3: "NUt1_a1AE"})
+ check('class', '@a', {3: "Ut1_a"}, asTextOutput='class [anonymous]')
+ check('union', '@a', {3: "Ut1_a"}, asTextOutput='union [anonymous]')
+ check('enum', '@a', {3: "Ut1_a"}, asTextOutput='enum [anonymous]')
+ check('class', '@1', {3: "Ut1_1"}, asTextOutput='class [anonymous]')
+ check('class', '@a::A', {3: "NUt1_a1AE"}, asTextOutput='class [anonymous]::A')
def test_templates():
- check('class', "A", {2: "IE1AI1TE"}, output="template<> A")
+ check('class', "A", {2: "IE1AI1TE"}, output="template<> {key}A")
# first just check which objects support templating
- check('class', "template<> A", {2: "IE1A"})
+ check('class', "template<> {key}A", {2: "IE1A"})
check('function', "template<> void A()", {2: "IE1Av", 4: "IE1Avv"})
check('member', "template<> A a", {2: "IE1a"})
- check('type', "template<> a = A", {2: "IE1a"})
+ check('type', "template<> {key}a = A", {2: "IE1a"}, key='using')
with pytest.raises(DefinitionError):
parse('enum', "template<> A")
with pytest.raises(DefinitionError):
parse('enumerator', "template<> A")
# then all the real tests
- check('class', "template A", {2: "I00E1A"})
- check('type', "template<> a", {2: "IE1a"})
+ check('class', "template {key}A", {2: "I00E1A"})
+ check('type', "template<> {key}a", {2: "IE1a"}, key='using')
- check('class', "template A", {2: "I0E1A"})
- check('class', "template A", {2: "I0E1A"})
- check('class', "template A", {2: "IDpE1A"})
- check('class', "template A", {2: "IDpE1A"})
- check('class', "template A", {2: "I0E1A"})
- check('class', "template A", {2: "I0E1A"})
+ check('class', "template {key}A", {2: "I0E1A"})
+ check('class', "template {key}A", {2: "I0E1A"})
+ check('class', "template {key}A", {2: "IDpE1A"})
+ check('class', "template {key}A", {2: "IDpE1A"})
+ check('class', "template {key}A", {2: "I0E1A"})
+ check('class', "template {key}A", {2: "I0E1A"})
- check('class', "template typename T> A", {2: "II0E0E1A"})
- check('class', "template typename> A", {2: "II0E0E1A"})
- check('class', "template typename ...T> A", {2: "II0EDpE1A"})
- check('class', "template typename...> A", {2: "II0EDpE1A"})
+ check('class', "template typename T> {key}A", {2: "II0E0E1A"})
+ check('class', "template typename> {key}A", {2: "II0E0E1A"})
+ check('class', "template typename ...T> {key}A", {2: "II0EDpE1A"})
+ check('class', "template typename...> {key}A", {2: "II0EDpE1A"})
- check('class', "template A", {2: "I_iE1A"})
- check('class', "template A", {2: "I_iE1A"})
- check('class', "template A", {2: "I_DpiE1A"})
- check('class', "template A", {2: "I_iE1A"})
- check('class', "template A", {2: "I_iE1A"})
+ check('class', "template {key}A", {2: "I_iE1A"})
+ check('class', "template {key}A", {2: "I_iE1A"})
+ check('class', "template {key}A", {2: "I_DpiE1A"})
+ check('class', "template {key}A", {2: "I_iE1A"})
+ check('class', "template {key}A", {2: "I_iE1A"})
- check('class', "template<> A>", {2: "IE1AIN2NS1BIEEE"})
+ check('class', "template<> {key}A>", {2: "IE1AIN2NS1BIEEE"})
# from #2058
check('function',
@@ -746,21 +777,21 @@ def test_templates():
parse('enum', 'abc::ns::foo{id_0, id_1, id_2} A')
with pytest.raises(DefinitionError):
parse('enumerator', 'abc::ns::foo{id_0, id_1, id_2} A')
- check('class', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar',
+ check('class', 'abc::ns::foo{{id_0, id_1, id_2}} {key}xyz::bar',
{2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
- check('class', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar',
+ check('class', 'abc::ns::foo{{id_0, id_1, ...id_2}} {key}xyz::bar',
{2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
- check('class', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar',
+ check('class', 'abc::ns::foo{{id_0, id_1, id_2}} {key}xyz::bar',
{2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barI4id_04id_14id_2EE'})
- check('class', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar',
+ check('class', 'abc::ns::foo{{id_0, id_1, ...id_2}} {key}xyz::bar',
{2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barI4id_04id_1Dp4id_2EE'})
- check('class', 'template<> Concept{U} A::B', {2: 'IEI0EX7ConceptI1UEEN1AIiE1BE'})
+ check('class', 'template<> Concept{{U}} {key}A::B', {2: 'IEI0EX7ConceptI1UEEN1AIiE1BE'})
- check('type', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar = ghi::qux',
- {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
- check('type', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar = ghi::qux',
- {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
+ check('type', 'abc::ns::foo{{id_0, id_1, id_2}} {key}xyz::bar = ghi::qux',
+ {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'}, key='using')
+ check('type', 'abc::ns::foo{{id_0, id_1, ...id_2}} {key}xyz::bar = ghi::qux',
+ {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'}, key='using')
check('function', 'abc::ns::foo{id_0, id_1, id_2} void xyz::bar()',
{2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barEv',
4: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barEvv'})
@@ -771,8 +802,8 @@ def test_templates():
{2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
check('member', 'abc::ns::foo{id_0, id_1, ...id_2} ghi::qux xyz::bar',
{2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
- check('concept', 'Iterator{T, U} Another', {2: 'I00EX8IteratorI1T1UEE7Another'})
- check('concept', 'template Numerics = (... && Numeric)',
+ check('concept', 'Iterator{{T, U}} {key}Another', {2: 'I00EX8IteratorI1T1UEE7Another'})
+ check('concept', 'template {key}Numerics = (... && Numeric)',
{2: 'IDpE8Numerics'})
# explicit specializations of members
@@ -784,7 +815,7 @@ def test_templates():
output='template<> template<> int A::B::b') # same as above
# defaulted constrained type parameters
- check('type', 'template A', {2: 'I_1CE1A'})
+ check('type', 'template {key}A', {2: 'I_1CE1A'}, key='using')
def test_template_args():
@@ -796,9 +827,10 @@ def test_template_args():
3: "I0E5allowP1FN4funcI1F1BXne1GL1EEE4typeE",
4: "I0E5allowvP1FN4funcI1F1BXne1GL1EEE4typeE"})
# from #3542
- check('type', "template "
+ check('type', "template {key}"
"enable_if_not_array_t = std::enable_if_t::value, int>",
- {2: "I0E21enable_if_not_array_t"})
+ {2: "I0E21enable_if_not_array_t"},
+ key='using')
def test_initializers():
diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py
index 6f91323a6..653ab1cd4 100644
--- a/tests/test_domain_py.py
+++ b/tests/test_domain_py.py
@@ -40,22 +40,22 @@ def parse(sig):
def test_function_signatures():
rv = parse('func(a=1) -> int object')
- assert rv == 'a=1'
+ assert rv == '(a=1)'
rv = parse('func(a=1, [b=None])')
- assert rv == 'a=1, [b=None]'
+ assert rv == '(a=1, [b=None])'
rv = parse('func(a=1[, b=None])')
- assert rv == 'a=1, [b=None]'
+ assert rv == '(a=1, [b=None])'
rv = parse("compile(source : string, filename, symbol='file')")
- assert rv == "source : string, filename, symbol='file'"
+ assert rv == "(source : string, filename, symbol='file')"
rv = parse('func(a=[], [b=None])')
- assert rv == 'a=[], [b=None]'
+ assert rv == '(a=[], [b=None])'
rv = parse('func(a=[][, b=None])')
- assert rv == 'a=[], [b=None]'
+ assert rv == '(a=[], [b=None])'
@pytest.mark.sphinx('dummy', testroot='domain-py')
@@ -422,7 +422,8 @@ def test_pydata_signature(app):
doctree = restructuredtext.parse(app, text)
assert_node(doctree, (addnodes.index,
[desc, ([desc_signature, ([desc_name, "version"],
- [desc_annotation, ": int"],
+ [desc_annotation, (": ",
+ [pending_xref, "int"])],
[desc_annotation, " = 1"])],
desc_content)]))
assert_node(doctree[1], addnodes.desc, desctype="data",
@@ -454,8 +455,8 @@ def test_pyobject_prefix(app):
desc,
addnodes.index,
desc)])]))
- assert doctree[1][1][1].astext().strip() == 'say' # prefix is stripped
- assert doctree[1][1][3].astext().strip() == 'FooBar.say' # not stripped
+ assert doctree[1][1][1].astext().strip() == 'say()' # prefix is stripped
+ assert doctree[1][1][3].astext().strip() == 'FooBar.say()' # not stripped
def test_pydata(app):
@@ -692,7 +693,8 @@ def test_pyattribute(app):
assert_node(doctree[1][1][0], addnodes.index,
entries=[('single', 'attr (Class attribute)', 'Class.attr', '', None)])
assert_node(doctree[1][1][1], ([desc_signature, ([desc_name, "attr"],
- [desc_annotation, ": str"],
+ [desc_annotation, (": ",
+ [pending_xref, "str"])],
[desc_annotation, " = ''"])],
[desc_content, ()]))
assert 'Class.attr' in domain.objects
diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py
index 69846d3ae..4ed4a9b05 100644
--- a/tests/test_ext_autodoc.py
+++ b/tests/test_ext_autodoc.py
@@ -2,15 +2,1795 @@
test_autodoc
~~~~~~~~~~~~
- Test the autodoc extension.
+ Test the autodoc extension. This tests mainly the Documenters; the auto
+ directives are tested in a test source file translated by test_build.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
+import sys
+from unittest.mock import Mock
+from warnings import catch_warnings
+
import pytest
+from docutils.statemachine import ViewList
from sphinx import addnodes
+from sphinx.ext.autodoc import ModuleLevelDocumenter, ALL, Options
+from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options
+from sphinx.testing.util import SphinxTestApp, Struct # NOQA
+from sphinx.util.docutils import LoggingReporter
+
+try:
+ # Enable pyximport to test cython module
+ import pyximport
+ pyximport.install()
+except ImportError:
+ pyximport = None
+
+
+def do_autodoc(app, objtype, name, options=None):
+ if options is None:
+ options = {}
+ app.env.temp_data.setdefault('docname', 'index') # set dummy docname
+ doccls = app.registry.documenters[objtype]
+ docoptions = process_documenter_options(doccls, app.config, options)
+ state = Mock()
+ state.document.settings.tab_width = 8
+ bridge = DocumenterBridge(app.env, LoggingReporter(''), docoptions, 1, state)
+ documenter = doccls(bridge, name)
+ documenter.generate()
+
+ return bridge.result
+
+
+def make_directive_bridge(env):
+ options = Options(
+ inherited_members = False,
+ undoc_members = False,
+ private_members = False,
+ special_members = False,
+ imported_members = False,
+ show_inheritance = False,
+ noindex = False,
+ annotation = None,
+ synopsis = '',
+ platform = '',
+ deprecated = False,
+ members = [],
+ member_order = 'alphabetical',
+ exclude_members = set(),
+ ignore_module_all = False,
+ )
+
+ directive = Struct(
+ env = env,
+ genopt = options,
+ result = ViewList(),
+ filename_set = set(),
+ state = Mock(),
+ )
+ directive.state.document.settings.tab_width = 8
+
+ return directive
+
+
+processed_signatures = []
+
+
+def process_signature(app, what, name, obj, options, args, retann):
+ processed_signatures.append((what, name))
+ if name == 'bar':
+ return '42', None
+
+
+def skip_member(app, what, name, obj, skip, options):
+ if name in ('__special1__', '__special2__'):
+ return skip
+ if name.startswith('__'):
+ return True
+ if name == 'skipmeth':
+ return True
+
+
+def test_parse_name(app):
+ def verify(objtype, name, result):
+ inst = app.registry.documenters[objtype](directive, name)
+ assert inst.parse_name()
+ assert (inst.modname, inst.objpath, inst.args, inst.retann) == result
+
+ directive = make_directive_bridge(app.env)
+
+ # for modules
+ verify('module', 'test_ext_autodoc', ('test_ext_autodoc', [], None, None))
+ verify('module', 'test.test_ext_autodoc', ('test.test_ext_autodoc', [], None, None))
+ verify('module', 'test(arg)', ('test', [], 'arg', None))
+ assert 'signature arguments' in app._warning.getvalue()
+
+ # for functions/classes
+ verify('function', 'test_ext_autodoc.raises',
+ ('test_ext_autodoc', ['raises'], None, None))
+ verify('function', 'test_ext_autodoc.raises(exc) -> None',
+ ('test_ext_autodoc', ['raises'], 'exc', 'None'))
+ directive.env.temp_data['autodoc:module'] = 'test_ext_autodoc'
+ verify('function', 'raises', ('test_ext_autodoc', ['raises'], None, None))
+ del directive.env.temp_data['autodoc:module']
+ directive.env.ref_context['py:module'] = 'test_ext_autodoc'
+ verify('function', 'raises', ('test_ext_autodoc', ['raises'], None, None))
+ verify('class', 'Base', ('test_ext_autodoc', ['Base'], None, None))
+
+ # for members
+ directive.env.ref_context['py:module'] = 'foo'
+ verify('method', 'util.SphinxTestApp.cleanup',
+ ('foo', ['util', 'SphinxTestApp', 'cleanup'], None, None))
+ directive.env.ref_context['py:module'] = 'util'
+ directive.env.ref_context['py:class'] = 'Foo'
+ directive.env.temp_data['autodoc:class'] = 'SphinxTestApp'
+ verify('method', 'cleanup', ('util', ['SphinxTestApp', 'cleanup'], None, None))
+ verify('method', 'SphinxTestApp.cleanup',
+ ('util', ['SphinxTestApp', 'cleanup'], None, None))
+
+
+def test_format_signature(app):
+ app.connect('autodoc-process-signature', process_signature)
+ app.connect('autodoc-skip-member', skip_member)
+
+ directive = make_directive_bridge(app.env)
+
+ def formatsig(objtype, name, obj, args, retann):
+ inst = app.registry.documenters[objtype](directive, name)
+ inst.fullname = name
+ inst.doc_as_attr = False # for class objtype
+ inst.parent = object # dummy
+ inst.object = obj
+ inst.objpath = [name]
+ inst.args = args
+ inst.retann = retann
+ res = inst.format_signature()
+ print(res)
+ return res
+
+ # no signatures for modules
+ assert formatsig('module', 'test', None, None, None) == ''
+
+ # test for functions
+ def f(a, b, c=1, **d):
+ pass
+
+ def g(a='\n'):
+ pass
+ assert formatsig('function', 'f', f, None, None) == '(a, b, c=1, **d)'
+ assert formatsig('function', 'f', f, 'a, b, c, d', None) == '(a, b, c, d)'
+ assert formatsig('function', 'f', f, None, 'None') == '(a, b, c=1, **d) -> None'
+ assert formatsig('function', 'g', g, None, None) == r"(a='\n')"
+
+ # test for classes
+ class D:
+ pass
+
+ class E:
+ pass
+ # no signature for classes without __init__
+ for C in (D, E):
+ assert formatsig('class', 'D', C, None, None) == ''
+
+ class F:
+ def __init__(self, a, b=None):
+ pass
+
+ class G(F):
+ pass
+ for C in (F, G):
+ assert formatsig('class', 'C', C, None, None) == '(a, b=None)'
+ assert formatsig('class', 'C', D, 'a, b', 'X') == '(a, b) -> X'
+
+ # __init__ have signature at first line of docstring
+ directive.env.config.autoclass_content = 'both'
+
+ class F2:
+ '''some docstring for F2.'''
+ def __init__(self, *args, **kw):
+ '''
+ __init__(a1, a2, kw1=True, kw2=False)
+
+ some docstring for __init__.
+ '''
+ class G2(F2):
+ pass
+
+ assert formatsig('class', 'F2', F2, None, None) == \
+ '(a1, a2, kw1=True, kw2=False)'
+ assert formatsig('class', 'G2', G2, None, None) == \
+ '(a1, a2, kw1=True, kw2=False)'
+
+ # test for methods
+ class H:
+ def foo1(self, b, *c):
+ pass
+
+ def foo2(b, *c):
+ pass
+
+ def foo3(self, d='\n'):
+ pass
+ assert formatsig('method', 'H.foo', H.foo1, None, None) == '(b, *c)'
+ assert formatsig('method', 'H.foo', H.foo1, 'a', None) == '(a)'
+ assert formatsig('method', 'H.foo', H.foo2, None, None) == '(*c)'
+ assert formatsig('method', 'H.foo', H.foo3, None, None) == r"(d='\n')"
+
+ # test bound methods interpreted as functions
+ assert formatsig('function', 'foo', H().foo1, None, None) == '(b, *c)'
+ assert formatsig('function', 'foo', H().foo2, None, None) == '(*c)'
+ assert formatsig('function', 'foo', H().foo3, None, None) == r"(d='\n')"
+
+ # test exception handling (exception is caught and args is '')
+ directive.env.config.autodoc_docstring_signature = False
+ assert formatsig('function', 'int', int, None, None) == ''
+
+ # test processing by event handler
+ assert formatsig('method', 'bar', H.foo1, None, None) == '42'
+
+ # test functions created via functools.partial
+ from functools import partial
+ curried1 = partial(lambda a, b, c: None, 'A')
+ assert formatsig('function', 'curried1', curried1, None, None) == \
+ '(b, c)'
+ curried2 = partial(lambda a, b, c=42: None, 'A')
+ assert formatsig('function', 'curried2', curried2, None, None) == \
+ '(b, c=42)'
+ curried3 = partial(lambda a, b, *c: None, 'A')
+ assert formatsig('function', 'curried3', curried3, None, None) == \
+ '(b, *c)'
+ curried4 = partial(lambda a, b, c=42, *d, **e: None, 'A')
+ assert formatsig('function', 'curried4', curried4, None, None) == \
+ '(b, c=42, *d, **e)'
+
+
+def test_get_doc(app):
+ directive = make_directive_bridge(app.env)
+
+ def getdocl(objtype, obj):
+ inst = app.registry.documenters[objtype](directive, 'tmp')
+ inst.parent = object # dummy
+ inst.object = obj
+ inst.objpath = [obj.__name__]
+ inst.doc_as_attr = False
+ inst.format_signature() # handle docstring signatures!
+ ds = inst.get_doc()
+ # for testing purposes, concat them and strip the empty line at the end
+ res = sum(ds, [])[:-1]
+ print(res)
+ return res
+
+ # objects without docstring
+ def f():
+ pass
+ assert getdocl('function', f) == []
+
+ # standard function, diverse docstring styles...
+ def f():
+ """Docstring"""
+ def g():
+ """
+ Docstring
+ """
+ for func in (f, g):
+ assert getdocl('function', func) == ['Docstring']
+
+ # first line vs. other lines indentation
+ def f():
+ """First line
+
+ Other
+ lines
+ """
+ assert getdocl('function', f) == ['First line', '', 'Other', ' lines']
+
+ # charset guessing (this module is encoded in utf-8)
+ def f():
+ """Döcstring"""
+ assert getdocl('function', f) == ['Döcstring']
+
+ # already-unicode docstrings must be taken literally
+ def f():
+ """Döcstring"""
+ assert getdocl('function', f) == ['Döcstring']
+
+ # verify that method docstrings get extracted in both normal case
+ # and in case of bound method posing as a function
+ class J: # NOQA
+ def foo(self):
+ """Method docstring"""
+ assert getdocl('method', J.foo) == ['Method docstring']
+ assert getdocl('function', J().foo) == ['Method docstring']
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_new_documenter(app):
+ class MyDocumenter(ModuleLevelDocumenter):
+ objtype = 'integer'
+ directivetype = 'integer'
+ priority = 100
+
+ @classmethod
+ def can_document_member(cls, member, membername, isattr, parent):
+ return isinstance(member, int)
+
+ def document_members(self, all_members=False):
+ return
+
+ app.add_autodocumenter(MyDocumenter)
+
+ options = {"members": 'integer'}
+ actual = do_autodoc(app, 'module', 'target', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target',
+ '',
+ '',
+ '.. py:integer:: integer',
+ ' :module: target',
+ '',
+ ' documentation for the integer',
+ '',
+ ]
+
+
+def test_attrgetter_using(app):
+ from target import Class
+ from target.inheritance import Derived
+
+ directive = make_directive_bridge(app.env)
+
+ def assert_getter_works(objtype, name, obj, attrs=[], **kw):
+ getattr_spy = []
+
+ def special_getattr(obj, name, *defargs):
+ if name in attrs:
+ getattr_spy.append((obj, name))
+ return None
+ return getattr(obj, name, *defargs)
+ app.add_autodoc_attrgetter(type, special_getattr)
+
+ del getattr_spy[:]
+ inst = app.registry.documenters[objtype](directive, name)
+ inst.generate(**kw)
+
+ hooked_members = [s[1] for s in getattr_spy]
+ documented_members = [s[1] for s in processed_signatures]
+ for attr in attrs:
+ fullname = '.'.join((name, attr))
+ assert attr in hooked_members
+ assert fullname not in documented_members, \
+ '%r was not hooked by special_attrgetter function' % fullname
+
+ with catch_warnings(record=True):
+ directive.genopt['members'] = ALL
+ directive.genopt['inherited_members'] = False
+ print(directive.genopt)
+ assert_getter_works('class', 'target.Class', Class, ['meth'])
+
+ directive.genopt['inherited_members'] = True
+ assert_getter_works('class', 'target.inheritance.Derived', Derived, ['inheritedmeth'])
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_py_module(app, warning):
+ # without py:module
+ actual = do_autodoc(app, 'method', 'Class.meth')
+ assert list(actual) == []
+ assert ("don't know which module to import for autodocumenting 'Class.meth'"
+ in warning.getvalue())
+
+ # with py:module
+ app.env.ref_context['py:module'] = 'target'
+ warning.truncate(0)
+
+ actual = do_autodoc(app, 'method', 'Class.meth')
+ assert list(actual) == [
+ '',
+ '.. py:method:: Class.meth()',
+ ' :module: target',
+ '',
+ ' Function.',
+ '',
+ ]
+ assert ("don't know which module to import for autodocumenting 'Class.meth'"
+ not in warning.getvalue())
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_decorator(app):
+ actual = do_autodoc(app, 'decorator', 'target.decorator.deco1')
+ assert list(actual) == [
+ '',
+ '.. py:decorator:: deco1',
+ ' :module: target.decorator',
+ '',
+ ' docstring for deco1',
+ '',
+ ]
+
+ actual = do_autodoc(app, 'decorator', 'target.decorator.deco2')
+ assert list(actual) == [
+ '',
+ '.. py:decorator:: deco2(condition, message)',
+ ' :module: target.decorator',
+ '',
+ ' docstring for deco2',
+ '',
+ ]
+
+
+@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.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_warnings(app, warning):
+ app.env.temp_data['docname'] = 'dummy'
+
+ # can't import module
+ do_autodoc(app, 'module', 'unknown')
+ assert "failed to import module 'unknown'" in warning.getvalue()
+
+ # 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.inheritance.Base')
+ assert list(filter(lambda l: '::' in l, actual)) == [
+ '.. py:class:: Base',
+ ]
+
+ # default ALL-members
+ options = {"members": None}
+ actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
+ assert list(filter(lambda l: '::' in l, actual)) == [
+ '.. py:class:: Base',
+ ' .. py:method:: Base.inheritedclassmeth()',
+ ' .. py:method:: Base.inheritedmeth()',
+ ' .. py:method:: Base.inheritedstaticmeth(cls)'
+ ]
+
+ # default specific-members
+ options = {"members": "inheritedmeth,inheritedstaticmeth"}
+ actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
+ assert list(filter(lambda l: '::' in l, actual)) == [
+ '.. py:class:: Base',
+ ' .. py:method:: Base.inheritedmeth()',
+ ' .. py:method:: 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.inheritance.Base', options)
+ assert list(filter(lambda l: '::' in l, actual)) == [
+ '.. py:class:: Base',
+ ' .. py:method:: Base.inheritedclassmeth()'
+ ]
+
+ # members vs exclude-members
+ options = {"members": "inheritedmeth",
+ "exclude-members": "inheritedmeth"}
+ actual = do_autodoc(app, 'class', 'target.inheritance.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.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:method:: Class.moore(a, e, f) -> happiness',
+ ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
+ ' .. 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.inheritance.Derived', options)
+ assert list(filter(lambda l: 'method::' in l, actual)) == [
+ ' .. py:method:: Derived.inheritedclassmeth()',
+ ' .. py:method:: Derived.inheritedmeth()',
+ ' .. py:method:: Derived.inheritedstaticmeth(cls)',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_inherited_members_Base(app):
+ options = {"members": None,
+ "inherited-members": "Base",
+ "special-members": None}
+
+ # check methods for object class are shown
+ actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
+ assert ' .. py:method:: Derived.inheritedmeth()' in actual
+ assert ' .. py:method:: Derived.inheritedclassmeth' not in actual
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_inherited_members_None(app):
+ options = {"members": None,
+ "inherited-members": "None",
+ "special-members": None}
+
+ # check methods for object class are shown
+ actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
+ assert ' .. py:method:: Derived.__init__()' in actual
+ assert ' .. py:method:: Derived.__str__()' in actual
+
+
+@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:: save_traceback(app: Sphinx) -> str' in actual
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+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
+ 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:attribute:: Class.__dict__',
+ ' .. py:method:: Class.__init__(arg)',
+ ' .. py:attribute:: Class.__module__',
+ ' .. py:method:: Class.__special1__()',
+ ' .. py:method:: Class.__special2__()',
+ ' .. py:attribute:: Class.__weakref__',
+ ' .. py:attribute:: Class.attr',
+ ' .. 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:method:: Class.moore(a, e, f) -> happiness',
+ ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
+ ' .. 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:: CustomDict',
+ '.. py:class:: InnerChild',
+ '.. py:class:: InstAttCls()',
+ '.. py:class:: Outer',
+ ' .. py:class:: Outer.Inner',
+ '.. py:class:: StrRepr'
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_noindex(app):
+ options = {"noindex": True}
+ actual = do_autodoc(app, 'module', 'target', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target',
+ ' :noindex:',
+ ''
+ ]
+
+ # TODO: :noindex: should be propagated to children of target item.
+
+ actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: Base',
+ ' :noindex:',
+ ' :module: target.inheritance',
+ ''
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_subclass_of_builtin_class(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'class', 'target.CustomDict', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: CustomDict',
+ ' :module: target',
+ '',
+ ' Docstring.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_inner_class(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'class', 'target.Outer', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: Outer',
+ ' :module: target',
+ '',
+ ' Foo',
+ '',
+ '',
+ ' .. py:class:: Outer.Inner',
+ ' :module: target',
+ '',
+ ' Foo',
+ '',
+ '',
+ ' .. py:method:: Outer.Inner.meth()',
+ ' :module: target',
+ '',
+ ' Foo',
+ '',
+ '',
+ ' .. py:attribute:: Outer.factory',
+ ' :module: target',
+ '',
+ ' alias of :class:`builtins.dict`'
+ ]
+
+ actual = do_autodoc(app, 'class', 'target.Outer.Inner', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: Outer.Inner',
+ ' :module: target',
+ '',
+ ' Foo',
+ '',
+ '',
+ ' .. py:method:: Outer.Inner.meth()',
+ ' :module: target',
+ '',
+ ' Foo',
+ '',
+ ]
+
+ options['show-inheritance'] = True
+ actual = do_autodoc(app, 'class', 'target.InnerChild', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: InnerChild',
+ ' :module: target', '',
+ ' Bases: :class:`target.Outer.Inner`',
+ '',
+ ' InnerChild docstring',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_classmethod(app):
+ actual = do_autodoc(app, 'method', 'target.inheritance.Base.inheritedclassmeth')
+ assert list(actual) == [
+ '',
+ '.. py:method:: Base.inheritedclassmeth()',
+ ' :module: target.inheritance',
+ ' :classmethod:',
+ '',
+ ' Inherited class method.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_staticmethod(app):
+ actual = do_autodoc(app, 'method', 'target.inheritance.Base.inheritedstaticmeth')
+ assert list(actual) == [
+ '',
+ '.. py:method:: Base.inheritedstaticmeth(cls)',
+ ' :module: target.inheritance',
+ ' :staticmethod:',
+ '',
+ ' Inherited static method.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_descriptor(app):
+ options = {"members": None,
+ "undoc-members": True}
+ actual = do_autodoc(app, 'class', 'target.descriptor.Class', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: Class',
+ ' :module: target.descriptor',
+ '',
+ '',
+ ' .. py:attribute:: Class.descr',
+ ' :module: target.descriptor',
+ '',
+ ' Descriptor instance docstring.',
+ '',
+ '',
+ ' .. py:method:: Class.prop',
+ ' :module: target.descriptor',
+ ' :property:',
+ '',
+ ' Property.',
+ ''
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_c_module(app):
+ actual = do_autodoc(app, 'function', 'time.asctime')
+ assert list(actual) == [
+ '',
+ '.. py:function:: asctime([tuple]) -> string',
+ ' :module: time',
+ '',
+ " Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.",
+ ' When the time tuple is not present, current time as returned by localtime()',
+ ' is used.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_member_order(app):
+ # case member-order='bysource'
+ options = {"members": None,
+ 'member-order': 'bysource',
+ "undoc-members": True,
+ 'private-members': True}
+ actual = do_autodoc(app, 'class', 'target.Class', options)
+ assert list(filter(lambda l: '::' in l, actual)) == [
+ '.. py:class:: Class(arg)',
+ ' .. py:method:: Class.meth()',
+ ' .. py:method:: Class.undocmeth()',
+ ' .. py:method:: Class.skipmeth()',
+ ' .. py:method:: Class.excludemeth()',
+ ' .. py:attribute:: Class.skipattr',
+ ' .. py:attribute:: Class.attr',
+ ' .. py:attribute:: Class.docattr',
+ ' .. py:attribute:: Class.udocattr',
+ ' .. py:attribute:: Class.mdocattr',
+ ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
+ ' .. py:method:: Class.moore(a, e, f) -> happiness',
+ ' .. py:attribute:: Class.inst_attr_inline',
+ ' .. py:attribute:: Class.inst_attr_comment',
+ ' .. py:attribute:: Class.inst_attr_string',
+ ' .. py:attribute:: Class._private_inst_attr'
+ ]
+
+ # case member-order='groupwise'
+ options = {"members": None,
+ 'member-order': 'groupwise',
+ "undoc-members": True,
+ 'private-members': True}
+ actual = do_autodoc(app, 'class', 'target.Class', options)
+ assert list(filter(lambda l: '::' in l, actual)) == [
+ '.. py:class:: Class(arg)',
+ ' .. py:method:: Class.excludemeth()',
+ ' .. py:method:: Class.meth()',
+ ' .. py:method:: Class.moore(a, e, f) -> happiness',
+ ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
+ ' .. py:method:: Class.skipmeth()',
+ ' .. py:method:: Class.undocmeth()',
+ ' .. py:attribute:: Class._private_inst_attr',
+ ' .. py:attribute:: Class.attr',
+ ' .. py:attribute:: Class.docattr',
+ ' .. py:attribute:: Class.inst_attr_comment',
+ ' .. py:attribute:: Class.inst_attr_inline',
+ ' .. py:attribute:: Class.inst_attr_string',
+ ' .. py:attribute:: Class.mdocattr',
+ ' .. py:attribute:: Class.skipattr',
+ ' .. py:attribute:: Class.udocattr'
+ ]
+
+ # case member-order=None
+ options = {"members": None,
+ "undoc-members": True,
+ 'private-members': True}
+ actual = do_autodoc(app, 'class', 'target.Class', options)
+ assert list(filter(lambda l: '::' in l, actual)) == [
+ '.. py:class:: Class(arg)',
+ ' .. py:attribute:: Class._private_inst_attr',
+ ' .. py:attribute:: Class.attr',
+ ' .. 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:method:: Class.moore(a, e, f) -> happiness',
+ ' .. py:method:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)',
+ ' .. 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_module_scope(app):
+ app.env.temp_data['autodoc:module'] = 'target'
+ actual = do_autodoc(app, 'attribute', 'Class.mdocattr')
+ assert list(actual) == [
+ '',
+ '.. py:attribute:: Class.mdocattr',
+ ' :module: target',
+ ' :value: <_io.StringIO object>',
+ '',
+ ' should be documented as well - süß',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_class_scope(app):
+ app.env.temp_data['autodoc:module'] = 'target'
+ app.env.temp_data['autodoc:class'] = 'Class'
+ actual = do_autodoc(app, 'attribute', 'mdocattr')
+ assert list(actual) == [
+ '',
+ '.. py:attribute:: Class.mdocattr',
+ ' :module: target',
+ ' :value: <_io.StringIO object>',
+ '',
+ ' should be documented as well - süß',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_class_attributes(app):
+ options = {"members": None,
+ "undoc-members": True}
+ actual = do_autodoc(app, 'class', 'target.AttCls', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: AttCls',
+ ' :module: target',
+ '',
+ '',
+ ' .. py:attribute:: AttCls.a1',
+ ' :module: target',
+ ' :value: hello world',
+ '',
+ '',
+ ' .. py:attribute:: AttCls.a2',
+ ' :module: target',
+ ' :value: None',
+ ''
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_instance_attributes(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'class', 'target.InstAttCls', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: InstAttCls()',
+ ' :module: target',
+ '',
+ ' Class with documented class and instance attributes.',
+ '',
+ '',
+ ' .. py:attribute:: InstAttCls.ca1',
+ ' :module: target',
+ " :value: 'a'",
+ '',
+ ' Doc comment for class attribute InstAttCls.ca1.',
+ ' It can have multiple lines.',
+ '',
+ '',
+ ' .. py:attribute:: InstAttCls.ca2',
+ ' :module: target',
+ " :value: 'b'",
+ '',
+ ' Doc comment for InstAttCls.ca2. One line only.',
+ '',
+ '',
+ ' .. py:attribute:: InstAttCls.ca3',
+ ' :module: target',
+ " :value: 'c'",
+ '',
+ ' Docstring for class attribute InstAttCls.ca3.',
+ '',
+ '',
+ ' .. py:attribute:: InstAttCls.ia1',
+ ' :module: target',
+ '',
+ ' Doc comment for instance attribute InstAttCls.ia1',
+ '',
+ '',
+ ' .. py:attribute:: InstAttCls.ia2',
+ ' :module: target',
+ '',
+ ' Docstring for instance attribute InstAttCls.ia2.',
+ ''
+ ]
+
+ # pick up arbitrary attributes
+ options = {"members": 'ca1,ia1'}
+ actual = do_autodoc(app, 'class', 'target.InstAttCls', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: InstAttCls()',
+ ' :module: target',
+ '',
+ ' Class with documented class and instance attributes.',
+ '',
+ '',
+ ' .. py:attribute:: InstAttCls.ca1',
+ ' :module: target',
+ " :value: 'a'",
+ '',
+ ' Doc comment for class attribute InstAttCls.ca1.',
+ ' It can have multiple lines.',
+ '',
+ '',
+ ' .. py:attribute:: InstAttCls.ia1',
+ ' :module: target',
+ '',
+ ' Doc comment for instance attribute InstAttCls.ia1',
+ ''
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_slots(app):
+ options = {"members": None,
+ "undoc-members": True}
+ actual = do_autodoc(app, 'module', 'target.slots', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.slots',
+ '',
+ '',
+ '.. py:class:: Bar()',
+ ' :module: target.slots',
+ '',
+ '',
+ ' .. py:attribute:: Bar.attr1',
+ ' :module: target.slots',
+ '',
+ ' docstring of attr1',
+ '',
+ '',
+ ' .. py:attribute:: Bar.attr2',
+ ' :module: target.slots',
+ '',
+ ' docstring of instance attr2',
+ '',
+ '',
+ ' .. py:attribute:: Bar.attr3',
+ ' :module: target.slots',
+ '',
+ '',
+ '.. py:class:: Foo',
+ ' :module: target.slots',
+ '',
+ '',
+ ' .. py:attribute:: Foo.attr',
+ ' :module: target.slots',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_enum_class(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'class', 'target.enum.EnumCls', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: EnumCls',
+ ' :module: target.enum',
+ '',
+ ' this is enum class',
+ '',
+ '',
+ ' .. py:method:: EnumCls.say_goodbye()',
+ ' :module: target.enum',
+ ' :classmethod:',
+ '',
+ ' a classmethod says good-bye to you.',
+ '',
+ '',
+ ' .. py:method:: EnumCls.say_hello()',
+ ' :module: target.enum',
+ '',
+ ' a method says hello to you.',
+ '',
+ '',
+ ' .. py:attribute:: EnumCls.val1',
+ ' :module: target.enum',
+ ' :value: 12',
+ '',
+ ' doc for val1',
+ '',
+ '',
+ ' .. py:attribute:: EnumCls.val2',
+ ' :module: target.enum',
+ ' :value: 23',
+ '',
+ ' doc for val2',
+ '',
+ '',
+ ' .. py:attribute:: EnumCls.val3',
+ ' :module: target.enum',
+ ' :value: 34',
+ '',
+ ' doc for val3',
+ '',
+ ]
+
+ # checks for an attribute of EnumClass
+ actual = do_autodoc(app, 'attribute', 'target.enum.EnumCls.val1')
+ assert list(actual) == [
+ '',
+ '.. py:attribute:: EnumCls.val1',
+ ' :module: target.enum',
+ ' :value: 12',
+ '',
+ ' doc for val1',
+ ''
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_descriptor_class(app):
+ options = {"members": 'CustomDataDescriptor,CustomDataDescriptor2'}
+ actual = do_autodoc(app, 'module', 'target.descriptor', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.descriptor',
+ '',
+ '',
+ '.. py:class:: CustomDataDescriptor(doc)',
+ ' :module: target.descriptor',
+ '',
+ ' Descriptor class docstring.',
+ '',
+ '',
+ ' .. py:method:: CustomDataDescriptor.meth()',
+ ' :module: target.descriptor',
+ '',
+ ' Function.',
+ '',
+ '',
+ '.. py:class:: CustomDataDescriptor2(doc)',
+ ' :module: target.descriptor',
+ '',
+ ' Descriptor class with custom metaclass docstring.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autofunction_for_classes(app):
+ actual = do_autodoc(app, 'function', 'target.classes.Foo')
+ assert list(actual) == [
+ '',
+ '.. py:function:: Foo()',
+ ' :module: target.classes',
+ '',
+ ]
+
+ actual = do_autodoc(app, 'function', 'target.classes.Bar')
+ assert list(actual) == [
+ '',
+ '.. py:function:: Bar(x, y)',
+ ' :module: target.classes',
+ '',
+ ]
+
+ actual = do_autodoc(app, 'function', 'target.classes.Baz')
+ assert list(actual) == [
+ '',
+ '.. py:function:: Baz(x, y)',
+ ' :module: target.classes',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autofunction_for_callable(app):
+ actual = do_autodoc(app, 'function', 'target.callable.function')
+ assert list(actual) == [
+ '',
+ '.. py:function:: function(arg1, arg2, **kwargs)',
+ ' :module: target.callable',
+ '',
+ ' A callable object that behaves like a function.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autofunction_for_method(app):
+ actual = do_autodoc(app, 'function', 'target.callable.method')
+ assert list(actual) == [
+ '',
+ '.. py:function:: method(arg1, arg2)',
+ ' :module: target.callable',
+ '',
+ ' docstring of Callable.method().',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autofunction_for_builtin(app):
+ actual = do_autodoc(app, 'function', 'os.umask')
+ assert list(actual) == [
+ '',
+ '.. py:function:: umask(mask, /)',
+ ' :module: os',
+ '',
+ ' Set the current numeric umask and return the previous umask.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autofunction_for_methoddescriptor(app):
+ actual = do_autodoc(app, 'function', 'builtins.int.__add__')
+ assert list(actual) == [
+ '',
+ '.. py:function:: int.__add__(self, value, /)',
+ ' :module: builtins',
+ '',
+ ' Return self+value.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autofunction_for_decorated(app):
+ actual = do_autodoc(app, 'function', 'target.decorator.foo')
+ assert list(actual) == [
+ '',
+ '.. py:function:: foo()',
+ ' :module: target.decorator',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_automethod_for_builtin(app):
+ actual = do_autodoc(app, 'method', 'builtins.int.__add__')
+ assert list(actual) == [
+ '',
+ '.. py:method:: int.__add__(value, /)',
+ ' :module: builtins',
+ '',
+ ' Return self+value.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_automethod_for_decorated(app):
+ actual = do_autodoc(app, 'method', 'target.decorator.Bar.meth')
+ assert list(actual) == [
+ '',
+ '.. py:method:: Bar.meth()',
+ ' :module: target.decorator',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_abstractmethods(app):
+ options = {"members": None,
+ "undoc-members": None}
+ actual = do_autodoc(app, 'module', 'target.abstractmethods', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.abstractmethods',
+ '',
+ '',
+ '.. py:class:: Base',
+ ' :module: target.abstractmethods',
+ '',
+ '',
+ ' .. py:method:: Base.abstractmeth()',
+ ' :module: target.abstractmethods',
+ ' :abstractmethod:',
+ '',
+ '',
+ ' .. py:method:: Base.classmeth()',
+ ' :module: target.abstractmethods',
+ ' :abstractmethod:',
+ ' :classmethod:',
+ '',
+ '',
+ ' .. py:method:: Base.coroutinemeth()',
+ ' :module: target.abstractmethods',
+ ' :abstractmethod:',
+ ' :async:',
+ '',
+ '',
+ ' .. py:method:: Base.meth()',
+ ' :module: target.abstractmethods',
+ '',
+ '',
+ ' .. py:method:: Base.prop',
+ ' :module: target.abstractmethods',
+ ' :abstractmethod:',
+ ' :property:',
+ '',
+ '',
+ ' .. py:method:: Base.staticmeth()',
+ ' :module: target.abstractmethods',
+ ' :abstractmethod:',
+ ' :staticmethod:',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_partialfunction(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'module', 'target.partialfunction', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.partialfunction',
+ '',
+ '',
+ '.. py:function:: func1(a, b, c)',
+ ' :module: target.partialfunction',
+ '',
+ ' docstring of func1',
+ '',
+ '',
+ '.. py:function:: func2(b, c)',
+ ' :module: target.partialfunction',
+ '',
+ ' docstring of func1',
+ '',
+ '',
+ '.. py:function:: func3(c)',
+ ' :module: target.partialfunction',
+ '',
+ ' docstring of func3',
+ '',
+ '',
+ '.. py:function:: func4()',
+ ' :module: target.partialfunction',
+ '',
+ ' docstring of func3',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_imported_partialfunction_should_not_shown_without_imported_members(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'module', 'target.imported_members', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.imported_members',
+ ''
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_bound_method(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'module', 'target.bound_method', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.bound_method',
+ '',
+ '',
+ '.. py:function:: bound_method()',
+ ' :module: target.bound_method',
+ '',
+ ' Method docstring',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_coroutine(app):
+ actual = do_autodoc(app, 'function', 'target.functions.coroutinefunc')
+ assert list(actual) == [
+ '',
+ '.. py:function:: coroutinefunc()',
+ ' :module: target.functions',
+ ' :async:',
+ '',
+ ]
+
+ options = {"members": None}
+ actual = do_autodoc(app, 'class', 'target.coroutine.AsyncClass', options)
+ assert list(actual) == [
+ '',
+ '.. py:class:: AsyncClass',
+ ' :module: target.coroutine',
+ '',
+ '',
+ ' .. py:method:: AsyncClass.do_coroutine()',
+ ' :module: target.coroutine',
+ ' :async:',
+ '',
+ ' A documented coroutine function',
+ '',
+ '',
+ ' .. py:method:: AsyncClass.do_coroutine2()',
+ ' :module: target.coroutine',
+ ' :async:',
+ ' :classmethod:',
+ '',
+ ' A documented coroutine classmethod',
+ '',
+ '',
+ ' .. py:method:: AsyncClass.do_coroutine3()',
+ ' :module: target.coroutine',
+ ' :async:',
+ ' :staticmethod:',
+ '',
+ ' A documented coroutine staticmethod',
+ '',
+ ]
+
+ # force-synchronized wrapper
+ actual = do_autodoc(app, 'function', 'target.coroutine.sync_func')
+ assert list(actual) == [
+ '',
+ '.. py:function:: sync_func(*args, **kwargs)',
+ ' :module: target.coroutine',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_partialmethod(app):
+ expected = [
+ '',
+ '.. py:class:: Cell',
+ ' :module: target.partialmethod',
+ '',
+ ' An example for partialmethod.',
+ '',
+ ' refs: https://docs.python.jp/3/library/functools.html#functools.partialmethod',
+ '',
+ '',
+ ' .. py:method:: Cell.set_alive()',
+ ' :module: target.partialmethod',
+ '',
+ ' Make a cell alive.',
+ '',
+ '',
+ ' .. py:method:: Cell.set_state(state)',
+ ' :module: target.partialmethod',
+ '',
+ ' Update state of cell to *state*.',
+ '',
+ ]
+
+ options = {"members": None}
+ actual = do_autodoc(app, 'class', 'target.partialmethod.Cell', options)
+ assert list(actual) == expected
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_wrappedfunction(app):
+ actual = do_autodoc(app, 'function', 'target.wrappedfunction.slow_function')
+ assert list(actual) == [
+ '',
+ '.. py:function:: slow_function(message, timeout)',
+ ' :module: target.wrappedfunction',
+ '',
+ ' This function is slow.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_partialmethod_undoc_members(app):
+ expected = [
+ '',
+ '.. py:class:: Cell',
+ ' :module: target.partialmethod',
+ '',
+ ' An example for partialmethod.',
+ '',
+ ' refs: https://docs.python.jp/3/library/functools.html#functools.partialmethod',
+ '',
+ '',
+ ' .. py:method:: Cell.set_alive()',
+ ' :module: target.partialmethod',
+ '',
+ ' Make a cell alive.',
+ '',
+ '',
+ ' .. py:method:: Cell.set_dead()',
+ ' :module: target.partialmethod',
+ '',
+ '',
+ ' .. py:method:: Cell.set_state(state)',
+ ' :module: target.partialmethod',
+ '',
+ ' Update state of cell to *state*.',
+ '',
+ ]
+
+ options = {"members": None,
+ "undoc-members": None}
+ actual = do_autodoc(app, 'class', 'target.partialmethod.Cell', options)
+ assert list(actual) == expected
+
+
+@pytest.mark.skipif(sys.version_info < (3, 6), reason='py36+ is available since python3.6.')
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_typed_instance_variables(app):
+ options = {"members": None,
+ "undoc-members": True}
+ actual = do_autodoc(app, 'module', 'target.typed_vars', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.typed_vars',
+ '',
+ '',
+ '.. py:class:: Class()',
+ ' :module: target.typed_vars',
+ '',
+ '',
+ ' .. py:attribute:: Class.attr1',
+ ' :module: target.typed_vars',
+ ' :type: int',
+ ' :value: 0',
+ '',
+ '',
+ ' .. py:attribute:: Class.attr2',
+ ' :module: target.typed_vars',
+ ' :type: int',
+ '',
+ '',
+ ' .. py:attribute:: Class.attr3',
+ ' :module: target.typed_vars',
+ ' :type: int',
+ ' :value: 0',
+ '',
+ '',
+ ' .. py:attribute:: Class.attr4',
+ ' :module: target.typed_vars',
+ ' :type: int',
+ '',
+ ' attr4',
+ '',
+ '',
+ ' .. py:attribute:: Class.attr5',
+ ' :module: target.typed_vars',
+ ' :type: int',
+ '',
+ ' attr5',
+ '',
+ '',
+ ' .. py:attribute:: Class.attr6',
+ ' :module: target.typed_vars',
+ ' :type: int',
+ '',
+ ' attr6',
+ '',
+ '',
+ ' .. py:attribute:: Class.descr4',
+ ' :module: target.typed_vars',
+ ' :type: int',
+ '',
+ ' This is descr4',
+ '',
+ '',
+ '.. py:data:: attr1',
+ ' :module: target.typed_vars',
+ ' :type: str',
+ " :value: ''",
+ '',
+ ' attr1',
+ '',
+ '',
+ '.. py:data:: attr2',
+ ' :module: target.typed_vars',
+ ' :type: str',
+ '',
+ ' attr2',
+ '',
+ '',
+ '.. py:data:: attr3',
+ ' :module: target.typed_vars',
+ ' :type: str',
+ " :value: ''",
+ '',
+ ' attr3',
+ '',
+ ]
+
+
+@pytest.mark.skipif(sys.version_info < (3, 9), reason='py39+ is required.')
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_autodoc_Annotated(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'module', 'target.annotated', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.annotated',
+ '',
+ '',
+ '.. py:function:: hello(name: str) -> None',
+ ' :module: target.annotated',
+ '',
+ ' docstring',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='pycode-egg')
+def test_autodoc_for_egged_code(app):
+ options = {"members": None,
+ "undoc-members": None}
+ actual = do_autodoc(app, 'module', 'sample', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: sample',
+ '',
+ '',
+ '.. py:data:: CONSTANT',
+ ' :module: sample',
+ ' :value: 1',
+ '',
+ ' constant on sample.py',
+ '',
+ '',
+ '.. py:function:: hello(s)',
+ ' :module: sample',
+ ''
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_singledispatch(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'module', 'target.singledispatch', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.singledispatch',
+ '',
+ '',
+ '.. py:function:: func(arg, kwarg=None)',
+ ' func(arg: int, kwarg=None)',
+ ' func(arg: str, kwarg=None)',
+ ' :module: target.singledispatch',
+ '',
+ ' A function for general use.',
+ '',
+ ]
+
+
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_singledispatch_autofunction(app):
+ options = {}
+ actual = do_autodoc(app, 'function', 'target.singledispatch.func', options)
+ assert list(actual) == [
+ '',
+ '.. py:function:: func(arg, kwarg=None)',
+ ' func(arg: int, kwarg=None)',
+ ' func(arg: str, kwarg=None)',
+ ' :module: target.singledispatch',
+ '',
+ ' A function for general use.',
+ '',
+ ]
+
+
+@pytest.mark.skipif(sys.version_info < (3, 8),
+ reason='singledispatchmethod is available since python3.8')
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_singledispatchmethod(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'module', 'target.singledispatchmethod', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.singledispatchmethod',
+ '',
+ '',
+ '.. py:class:: Foo',
+ ' :module: target.singledispatchmethod',
+ '',
+ ' docstring',
+ '',
+ '',
+ ' .. py:method:: Foo.meth(arg, kwarg=None)',
+ ' Foo.meth(arg: int, kwarg=None)',
+ ' Foo.meth(arg: str, kwarg=None)',
+ ' :module: target.singledispatchmethod',
+ '',
+ ' A method for general use.',
+ '',
+ ]
+
+
+@pytest.mark.skipif(sys.version_info < (3, 8),
+ reason='singledispatchmethod is available since python3.8')
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_singledispatchmethod_automethod(app):
+ options = {}
+ actual = do_autodoc(app, 'method', 'target.singledispatchmethod.Foo.meth', options)
+ assert list(actual) == [
+ '',
+ '.. py:method:: Foo.meth(arg, kwarg=None)',
+ ' Foo.meth(arg: int, kwarg=None)',
+ ' Foo.meth(arg: str, kwarg=None)',
+ ' :module: target.singledispatchmethod',
+ '',
+ ' A method for general use.',
+ '',
+ ]
+
+
+@pytest.mark.skipif(pyximport is None, reason='cython is not installed')
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_cython(app):
+ options = {"members": None,
+ "undoc-members": None}
+ actual = do_autodoc(app, 'module', 'target.cython', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.cython',
+ '',
+ '',
+ '.. py:class:: Class',
+ ' :module: target.cython',
+ '',
+ ' Docstring.',
+ '',
+ '',
+ ' .. py:method:: Class.meth(name: str, age: int = 0) -> None',
+ ' :module: target.cython',
+ '',
+ ' Docstring.',
+ '',
+ '',
+ '.. py:function:: foo(x: int, *args, y: str, **kwargs)',
+ ' :module: target.cython',
+ '',
+ ' Docstring.',
+ '',
+ ]
+
+
+@pytest.mark.skipif(sys.version_info < (3, 8),
+ reason='typing.final is available since python3.8')
+@pytest.mark.sphinx('html', testroot='ext-autodoc')
+def test_final(app):
+ options = {"members": None}
+ actual = do_autodoc(app, 'module', 'target.final', options)
+ assert list(actual) == [
+ '',
+ '.. py:module:: target.final',
+ '',
+ '',
+ '.. py:class:: Class',
+ ' :module: target.final',
+ ' :final:',
+ '',
+ ' docstring',
+ '',
+ '',
+ ' .. py:method:: Class.meth1()',
+ ' :module: target.final',
+ ' :final:',
+ '',
+ ' docstring',
+ '',
+ '',
+ ' .. py:method:: Class.meth2()',
+ ' :module: target.final',
+ '',
+ ' docstring',
+ '',
+ ]
@pytest.mark.sphinx('dummy', testroot='ext-autodoc')
@@ -19,7 +1799,7 @@ def test_autodoc(app, status, warning):
content = app.env.get_doctree('index')
assert isinstance(content[3], addnodes.desc)
- assert content[3][0].astext() == 'autodoc_dummy_module.test'
+ assert content[3][0].astext() == 'autodoc_dummy_module.test()'
assert content[3][1].astext() == 'Dummy function using dummy.*'
# issue sphinx-doc/sphinx#2437
diff --git a/tests/test_ext_autodoc_configs.py b/tests/test_ext_autodoc_configs.py
index d82666fb3..6821c6264 100644
--- a/tests/test_ext_autodoc_configs.py
+++ b/tests/test_ext_autodoc_configs.py
@@ -12,7 +12,7 @@ import platform
import pytest
-from test_autodoc import do_autodoc
+from test_ext_autodoc import do_autodoc
IS_PYPY = platform.python_implementation() == 'PyPy'
diff --git a/tests/test_ext_autodoc_events.py b/tests/test_ext_autodoc_events.py
index 106c5793a..4e8348abc 100644
--- a/tests/test_ext_autodoc_events.py
+++ b/tests/test_ext_autodoc_events.py
@@ -11,7 +11,7 @@
import pytest
from sphinx.ext.autodoc import between, cut_lines
-from test_autodoc import do_autodoc
+from test_ext_autodoc import do_autodoc
@pytest.mark.sphinx('html', testroot='ext-autodoc')
diff --git a/tests/test_ext_autodoc_private_members.py b/tests/test_ext_autodoc_private_members.py
index befcac396..f4cadd3a5 100644
--- a/tests/test_ext_autodoc_private_members.py
+++ b/tests/test_ext_autodoc_private_members.py
@@ -10,7 +10,7 @@
import pytest
-from test_autodoc import do_autodoc
+from test_ext_autodoc import do_autodoc
@pytest.mark.sphinx('html', testroot='ext-autodoc')
diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py
index f97840aa5..aa075a9e6 100644
--- a/tests/test_ext_autosummary.py
+++ b/tests/test_ext_autosummary.py
@@ -208,10 +208,11 @@ def test_autosummary_generate(app, status, warning):
nodes.row)])])
assert_node(doctree[4][0], addnodes.toctree, caption="An autosummary")
+ assert len(doctree[3][0][0][2]) == 4
assert doctree[3][0][0][2][0].astext() == 'autosummary_dummy_module\n\n'
assert doctree[3][0][0][2][1].astext() == 'autosummary_dummy_module.Foo()\n\n'
- assert doctree[3][0][0][2][2].astext() == 'autosummary_dummy_module.bar(x[, y])\n\n'
- assert doctree[3][0][0][2][3].astext() == 'autosummary_importfail\n\n'
+ assert doctree[3][0][0][2][2].astext() == 'autosummary_dummy_module.Foo.Bar\n\n'
+ assert doctree[3][0][0][2][3].astext() == 'autosummary_dummy_module.bar(x[, y])\n\n'
module = (app.srcdir / 'generated' / 'autosummary_dummy_module.rst').read_text()
assert (' .. autosummary::\n'
@@ -231,6 +232,11 @@ def test_autosummary_generate(app, status, warning):
' ~Foo.baz\n'
' \n' in Foo)
+ FooBar = (app.srcdir / 'generated' / 'autosummary_dummy_module.Foo.Bar.rst').read_text()
+ assert ('.. currentmodule:: autosummary_dummy_module\n'
+ '\n'
+ '.. autoclass:: Foo.Bar\n' in FooBar)
+
@pytest.mark.sphinx('dummy', testroot='ext-autosummary',
confoverrides={'autosummary_generate_overwrite': False})
@@ -390,7 +396,7 @@ def test_autosummary_template(app):
confoverrides={'autosummary_generate': []})
def test_empty_autosummary_generate(app, status, warning):
app.build()
- assert ("WARNING: autosummary: stub file not found 'autosummary_importfail'"
+ assert ("WARNING: autosummary: failed to import autosummary_importfail"
in warning.getvalue())
diff --git a/tests/test_markup.py b/tests/test_markup.py
index 1b41dc69a..5fb835605 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -13,7 +13,6 @@ import re
import pytest
from docutils import frontend, utils, nodes
from docutils.parsers.rst import Parser as RstParser
-from docutils.transforms.universal import SmartQuotes
from sphinx import addnodes
from sphinx.builders.html.transforms import KeyboardTransform
@@ -21,6 +20,8 @@ from sphinx.builders.latex import LaTeXBuilder
from sphinx.builders.latex.theming import ThemeFactory
from sphinx.roles import XRefRole
from sphinx.testing.util import Struct, assert_node
+from sphinx.transforms import SphinxSmartQuotes
+from sphinx.util import docutils
from sphinx.util import texescape
from sphinx.util.docutils import sphinx_domains
from sphinx.writers.html import HTMLWriter, HTMLTranslator
@@ -67,7 +68,7 @@ def parse(new_document):
document = new_document()
parser = RstParser()
parser.parse(rst, document)
- SmartQuotes(document, startnode=None).apply()
+ SphinxSmartQuotes(document, startnode=None).apply()
for msg in document.traverse(nodes.system_message):
if msg['level'] == 1:
msg.replace_self([])
@@ -349,6 +350,21 @@ def test_inline(get_verifier, type, rst, html_expected, latex_expected):
verifier(rst, html_expected, latex_expected)
+@pytest.mark.parametrize('type,rst,html_expected,latex_expected', [
+ (
+ 'verify',
+ r'4 backslashes \\\\',
+ r'4 backslashes \\
',
+ None,
+ ),
+])
+@pytest.mark.skipif(docutils.__version_info__ < (0, 16),
+ reason='docutils-0.16 or above is required')
+def test_inline_docutils16(get_verifier, type, rst, html_expected, latex_expected):
+ verifier = get_verifier(type)
+ verifier(rst, html_expected, latex_expected)
+
+
@pytest.mark.sphinx(confoverrides={'latex_engine': 'xelatex'})
@pytest.mark.parametrize('type,rst,html_expected,latex_expected', [
(
diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py
index 65070d6d1..4da61df47 100644
--- a/tests/test_util_inspect.py
+++ b/tests/test_util_inspect.py
@@ -18,7 +18,7 @@ from inspect import Parameter
import pytest
from sphinx.util import inspect
-from sphinx.util.inspect import stringify_signature
+from sphinx.util.inspect import stringify_signature, is_builtin_class_method
def test_signature():
@@ -30,10 +30,10 @@ def test_signature():
inspect.signature('')
# builitin classes
- with pytest.raises(TypeError):
+ with pytest.raises(ValueError):
inspect.signature(int)
- with pytest.raises(TypeError):
+ with pytest.raises(ValueError):
inspect.signature(str)
# normal function
@@ -97,7 +97,7 @@ def test_signature_methods():
# wrapped bound method
sig = inspect.signature(wrapped_bound_method)
- assert stringify_signature(sig) == '(arg1, **kwargs)'
+ assert stringify_signature(sig) == '(*args, **kwargs)'
def test_signature_partialmethod():
@@ -127,7 +127,7 @@ def test_signature_partialmethod():
def test_signature_annotations():
from typing_test_data import (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10,
- f11, f12, f13, f14, f15, f16, f17, f18, f19, Node)
+ f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, Node)
# Class annotations
sig = inspect.signature(f0)
@@ -184,6 +184,10 @@ def test_signature_annotations():
sig = inspect.signature(f13)
assert stringify_signature(sig) == '() -> Optional[str]'
+ # optional union
+ sig = inspect.signature(f20)
+ assert stringify_signature(sig) == '() -> Optional[Union[int, str]]'
+
# Any
sig = inspect.signature(f14)
assert stringify_signature(sig) == '() -> Any'
@@ -579,3 +583,21 @@ def test_getdoc_inherited_decorated_method():
assert inspect.getdoc(Bar.meth, getattr, False, Bar, "meth") is None
assert inspect.getdoc(Bar.meth, getattr, True, Bar, "meth") == "docstring."
+
+
+def test_is_builtin_class_method():
+ class MyInt(int):
+ def my_method(self):
+ pass
+
+ assert inspect.is_builtin_class_method(MyInt, 'to_bytes')
+ assert inspect.is_builtin_class_method(MyInt, '__init__')
+ assert not inspect.is_builtin_class_method(MyInt, 'my_method')
+ assert not inspect.is_builtin_class_method(MyInt, 'does_not_exist')
+ assert not inspect.is_builtin_class_method(4, 'still does not crash')
+
+ class ObjectWithMroAttr:
+ def __init__(self, mro_attr):
+ self.__mro__ = mro_attr
+
+ assert not inspect.is_builtin_class_method(ObjectWithMroAttr([1, 2, 3]), 'still does not crash')
diff --git a/tests/typing_test_data.py b/tests/typing_test_data.py
index 76db7c898..70c3144a0 100644
--- a/tests/typing_test_data.py
+++ b/tests/typing_test_data.py
@@ -96,6 +96,10 @@ def f19(*args: int, **kwargs: str):
pass
+def f20() -> Optional[Union[int, str]]:
+ pass
+
+
class Node:
def __init__(self, parent: Optional['Node']) -> None: