mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Allow multi-line object description signatures (#11011)
Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com> Co-authored-by: Jean-François B <2589111+jfbu@users.noreply.github.com> Co-authored-by: TLouf <loufthomas@gmail.com>
This commit is contained in:
parent
c73628dfca
commit
86b07d4a97
7
CHANGES
7
CHANGES
@ -26,6 +26,13 @@ Features added
|
||||
generated HTML, using the CRC32 algorithm.
|
||||
* :meth:`~sphinx.application.Sphinx.require_sphinx` now allows the version
|
||||
requirement to be specified as ``(major, minor)``.
|
||||
* #11011: Allow configuring a line-length limit for object signatures, via
|
||||
:confval:`maximum_signature_line_length` and the domain-specific variants.
|
||||
If the length of the signature (in characters) is greater than the configured
|
||||
limit, each parameter in the signature will be split to its own logical line.
|
||||
This behaviour may also be controlled by options on object description
|
||||
directives, for example :rst:dir:`py:function:single-line-parameter-list`.
|
||||
Patch by Thomas Louf, Adam Turner, and Jean-François Burnol.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
@ -1479,6 +1479,12 @@ Macros
|
||||
.. versionadded:: 6.2.0
|
||||
``\sphinxparam``, ``\sphinxsamedocref``
|
||||
|
||||
.. versionadded:: 7.1.0
|
||||
``\sphinxparamcomma`` which defaults to a comma followed by a space and
|
||||
``\sphinxparamcommaoneperline`` which is used for one-parameter-per-line
|
||||
signatures (see :confval:`maximum_signature_line_length`). It defaults
|
||||
to ``\texttt{,}`` to make these end-of-line separators more distinctive.
|
||||
|
||||
- More text styling:
|
||||
|
||||
.. csv-table::
|
||||
|
@ -675,6 +675,25 @@ General configuration
|
||||
If the value is a fully-qualified name of a custom Pygments style class,
|
||||
this is then used as custom style.
|
||||
|
||||
.. confval:: maximum_signature_line_length
|
||||
|
||||
If a signature's length in characters exceeds the number set, each
|
||||
parameter within the signature will be displayed on an individual logical
|
||||
line.
|
||||
|
||||
When ``None`` (the default), there is no maximum length and the entire
|
||||
signature will be displayed on a single logical line.
|
||||
|
||||
A 'logical line' is similar to a hard line break---builders or themes may
|
||||
choose to 'soft wrap' a single logical line, and this setting does not affect
|
||||
that behaviour.
|
||||
|
||||
Domains may provide options to suppress any hard wrapping on an individual
|
||||
object directive, such as seen in the C, C++, and Python domains (e.g.
|
||||
:rst:dir:`py:function:single-line-parameter-list`).
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. confval:: add_function_parentheses
|
||||
|
||||
A boolean that decides whether parentheses are appended to function and
|
||||
@ -2912,6 +2931,14 @@ Options for the C domain
|
||||
|
||||
.. versionadded:: 4.0.3
|
||||
|
||||
.. confval:: c_maximum_signature_line_length
|
||||
|
||||
If a signature's length in characters exceeds the number set, each
|
||||
parameter will be displayed on an individual logical line. This is a
|
||||
domain-specific setting, overriding :confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. _cpp-config:
|
||||
|
||||
Options for the C++ domain
|
||||
@ -2942,6 +2969,14 @@ Options for the C++ domain
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. confval:: cpp_maximum_signature_line_length
|
||||
|
||||
If a signature's length in characters exceeds the number set, each
|
||||
parameter will be displayed on an individual logical line. This is a
|
||||
domain-specific setting, overriding :confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
Options for the Python domain
|
||||
-----------------------------
|
||||
|
||||
@ -2984,6 +3019,25 @@ Options for the Python domain
|
||||
|
||||
.. note:: This configuration is still in experimental
|
||||
|
||||
.. confval:: python_maximum_signature_line_length
|
||||
|
||||
If a signature's length in characters exceeds the number set, each
|
||||
argument will be displayed on an individual logical line. This is a
|
||||
domain-specific setting, overriding :confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
Options for the Javascript domain
|
||||
---------------------------------
|
||||
|
||||
.. confval:: javascript_maximum_signature_line_length
|
||||
|
||||
If a signature's length in characters exceeds the number set, each
|
||||
parameter will be displayed on an individual logical line. This is a
|
||||
domain-specific setting, overriding :confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
Example of configuration file
|
||||
-----------------------------
|
||||
|
||||
|
@ -231,6 +231,16 @@ The following directives are provided for module and class contents:
|
||||
Describe the location where the object is defined. The default value is
|
||||
the module specified by :rst:dir:`py:currentmodule`.
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the function's arguments will be emitted on a single logical
|
||||
line, overriding :confval:`python_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
|
||||
.. rst:directive:: .. py:data:: name
|
||||
|
||||
Describes global data in a module, including both variables and values used
|
||||
@ -329,6 +339,15 @@ The following directives are provided for module and class contents:
|
||||
Describe the location where the object is defined. The default value is
|
||||
the module specified by :rst:dir:`py:currentmodule`.
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the class constructor's arguments will be emitted on a single
|
||||
logical line, overriding :confval:`python_maximum_signature_line_length`
|
||||
and :confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. rst:directive:: .. py:attribute:: name
|
||||
|
||||
Describes an object data attribute. The description should include
|
||||
@ -441,6 +460,15 @@ The following directives are provided for module and class contents:
|
||||
Describe the location where the object is defined. The default value is
|
||||
the module specified by :rst:dir:`py:currentmodule`.
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the method's arguments will be emitted on a single logical
|
||||
line, overriding :confval:`python_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. rst:directive:option:: staticmethod
|
||||
:type: no value
|
||||
|
||||
@ -494,6 +522,15 @@ The following directives are provided for module and class contents:
|
||||
There is no ``py:deco`` role to link to a decorator that is marked up with
|
||||
this directive; rather, use the :rst:role:`py:func` role.
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the decorator's arguments will be emitted on a single logical
|
||||
line, overriding :confval:`python_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. rst:directive:: .. py:decoratormethod:: name
|
||||
.. py:decoratormethod:: name(signature)
|
||||
|
||||
@ -763,6 +800,15 @@ The C domain (name **c**) is suited for documentation of C API.
|
||||
:retval NULL: under some conditions.
|
||||
:retval NULL: under some other conditions as well.
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the function's parameters will be emitted on a single logical
|
||||
line, overriding :confval:`c_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
|
||||
.. rst:directive:: .. c:macro:: name
|
||||
.. c:macro:: name(arg list)
|
||||
@ -776,6 +822,15 @@ The C domain (name **c**) is suited for documentation of C API.
|
||||
.. versionadded:: 3.0
|
||||
The function style variant.
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the macro's parameters will be emitted on a single logical
|
||||
line, overriding :confval:`c_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. rst:directive:: .. c:struct:: name
|
||||
|
||||
Describes a C struct.
|
||||
@ -1126,6 +1181,15 @@ visibility statement (``public``, ``private`` or ``protected``).
|
||||
.. cpp:function:: template<> \
|
||||
void print(int i)
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the function's parameters will be emitted on a single logical
|
||||
line, overriding :confval:`cpp_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. rst:directive:: .. cpp:member:: (member) variable declaration
|
||||
.. cpp:var:: (member) variable declaration
|
||||
|
||||
@ -1908,6 +1972,15 @@ The JavaScript domain (name **js**) provides the following directives:
|
||||
:throws SomeError: For whatever reason in that case.
|
||||
:returns: Something.
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the function's parameters will be emitted on a single logical
|
||||
line, overriding :confval:`javascript_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. rst:directive:: .. js:method:: name(signature)
|
||||
|
||||
This directive is an alias for :rst:dir:`js:function`, however it describes
|
||||
@ -1915,6 +1988,15 @@ The JavaScript domain (name **js**) provides the following directives:
|
||||
|
||||
.. versionadded:: 1.6
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the function's parameters will be emitted on a single logical
|
||||
line, overriding :confval:`javascript_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. rst:directive:: .. js:class:: name
|
||||
|
||||
Describes a constructor that creates an object. This is basically like a
|
||||
@ -1933,6 +2015,15 @@ The JavaScript domain (name **js**) provides the following directives:
|
||||
:param string name: The name of the animal
|
||||
:param number age: an optional age for the animal
|
||||
|
||||
.. rst:directive:option:: single-line-parameter-list
|
||||
:type: no value
|
||||
|
||||
Ensures that the function's parameters will be emitted on a single logical
|
||||
line, overriding :confval:`javascript_maximum_signature_line_length` and
|
||||
:confval:`maximum_signature_line_length`.
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. rst:directive:: .. js:data:: name
|
||||
|
||||
Describes a global variable or constant.
|
||||
|
@ -246,7 +246,12 @@ class desc_returns(desc_type):
|
||||
|
||||
|
||||
class desc_parameterlist(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
||||
"""Node for a general parameter list."""
|
||||
"""Node for a general parameter list.
|
||||
|
||||
As default the parameter list is written in line with the rest of the signature.
|
||||
Set ``multi_line_parameter_list = True`` to describe a multi-line parameter list.
|
||||
In that case each parameter will then be written on its own, indented line.
|
||||
"""
|
||||
child_text_separator = ', '
|
||||
|
||||
def astext(self):
|
||||
|
@ -137,7 +137,7 @@ class Config:
|
||||
'numfig': (False, 'env', []),
|
||||
'numfig_secnum_depth': (1, 'env', []),
|
||||
'numfig_format': ({}, 'env', []), # will be initialized in init_numfig_format()
|
||||
|
||||
'maximum_signature_line_length': (None, 'env', {int, None}),
|
||||
'math_number_all': (False, 'env', []),
|
||||
'math_eqref_format': (None, 'env', [str]),
|
||||
'math_numfig': (True, 'env', []),
|
||||
|
@ -727,9 +727,19 @@ class ASTParameters(ASTBase):
|
||||
def describe_signature(self, signode: TextElement, mode: str,
|
||||
env: BuildEnvironment, symbol: Symbol) -> None:
|
||||
verify_description_mode(mode)
|
||||
multi_line_parameter_list = False
|
||||
test_node: Element = signode
|
||||
while test_node.parent:
|
||||
if not isinstance(test_node, addnodes.desc_signature):
|
||||
test_node = test_node.parent
|
||||
continue
|
||||
multi_line_parameter_list = test_node.get('multi_line_parameter_list', False)
|
||||
break
|
||||
|
||||
# only use the desc_parameterlist for the outer list, not for inner lists
|
||||
if mode == 'lastIsName':
|
||||
paramlist = addnodes.desc_parameterlist()
|
||||
paramlist['multi_line_parameter_list'] = multi_line_parameter_list
|
||||
for arg in self.args:
|
||||
param = addnodes.desc_parameter('', '', noemph=True)
|
||||
arg.describe_signature(param, 'param', env, symbol=symbol)
|
||||
@ -3153,6 +3163,7 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
||||
option_spec: OptionSpec = {
|
||||
'noindexentry': directives.flag,
|
||||
'nocontentsentry': directives.flag,
|
||||
'single-line-parameter-list': directives.flag,
|
||||
}
|
||||
|
||||
def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None:
|
||||
@ -3258,6 +3269,14 @@ class CObject(ObjectDescription[ASTDeclaration]):
|
||||
def handle_signature(self, sig: str, signode: TextElement) -> ASTDeclaration:
|
||||
parentSymbol: Symbol = self.env.temp_data['c:parent_symbol']
|
||||
|
||||
max_len = (self.env.config.c_maximum_signature_line_length
|
||||
or self.env.config.maximum_signature_line_length
|
||||
or 0)
|
||||
signode['multi_line_parameter_list'] = (
|
||||
'single-line-parameter-list' not in self.options
|
||||
and (len(sig) > max_len > 0)
|
||||
)
|
||||
|
||||
parser = DefinitionParser(sig, location=signode, config=self.env.config)
|
||||
try:
|
||||
ast = self.parse_definition(parser)
|
||||
@ -3866,11 +3885,12 @@ def setup(app: Sphinx) -> dict[str, Any]:
|
||||
app.add_config_value("c_id_attributes", [], 'env')
|
||||
app.add_config_value("c_paren_attributes", [], 'env')
|
||||
app.add_config_value("c_extra_keywords", _macroKeywords, 'env')
|
||||
app.add_config_value("c_maximum_signature_line_length", None, 'env', types={int, None})
|
||||
app.add_post_transform(AliasTransform)
|
||||
|
||||
return {
|
||||
'version': 'builtin',
|
||||
'env_version': 2,
|
||||
'env_version': 3,
|
||||
'parallel_read_safe': True,
|
||||
'parallel_write_safe': True,
|
||||
}
|
||||
|
@ -2142,9 +2142,19 @@ class ASTParametersQualifiers(ASTBase):
|
||||
def describe_signature(self, signode: TextElement, mode: str,
|
||||
env: BuildEnvironment, symbol: Symbol) -> None:
|
||||
verify_description_mode(mode)
|
||||
multi_line_parameter_list = False
|
||||
test_node: Element = signode
|
||||
while test_node.parent:
|
||||
if not isinstance(test_node, addnodes.desc_signature):
|
||||
test_node = test_node.parent
|
||||
continue
|
||||
multi_line_parameter_list = test_node.get('multi_line_parameter_list', False)
|
||||
break
|
||||
|
||||
# only use the desc_parameterlist for the outer list, not for inner lists
|
||||
if mode == 'lastIsName':
|
||||
paramlist = addnodes.desc_parameterlist()
|
||||
paramlist['multi_line_parameter_list'] = multi_line_parameter_list
|
||||
for arg in self.args:
|
||||
param = addnodes.desc_parameter('', '', noemph=True)
|
||||
arg.describe_signature(param, 'param', env, symbol=symbol)
|
||||
@ -7192,6 +7202,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
'noindexentry': directives.flag,
|
||||
'nocontentsentry': directives.flag,
|
||||
'tparam-line-spec': directives.flag,
|
||||
'single-line-parameter-list': directives.flag,
|
||||
}
|
||||
|
||||
def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None:
|
||||
@ -7348,6 +7359,14 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> ASTDeclaration:
|
||||
parentSymbol: Symbol = self.env.temp_data['cpp:parent_symbol']
|
||||
|
||||
max_len = (self.env.config.cpp_maximum_signature_line_length
|
||||
or self.env.config.maximum_signature_line_length
|
||||
or 0)
|
||||
signode['multi_line_parameter_list'] = (
|
||||
'single-line-parameter-list' not in self.options
|
||||
and (len(sig) > max_len > 0)
|
||||
)
|
||||
|
||||
parser = DefinitionParser(sig, location=signode, config=self.env.config)
|
||||
try:
|
||||
ast = self.parse_definition(parser)
|
||||
@ -8140,6 +8159,7 @@ def setup(app: Sphinx) -> dict[str, Any]:
|
||||
app.add_config_value("cpp_index_common_prefix", [], 'env')
|
||||
app.add_config_value("cpp_id_attributes", [], 'env')
|
||||
app.add_config_value("cpp_paren_attributes", [], 'env')
|
||||
app.add_config_value("cpp_maximum_signature_line_length", None, 'env', types={int, None})
|
||||
app.add_post_transform(AliasTransform)
|
||||
|
||||
# debug stuff
|
||||
@ -8154,7 +8174,7 @@ def setup(app: Sphinx) -> dict[str, Any]:
|
||||
|
||||
return {
|
||||
'version': 'builtin',
|
||||
'env_version': 8,
|
||||
'env_version': 9,
|
||||
'parallel_read_safe': True,
|
||||
'parallel_write_safe': True,
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ class JSObject(ObjectDescription[Tuple[str, str]]):
|
||||
'noindex': directives.flag,
|
||||
'noindexentry': directives.flag,
|
||||
'nocontentsentry': directives.flag,
|
||||
'single-line-parameter-list': directives.flag,
|
||||
}
|
||||
|
||||
def get_display_prefix(self) -> list[Node]:
|
||||
@ -88,6 +89,14 @@ class JSObject(ObjectDescription[Tuple[str, str]]):
|
||||
signode['object'] = prefix
|
||||
signode['fullname'] = fullname
|
||||
|
||||
max_len = (self.env.config.javascript_maximum_signature_line_length
|
||||
or self.env.config.maximum_signature_line_length
|
||||
or 0)
|
||||
multi_line_parameter_list = (
|
||||
'single-line-parameter-list' not in self.options
|
||||
and (len(sig) > max_len > 0)
|
||||
)
|
||||
|
||||
display_prefix = self.get_display_prefix()
|
||||
if display_prefix:
|
||||
signode += addnodes.desc_annotation('', '', *display_prefix)
|
||||
@ -108,7 +117,7 @@ class JSObject(ObjectDescription[Tuple[str, str]]):
|
||||
if not arglist:
|
||||
signode += addnodes.desc_parameterlist()
|
||||
else:
|
||||
_pseudo_parse_arglist(signode, arglist)
|
||||
_pseudo_parse_arglist(signode, arglist, multi_line_parameter_list)
|
||||
return fullname, prefix
|
||||
|
||||
def _object_hierarchy_parts(self, sig_node: desc_signature) -> tuple[str, ...]:
|
||||
@ -473,10 +482,12 @@ class JavaScriptDomain(Domain):
|
||||
|
||||
def setup(app: Sphinx) -> dict[str, Any]:
|
||||
app.add_domain(JavaScriptDomain)
|
||||
|
||||
app.add_config_value(
|
||||
'javascript_maximum_signature_line_length', None, 'env', types={int, None},
|
||||
)
|
||||
return {
|
||||
'version': 'builtin',
|
||||
'env_version': 2,
|
||||
'env_version': 3,
|
||||
'parallel_read_safe': True,
|
||||
'parallel_write_safe': True,
|
||||
}
|
||||
|
@ -258,10 +258,11 @@ def _parse_annotation(annotation: str, env: BuildEnvironment | None) -> list[Nod
|
||||
|
||||
|
||||
def _parse_arglist(
|
||||
arglist: str, env: BuildEnvironment | None = None,
|
||||
arglist: str, env: BuildEnvironment | None = None, multi_line_parameter_list: bool = False,
|
||||
) -> addnodes.desc_parameterlist:
|
||||
"""Parse a list of arguments using AST parser"""
|
||||
params = addnodes.desc_parameterlist(arglist)
|
||||
params['multi_line_parameter_list'] = multi_line_parameter_list
|
||||
sig = signature_from_str('(%s)' % arglist)
|
||||
last_kind = None
|
||||
for param in sig.parameters.values():
|
||||
@ -309,7 +310,9 @@ def _parse_arglist(
|
||||
return params
|
||||
|
||||
|
||||
def _pseudo_parse_arglist(signode: desc_signature, arglist: str) -> None:
|
||||
def _pseudo_parse_arglist(
|
||||
signode: desc_signature, arglist: str, multi_line_parameter_list: bool = False,
|
||||
) -> None:
|
||||
""""Parse" a list of arguments separated by commas.
|
||||
|
||||
Arguments can have "optional" annotations given by enclosing them in
|
||||
@ -317,6 +320,7 @@ def _pseudo_parse_arglist(signode: desc_signature, arglist: str) -> None:
|
||||
string literal (e.g. default argument value).
|
||||
"""
|
||||
paramlist = addnodes.desc_parameterlist()
|
||||
paramlist['multi_line_parameter_list'] = multi_line_parameter_list
|
||||
stack: list[Element] = [paramlist]
|
||||
try:
|
||||
for argument in arglist.split(','):
|
||||
@ -459,6 +463,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
|
||||
'noindex': directives.flag,
|
||||
'noindexentry': directives.flag,
|
||||
'nocontentsentry': directives.flag,
|
||||
'single-line-parameter-list': directives.flag,
|
||||
'module': directives.unchanged,
|
||||
'canonical': directives.unchanged,
|
||||
'annotation': directives.unchanged,
|
||||
@ -541,6 +546,14 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
|
||||
signode['class'] = classname
|
||||
signode['fullname'] = fullname
|
||||
|
||||
max_len = (self.env.config.python_maximum_signature_line_length
|
||||
or self.env.config.maximum_signature_line_length
|
||||
or 0)
|
||||
multi_line_parameter_list = (
|
||||
'single-line-parameter-list' not in self.options
|
||||
and (len(sig) > max_len > 0)
|
||||
)
|
||||
|
||||
sig_prefix = self.get_signature_prefix(sig)
|
||||
if sig_prefix:
|
||||
if type(sig_prefix) is str:
|
||||
@ -559,15 +572,15 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
|
||||
signode += addnodes.desc_name(name, name)
|
||||
if arglist:
|
||||
try:
|
||||
signode += _parse_arglist(arglist, self.env)
|
||||
signode += _parse_arglist(arglist, self.env, multi_line_parameter_list)
|
||||
except SyntaxError:
|
||||
# fallback to parse arglist original parser.
|
||||
# it supports to represent optional arguments (ex. "func(foo [, bar])")
|
||||
_pseudo_parse_arglist(signode, arglist)
|
||||
_pseudo_parse_arglist(signode, arglist, multi_line_parameter_list)
|
||||
except NotImplementedError as exc:
|
||||
logger.warning("could not parse arglist (%r): %s", arglist, exc,
|
||||
location=signode)
|
||||
_pseudo_parse_arglist(signode, arglist)
|
||||
_pseudo_parse_arglist(signode, arglist, multi_line_parameter_list)
|
||||
else:
|
||||
if self.needs_arglist():
|
||||
# for callables, add an empty parameter list
|
||||
@ -1505,13 +1518,15 @@ def setup(app: Sphinx) -> dict[str, Any]:
|
||||
|
||||
app.add_domain(PythonDomain)
|
||||
app.add_config_value('python_use_unqualified_type_names', False, 'env')
|
||||
app.add_config_value('python_maximum_signature_line_length', None, 'env',
|
||||
types={int, None})
|
||||
app.add_config_value('python_display_short_literal_types', False, 'env')
|
||||
app.connect('object-description-transform', filter_meta_fields)
|
||||
app.connect('missing-reference', builtin_resolver, priority=900)
|
||||
|
||||
return {
|
||||
'version': 'builtin',
|
||||
'env_version': 3,
|
||||
'env_version': 4,
|
||||
'parallel_read_safe': True,
|
||||
'parallel_write_safe': True,
|
||||
}
|
||||
|
@ -146,6 +146,27 @@
|
||||
\item[{#1\sphinxcode{(}\py@sigparams{#2}{#3}\strut}]
|
||||
\pysigadjustitemsep
|
||||
}
|
||||
|
||||
\def\sphinxoptionalextraspace{0.5mm}
|
||||
\newcommand{\pysigwithonelineperarg}[3]{%
|
||||
% render each argument on its own line
|
||||
\item[#1\sphinxcode{(}\strut]
|
||||
\leavevmode\par\nopagebreak
|
||||
% this relies on \pysigstartsignatures having set \parskip to zero
|
||||
\begingroup
|
||||
\let\sphinxparamcomma\sphinxparamcommaoneperline
|
||||
\def\sphinxoptionalhook{\ifvmode\else\kern\sphinxoptionalextraspace\relax\fi}%
|
||||
% The very first \sphinxparam should not emit a \par hence a complication
|
||||
% with a group and global definition here as it may occur in a \sphinxoptional
|
||||
\global\let\spx@sphinxparam\sphinxparam
|
||||
\gdef\sphinxparam{\gdef\sphinxparam{\par\spx@sphinxparam}\spx@sphinxparam}%
|
||||
#2\par
|
||||
\endgroup
|
||||
\global\let\sphinxparam\spx@sphinxparam
|
||||
% fulllineitems sets \labelwidth to be like \leftmargin
|
||||
\nopagebreak\noindent\kern-\labelwidth\sphinxcode{)}{#3}
|
||||
\pysigadjustitemsep
|
||||
}
|
||||
\newcommand{\pysigadjustitemsep}{%
|
||||
% adjust \itemsep to control the separation with the next signature
|
||||
% sharing common description
|
||||
|
@ -58,7 +58,8 @@
|
||||
\protected\def\sphinxparam#1{\emph{#1}}
|
||||
% \optional is used for ``[, arg]``, i.e. desc_optional nodes.
|
||||
\long\protected\def\sphinxoptional#1{%
|
||||
{\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}}
|
||||
{\sphinxoptionalhook\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}}
|
||||
\let\sphinxoptionalhook\empty
|
||||
|
||||
% additional customizable styling
|
||||
\def\sphinxstyleindexentry #1{\texttt{#1}}
|
||||
@ -112,6 +113,11 @@
|
||||
|
||||
% Special characters
|
||||
%
|
||||
\def\sphinxparamcomma{, }% by default separate parameters with comma + space
|
||||
% If the signature is rendered with one line per param, this wil be used
|
||||
% instead (this \texttt makes the comma slightly more distinctive).
|
||||
\def\sphinxparamcommaoneperline{\texttt{,}}
|
||||
%
|
||||
% The \kern\z@ is to prevent en-dash and em-dash TeX ligatures.
|
||||
% A linebreak can occur after the dash in regular text (this is
|
||||
% normal behaviour of "-" in TeX, it is not related to \kern\z@).
|
||||
|
@ -670,6 +670,16 @@ dd {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.sig dd {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.sig dl {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
dl > dd:last-child,
|
||||
dl > dd:last-child > :last-child {
|
||||
margin-bottom: 0;
|
||||
|
@ -458,6 +458,11 @@ dl {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.sig dl {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
dd p {
|
||||
margin-top: 0px;
|
||||
}
|
||||
@ -472,6 +477,11 @@ dd {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.sig dd {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
dt:target, .highlighted {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
@ -150,14 +150,26 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
||||
|
||||
def visit_desc_parameterlist(self, node: Element) -> None:
|
||||
self.body.append('<span class="sig-paren">(</span>')
|
||||
self.first_param = 1
|
||||
self.is_first_param = True
|
||||
self.optional_param_level = 0
|
||||
self.params_left_at_level = 0
|
||||
self.param_group_index = 0
|
||||
# Counts as what we call a parameter group either a required parameter, or a
|
||||
# set of contiguous optional ones.
|
||||
self.list_is_required_param = [isinstance(c, addnodes.desc_parameter)
|
||||
for c in node.children]
|
||||
# How many required parameters are left.
|
||||
self.required_params_left = sum([isinstance(c, addnodes.desc_parameter)
|
||||
for c in node.children])
|
||||
self.required_params_left = sum(self.list_is_required_param)
|
||||
self.param_separator = node.child_text_separator
|
||||
self.multi_line_parameter_list = node.get('multi_line_parameter_list', False)
|
||||
if self.multi_line_parameter_list:
|
||||
self.body.append('\n\n')
|
||||
self.body.append(self.starttag(node, 'dl'))
|
||||
self.param_separator = self.param_separator.rstrip()
|
||||
|
||||
def depart_desc_parameterlist(self, node: Element) -> None:
|
||||
if node.get('multi_line_parameter_list'):
|
||||
self.body.append('</dl>\n\n')
|
||||
self.body.append('<span class="sig-paren">)</span>')
|
||||
|
||||
# If required parameters are still to come, then put the comma after
|
||||
@ -167,28 +179,82 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
||||
# foo([a, ]b, c[, d])
|
||||
#
|
||||
def visit_desc_parameter(self, node: Element) -> None:
|
||||
if self.first_param:
|
||||
self.first_param = 0
|
||||
elif not self.required_params_left:
|
||||
on_separate_line = self.multi_line_parameter_list
|
||||
if on_separate_line and not (self.is_first_param and self.optional_param_level > 0):
|
||||
self.body.append(self.starttag(node, 'dd', ''))
|
||||
if self.is_first_param:
|
||||
self.is_first_param = False
|
||||
elif not on_separate_line and not self.required_params_left:
|
||||
self.body.append(self.param_separator)
|
||||
if self.optional_param_level == 0:
|
||||
self.required_params_left -= 1
|
||||
else:
|
||||
self.params_left_at_level -= 1
|
||||
if not node.hasattr('noemph'):
|
||||
self.body.append('<em class="sig-param">')
|
||||
|
||||
def depart_desc_parameter(self, node: Element) -> None:
|
||||
if not node.hasattr('noemph'):
|
||||
self.body.append('</em>')
|
||||
if self.required_params_left:
|
||||
is_required = self.list_is_required_param[self.param_group_index]
|
||||
if self.multi_line_parameter_list:
|
||||
is_last_group = self.param_group_index + 1 == len(self.list_is_required_param)
|
||||
next_is_required = (
|
||||
not is_last_group
|
||||
and self.list_is_required_param[self.param_group_index + 1]
|
||||
)
|
||||
opt_param_left_at_level = self.params_left_at_level > 0
|
||||
if opt_param_left_at_level or is_required and (is_last_group or next_is_required):
|
||||
self.body.append(self.param_separator)
|
||||
self.body.append('</dd>\n')
|
||||
|
||||
elif self.required_params_left:
|
||||
self.body.append(self.param_separator)
|
||||
|
||||
if is_required:
|
||||
self.param_group_index += 1
|
||||
|
||||
def visit_desc_optional(self, node: Element) -> None:
|
||||
self.params_left_at_level = sum([isinstance(c, addnodes.desc_parameter)
|
||||
for c in node.children])
|
||||
self.optional_param_level += 1
|
||||
self.body.append('<span class="optional">[</span>')
|
||||
self.max_optional_param_level = self.optional_param_level
|
||||
if self.multi_line_parameter_list:
|
||||
# If the first parameter is optional, start a new line and open the bracket.
|
||||
if self.is_first_param:
|
||||
self.body.append(self.starttag(node, 'dd', ''))
|
||||
self.body.append('<span class="optional">[</span>')
|
||||
# Else, if there remains at least one required parameter, append the
|
||||
# parameter separator, open a new bracket, and end the line.
|
||||
elif self.required_params_left:
|
||||
self.body.append(self.param_separator)
|
||||
self.body.append('<span class="optional">[</span>')
|
||||
self.body.append('</dd>\n')
|
||||
# Else, open a new bracket, append the parameter separator,
|
||||
# and end the line.
|
||||
else:
|
||||
self.body.append('<span class="optional">[</span>')
|
||||
self.body.append(self.param_separator)
|
||||
self.body.append('</dd>\n')
|
||||
else:
|
||||
self.body.append('<span class="optional">[</span>')
|
||||
|
||||
def depart_desc_optional(self, node: Element) -> None:
|
||||
self.optional_param_level -= 1
|
||||
self.body.append('<span class="optional">]</span>')
|
||||
if self.multi_line_parameter_list:
|
||||
# If it's the first time we go down one level, add the separator
|
||||
# before the bracket.
|
||||
if self.optional_param_level == self.max_optional_param_level - 1:
|
||||
self.body.append(self.param_separator)
|
||||
self.body.append('<span class="optional">]</span>')
|
||||
# End the line if we have just closed the last bracket of this
|
||||
# optional parameter group.
|
||||
if self.optional_param_level == 0:
|
||||
self.body.append('</dd>\n')
|
||||
else:
|
||||
self.body.append('<span class="optional">]</span>')
|
||||
if self.optional_param_level == 0:
|
||||
self.param_group_index += 1
|
||||
|
||||
def visit_desc_annotation(self, node: Element) -> None:
|
||||
self.body.append(self.starttag(node, 'em', '', CLASS='property'))
|
||||
|
@ -702,7 +702,10 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
def _visit_signature_line(self, node: Element) -> None:
|
||||
for child in node:
|
||||
if isinstance(child, addnodes.desc_parameterlist):
|
||||
self.body.append(CR + r'\pysiglinewithargsret{')
|
||||
if child.get('multi_line_parameter_list'):
|
||||
self.body.append(CR + r'\pysigwithonelineperarg{')
|
||||
else:
|
||||
self.body.append(CR + r'\pysiglinewithargsret{')
|
||||
break
|
||||
else:
|
||||
self.body.append(CR + r'\pysigline{')
|
||||
@ -784,29 +787,82 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
def visit_desc_parameterlist(self, node: Element) -> None:
|
||||
# close name, open parameterlist
|
||||
self.body.append('}{')
|
||||
self.first_param = 1
|
||||
self.is_first_param = True
|
||||
self.optional_param_level = 0
|
||||
self.params_left_at_level = 0
|
||||
self.param_group_index = 0
|
||||
# Counts as what we call a parameter group either a required parameter, or a
|
||||
# set of contiguous optional ones.
|
||||
self.list_is_required_param = [isinstance(c, addnodes.desc_parameter)
|
||||
for c in node.children]
|
||||
# How many required parameters are left.
|
||||
self.required_params_left = sum(self.list_is_required_param)
|
||||
self.param_separator = r'\sphinxparamcomma '
|
||||
self.multi_line_parameter_list = node.get('multi_line_parameter_list', False)
|
||||
|
||||
def depart_desc_parameterlist(self, node: Element) -> None:
|
||||
# close parameterlist, open return annotation
|
||||
self.body.append('}{')
|
||||
|
||||
def visit_desc_parameter(self, node: Element) -> None:
|
||||
if not self.first_param:
|
||||
self.body.append(', ')
|
||||
if self.is_first_param:
|
||||
self.is_first_param = False
|
||||
elif not self.multi_line_parameter_list and not self.required_params_left:
|
||||
self.body.append(self.param_separator)
|
||||
if self.optional_param_level == 0:
|
||||
self.required_params_left -= 1
|
||||
else:
|
||||
self.first_param = 0
|
||||
self.params_left_at_level -= 1
|
||||
if not node.hasattr('noemph'):
|
||||
self.body.append(r'\sphinxparam{')
|
||||
|
||||
def depart_desc_parameter(self, node: Element) -> None:
|
||||
if not node.hasattr('noemph'):
|
||||
self.body.append('}')
|
||||
is_required = self.list_is_required_param[self.param_group_index]
|
||||
if self.multi_line_parameter_list:
|
||||
is_last_group = self.param_group_index + 1 == len(self.list_is_required_param)
|
||||
next_is_required = (
|
||||
not is_last_group
|
||||
and self.list_is_required_param[self.param_group_index + 1]
|
||||
)
|
||||
opt_param_left_at_level = self.params_left_at_level > 0
|
||||
if opt_param_left_at_level or is_required and (is_last_group or next_is_required):
|
||||
self.body.append(self.param_separator)
|
||||
|
||||
elif self.required_params_left:
|
||||
self.body.append(self.param_separator)
|
||||
|
||||
if is_required:
|
||||
self.param_group_index += 1
|
||||
|
||||
def visit_desc_optional(self, node: Element) -> None:
|
||||
self.body.append(r'\sphinxoptional{')
|
||||
self.params_left_at_level = sum([isinstance(c, addnodes.desc_parameter)
|
||||
for c in node.children])
|
||||
self.optional_param_level += 1
|
||||
self.max_optional_param_level = self.optional_param_level
|
||||
if self.multi_line_parameter_list:
|
||||
if self.is_first_param:
|
||||
self.body.append(r'\sphinxoptional{')
|
||||
elif self.required_params_left:
|
||||
self.body.append(self.param_separator)
|
||||
self.body.append(r'\sphinxoptional{')
|
||||
else:
|
||||
self.body.append(r'\sphinxoptional{')
|
||||
self.body.append(self.param_separator)
|
||||
else:
|
||||
self.body.append(r'\sphinxoptional{')
|
||||
|
||||
def depart_desc_optional(self, node: Element) -> None:
|
||||
self.optional_param_level -= 1
|
||||
if self.multi_line_parameter_list:
|
||||
# If it's the first time we go down one level, add the separator before the
|
||||
# bracket.
|
||||
if self.optional_param_level == self.max_optional_param_level - 1:
|
||||
self.body.append(self.param_separator)
|
||||
self.body.append('}')
|
||||
if self.optional_param_level == 0:
|
||||
self.param_group_index += 1
|
||||
|
||||
def visit_desc_annotation(self, node: Element) -> None:
|
||||
self.body.append(r'\sphinxbfcode{\sphinxupquote{')
|
||||
|
@ -594,24 +594,99 @@ class TextTranslator(SphinxTranslator):
|
||||
|
||||
def visit_desc_parameterlist(self, node: Element) -> None:
|
||||
self.add_text('(')
|
||||
self.first_param = 1
|
||||
self.is_first_param = True
|
||||
self.optional_param_level = 0
|
||||
self.params_left_at_level = 0
|
||||
self.param_group_index = 0
|
||||
# Counts as what we call a parameter group are either a required parameter, or a
|
||||
# set of contiguous optional ones.
|
||||
self.list_is_required_param = [isinstance(c, addnodes.desc_parameter)
|
||||
for c in node.children]
|
||||
self.required_params_left = sum(self.list_is_required_param)
|
||||
self.param_separator = ', '
|
||||
self.multi_line_parameter_list = node.get('multi_line_parameter_list', False)
|
||||
if self.multi_line_parameter_list:
|
||||
self.param_separator = self.param_separator.rstrip()
|
||||
|
||||
def depart_desc_parameterlist(self, node: Element) -> None:
|
||||
self.add_text(')')
|
||||
|
||||
def visit_desc_parameter(self, node: Element) -> None:
|
||||
if not self.first_param:
|
||||
self.add_text(', ')
|
||||
on_separate_line = self.multi_line_parameter_list
|
||||
if on_separate_line and not (self.is_first_param and self.optional_param_level > 0):
|
||||
self.new_state()
|
||||
if self.is_first_param:
|
||||
self.is_first_param = False
|
||||
elif not on_separate_line and not self.required_params_left:
|
||||
self.add_text(self.param_separator)
|
||||
if self.optional_param_level == 0:
|
||||
self.required_params_left -= 1
|
||||
else:
|
||||
self.first_param = 0
|
||||
self.params_left_at_level -= 1
|
||||
|
||||
self.add_text(node.astext())
|
||||
|
||||
is_required = self.list_is_required_param[self.param_group_index]
|
||||
if on_separate_line:
|
||||
is_last_group = self.param_group_index + 1 == len(self.list_is_required_param)
|
||||
next_is_required = (
|
||||
not is_last_group
|
||||
and self.list_is_required_param[self.param_group_index + 1]
|
||||
)
|
||||
opt_param_left_at_level = self.params_left_at_level > 0
|
||||
if opt_param_left_at_level or is_required and (is_last_group or next_is_required):
|
||||
self.add_text(self.param_separator)
|
||||
self.end_state(wrap=False, end=None)
|
||||
|
||||
elif self.required_params_left:
|
||||
self.add_text(self.param_separator)
|
||||
|
||||
if is_required:
|
||||
self.param_group_index += 1
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_desc_optional(self, node: Element) -> None:
|
||||
self.add_text('[')
|
||||
self.params_left_at_level = sum([isinstance(c, addnodes.desc_parameter)
|
||||
for c in node.children])
|
||||
self.optional_param_level += 1
|
||||
self.max_optional_param_level = self.optional_param_level
|
||||
if self.multi_line_parameter_list:
|
||||
# If the first parameter is optional, start a new line and open the bracket.
|
||||
if self.is_first_param:
|
||||
self.new_state()
|
||||
self.add_text('[')
|
||||
# Else, if there remains at least one required parameter, append the
|
||||
# parameter separator, open a new bracket, and end the line.
|
||||
elif self.required_params_left:
|
||||
self.add_text(self.param_separator)
|
||||
self.add_text('[')
|
||||
self.end_state(wrap=False, end=None)
|
||||
# Else, open a new bracket, append the parameter separator, and end the
|
||||
# line.
|
||||
else:
|
||||
self.add_text('[')
|
||||
self.add_text(self.param_separator)
|
||||
self.end_state(wrap=False, end=None)
|
||||
else:
|
||||
self.add_text('[')
|
||||
|
||||
def depart_desc_optional(self, node: Element) -> None:
|
||||
self.add_text(']')
|
||||
self.optional_param_level -= 1
|
||||
if self.multi_line_parameter_list:
|
||||
# If it's the first time we go down one level, add the separator before the
|
||||
# bracket.
|
||||
if self.optional_param_level == self.max_optional_param_level - 1:
|
||||
self.add_text(self.param_separator)
|
||||
self.add_text(']')
|
||||
# End the line if we have just closed the last bracket of this group of
|
||||
# optional parameters.
|
||||
if self.optional_param_level == 0:
|
||||
self.end_state(wrap=False, end=None)
|
||||
|
||||
else:
|
||||
self.add_text(']')
|
||||
if self.optional_param_level == 0:
|
||||
self.param_group_index += 1
|
||||
|
||||
def visit_desc_annotation(self, node: Element) -> None:
|
||||
pass
|
||||
|
@ -0,0 +1 @@
|
||||
c_maximum_signature_line_length = len("str hello(str name)") - 1
|
@ -0,0 +1,4 @@
|
||||
domain-c-c_maximum_signature_line_length
|
||||
========================================
|
||||
|
||||
.. c:function:: str hello(str name)
|
@ -0,0 +1 @@
|
||||
cpp_maximum_signature_line_length = len("str hello(str name)") - 1
|
@ -0,0 +1,4 @@
|
||||
domain-cpp-cpp_maximum_signature_line_length
|
||||
============================================
|
||||
|
||||
.. cpp:function:: str hello(str name)
|
@ -0,0 +1 @@
|
||||
javascript_maximum_signature_line_length = 1
|
@ -0,0 +1,6 @@
|
||||
domain-js-maximum_signature_line_length
|
||||
=======================================
|
||||
|
||||
.. js:function:: hello(name)
|
||||
|
||||
.. js:function:: foo([a, [b, ]]c, d[, e, f])
|
@ -0,0 +1 @@
|
||||
python_maximum_signature_line_length = 1
|
@ -0,0 +1,6 @@
|
||||
domain-py-maximum_signature_line_length
|
||||
=======================================
|
||||
|
||||
.. py:function:: hello(name: str) -> str
|
||||
|
||||
.. py:function:: foo([a, [b, ]]c, d[, e, f])
|
@ -3,7 +3,7 @@
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from itertools import product
|
||||
from itertools import chain, product
|
||||
from pathlib import Path
|
||||
from shutil import copyfile
|
||||
from subprocess import CalledProcessError
|
||||
@ -95,11 +95,18 @@ def skip_if_stylefiles_notfound(testfunc):
|
||||
@skip_if_requested
|
||||
@skip_if_stylefiles_notfound
|
||||
@pytest.mark.parametrize(
|
||||
"engine,docclass",
|
||||
product(LATEX_ENGINES, DOCCLASSES),
|
||||
"engine,docclass,python_maximum_signature_line_length",
|
||||
# Only running test with `python_maximum_signature_line_length` not None with last
|
||||
# LaTeX engine to reduce testing time, as if this configuration does not fail with
|
||||
# one engine, it's almost impossible it would fail with another.
|
||||
chain(
|
||||
product(LATEX_ENGINES[:-1], DOCCLASSES, [None]),
|
||||
product([LATEX_ENGINES[-1]], DOCCLASSES, [1]),
|
||||
),
|
||||
)
|
||||
@pytest.mark.sphinx('latex')
|
||||
def test_build_latex_doc(app, status, warning, engine, docclass):
|
||||
@pytest.mark.sphinx('latex', freshenv=True)
|
||||
def test_build_latex_doc(app, status, warning, engine, docclass, python_maximum_signature_line_length):
|
||||
app.config.python_maximum_signature_line_length = python_maximum_signature_line_length
|
||||
app.config.intersphinx_mapping = {
|
||||
'sphinx': ('https://www.sphinx-doc.org/en/master/', None),
|
||||
}
|
||||
@ -113,7 +120,6 @@ def test_build_latex_doc(app, status, warning, engine, docclass):
|
||||
normalize_intersphinx_mapping(app, app.config)
|
||||
load_mappings(app)
|
||||
app.builder.init()
|
||||
|
||||
LaTeXTranslator.ignore_missing_images = True
|
||||
app.builder.build_all()
|
||||
|
||||
@ -1734,3 +1740,16 @@ def test_duplicated_labels_before_module(app, status, warning):
|
||||
# ensure that we did not forget any label to check
|
||||
# and if so, report them nicely in case of failure
|
||||
assert sorted(tested_labels) == sorted(output_labels)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('latex', testroot='domain-py-python_maximum_signature_line_length',
|
||||
confoverrides={'python_maximum_signature_line_length': 23})
|
||||
def test_one_parameter_per_line(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'python.tex').read_text(encoding='utf8')
|
||||
|
||||
# TODO: should these asserts check presence or absence of a final \sphinxparamcomma?
|
||||
# signature of 23 characters is too short to trigger one-param-per-line mark-up
|
||||
assert ('\\pysiglinewithargsret{\\sphinxbfcode{\\sphinxupquote{hello}}}' in result)
|
||||
|
||||
assert ('\\pysigwithonelineperarg{\\sphinxbfcode{\\sphinxupquote{foo}}}' in result)
|
||||
|
@ -7,7 +7,18 @@ from xml.etree import ElementTree
|
||||
import pytest
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import desc
|
||||
from sphinx.addnodes import (
|
||||
desc,
|
||||
desc_content,
|
||||
desc_name,
|
||||
desc_parameter,
|
||||
desc_parameterlist,
|
||||
desc_sig_name,
|
||||
desc_sig_space,
|
||||
desc_signature,
|
||||
desc_signature_line,
|
||||
pending_xref,
|
||||
)
|
||||
from sphinx.domains.c import (
|
||||
DefinitionError,
|
||||
DefinitionParser,
|
||||
@ -19,6 +30,7 @@ from sphinx.domains.c import (
|
||||
from sphinx.ext.intersphinx import load_mappings, normalize_intersphinx_mapping
|
||||
from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
from sphinx.writers.text import STDINDENT
|
||||
|
||||
|
||||
class Config:
|
||||
@ -814,3 +826,251 @@ def test_domain_c_parse_noindexentry(app):
|
||||
assert_node(doctree, (addnodes.index, desc, addnodes.index, desc))
|
||||
assert_node(doctree[0], addnodes.index, entries=[('single', 'f (C function)', 'c.f', '', None)])
|
||||
assert_node(doctree[2], addnodes.index, entries=[])
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'c_maximum_signature_line_length': len("str hello(str name)"),
|
||||
})
|
||||
def test_cfunction_signature_with_c_maximum_signature_line_length_equal(app):
|
||||
text = ".. c:function:: str hello(str name)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, "hello"]],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="c", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, "str"]],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, "name"],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'c_maximum_signature_line_length': len("str hello(str name)"),
|
||||
})
|
||||
def test_cfunction_signature_with_c_maximum_signature_line_length_force_single(app):
|
||||
text = (".. c:function:: str hello(str names)\n"
|
||||
" :single-line-parameter-list:")
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, "hello"]],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="c", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, "str"]],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, "names"],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'c_maximum_signature_line_length': len("str hello(str name)"),
|
||||
})
|
||||
def test_cfunction_signature_with_c_maximum_signature_line_length_break(app):
|
||||
text = ".. c:function:: str hello(str names)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, "hello"]],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="c", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, "str"]],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, "names"],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("str hello(str name)"),
|
||||
})
|
||||
def test_cfunction_signature_with_maximum_signature_line_length_equal(app):
|
||||
text = ".. c:function:: str hello(str name)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, "hello"]],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="c", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, "str"]],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, "name"],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("str hello(str name)"),
|
||||
})
|
||||
def test_cfunction_signature_with_maximum_signature_line_length_force_single(app):
|
||||
text = (".. c:function:: str hello(str names)\n"
|
||||
" :single-line-parameter-list:")
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, "hello"]],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="c", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, "str"]],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, "names"],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("str hello(str name)"),
|
||||
})
|
||||
def test_cfunction_signature_with_maximum_signature_line_length_break(app):
|
||||
text = ".. c:function:: str hello(str names)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, "hello"]],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="c", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, "str"]],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, "names"],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'c_maximum_signature_line_length': len('str hello(str name)'),
|
||||
'maximum_signature_line_length': 1,
|
||||
})
|
||||
def test_c_maximum_signature_line_length_overrides_global(app):
|
||||
text = '.. c:function:: str hello(str name)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, 'hello']],
|
||||
desc_parameterlist,
|
||||
)]
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype='function',
|
||||
domain='c', objtype='function', noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, "str"]],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, 'name'],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='domain-c-c_maximum_signature_line_length')
|
||||
def test_domain_c_c_maximum_signature_line_length_in_html(app, status, warning):
|
||||
app.build()
|
||||
content = (app.outdir / 'index.html').read_text(encoding='utf-8')
|
||||
expected = """\
|
||||
|
||||
<dl>
|
||||
<dd>\
|
||||
<span class="n"><span class="pre">str</span></span>\
|
||||
<span class="w"> </span>\
|
||||
<span class="n"><span class="pre">name</span></span>,\
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<span class="sig-paren">)</span>\
|
||||
<a class="headerlink" href="#c.hello" title="Permalink to this definition">¶</a>\
|
||||
<br />\
|
||||
</dt>
|
||||
"""
|
||||
assert expected in content
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'text', testroot='domain-c-c_maximum_signature_line_length',
|
||||
)
|
||||
def test_domain_c_c_maximum_signature_line_length_in_text(app, status, warning):
|
||||
app.build()
|
||||
content = (app.outdir / 'index.txt').read_text(encoding='utf8')
|
||||
param_line_fmt = STDINDENT * " " + "{}\n"
|
||||
|
||||
expected_parameter_list_hello = "(\n{})".format(param_line_fmt.format("str name,"))
|
||||
|
||||
assert expected_parameter_list_hello in content
|
||||
|
@ -8,7 +8,18 @@ import pytest
|
||||
|
||||
import sphinx.domains.cpp as cppDomain
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import desc
|
||||
from sphinx.addnodes import (
|
||||
desc,
|
||||
desc_content,
|
||||
desc_name,
|
||||
desc_parameter,
|
||||
desc_parameterlist,
|
||||
desc_sig_name,
|
||||
desc_sig_space,
|
||||
desc_signature,
|
||||
desc_signature_line,
|
||||
pending_xref,
|
||||
)
|
||||
from sphinx.domains.cpp import (
|
||||
DefinitionError,
|
||||
DefinitionParser,
|
||||
@ -20,6 +31,7 @@ from sphinx.domains.cpp import (
|
||||
from sphinx.ext.intersphinx import load_mappings, normalize_intersphinx_mapping
|
||||
from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
from sphinx.writers.text import STDINDENT
|
||||
|
||||
|
||||
def parse(name, string):
|
||||
@ -1486,3 +1498,243 @@ def test_domain_cpp_normalize_unspecialized_template_args(make_app, app_params):
|
||||
)
|
||||
warning = app2._warning.getvalue()
|
||||
assert 'Internal C++ domain error during symbol merging' not in warning
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'cpp_maximum_signature_line_length': len('str hello(str name)'),
|
||||
})
|
||||
def test_cpp_function_signature_with_cpp_maximum_signature_line_length_equal(app):
|
||||
text = '.. cpp:function:: str hello(str name)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, 'hello']],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype='function',
|
||||
domain='cpp', objtype='function', noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, 'str']],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, 'name'],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'cpp_maximum_signature_line_length': len('str hello(str name)'),
|
||||
})
|
||||
def test_cpp_function_signature_with_cpp_maximum_signature_line_length_force_single(app):
|
||||
text = ('.. cpp:function:: str hello(str names)\n'
|
||||
' :single-line-parameter-list:')
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, 'hello']],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype='function',
|
||||
domain='cpp', objtype='function', noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, 'str']],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, 'names']),
|
||||
])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'cpp_maximum_signature_line_length': len("str hello(str name)"),
|
||||
})
|
||||
def test_cpp_function_signature_with_cpp_maximum_signature_line_length_break(app):
|
||||
text = '.. cpp:function:: str hello(str names)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, 'hello']],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype='function',
|
||||
domain='cpp', objtype='function', noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, 'str']],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, 'names']),
|
||||
])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len('str hello(str name)'),
|
||||
})
|
||||
def test_cpp_function_signature_with_maximum_signature_line_length_equal(app):
|
||||
text = '.. cpp:function:: str hello(str name)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, 'hello']],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype='function',
|
||||
domain='cpp', objtype='function', noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, 'str']],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, 'name'],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len('str hello(str name)'),
|
||||
})
|
||||
def test_cpp_function_signature_with_maximum_signature_line_length_force_single(app):
|
||||
text = ('.. cpp:function:: str hello(str names)\n'
|
||||
' :single-line-parameter-list:')
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, 'hello']],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype='function',
|
||||
domain='cpp', objtype='function', noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, 'str']],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, 'names']),
|
||||
])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("str hello(str name)"),
|
||||
})
|
||||
def test_cpp_function_signature_with_maximum_signature_line_length_break(app):
|
||||
text = '.. cpp:function:: str hello(str names)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_signature_line, (
|
||||
pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, 'hello']],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype='function',
|
||||
domain='cpp', objtype='function', noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, 'str']],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, 'names']),
|
||||
])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'cpp_maximum_signature_line_length': len('str hello(str name)'),
|
||||
'maximum_signature_line_length': 1,
|
||||
})
|
||||
def test_cpp_maximum_signature_line_length_overrides_global(app):
|
||||
text = '.. cpp:function:: str hello(str name)'
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, ([desc_signature, ([desc_signature_line, (pending_xref,
|
||||
desc_sig_space,
|
||||
[desc_name, [desc_sig_name, "hello"]],
|
||||
desc_parameterlist)])],
|
||||
desc_content)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype='function',
|
||||
domain='cpp', objtype='function', noindex=False)
|
||||
assert_node(doctree[1][0][0][3], [desc_parameterlist, desc_parameter, (
|
||||
[pending_xref, [desc_sig_name, 'str']],
|
||||
desc_sig_space,
|
||||
[desc_sig_name, 'name'],
|
||||
)])
|
||||
assert_node(doctree[1][0][0][3], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='domain-cpp-cpp_maximum_signature_line_length')
|
||||
def test_domain_cpp_cpp_maximum_signature_line_length_in_html(app, status, warning):
|
||||
app.build()
|
||||
content = (app.outdir / 'index.html').read_text(encoding='utf-8')
|
||||
expected = """\
|
||||
|
||||
<dl>
|
||||
<dd>\
|
||||
<span class="n"><span class="pre">str</span></span>\
|
||||
<span class="w"> </span>\
|
||||
<span class="n sig-param"><span class="pre">name</span></span>,\
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<span class="sig-paren">)</span>\
|
||||
<a class="headerlink" href=\
|
||||
"""
|
||||
assert expected in content
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'text', testroot='domain-cpp-cpp_maximum_signature_line_length',
|
||||
)
|
||||
def test_domain_cpp_cpp_maximum_signature_line_length_in_text(app, status, warning):
|
||||
app.build()
|
||||
content = (app.outdir / 'index.txt').read_text(encoding='utf8')
|
||||
param_line_fmt = STDINDENT * " " + "{}\n"
|
||||
|
||||
expected_parameter_list_hello = "(\n{})".format(param_line_fmt.format("str name,"))
|
||||
|
||||
assert expected_parameter_list_hello in content
|
||||
|
@ -22,6 +22,7 @@ from sphinx.addnodes import (
|
||||
from sphinx.domains.javascript import JavaScriptDomain
|
||||
from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
from sphinx.writers.text import STDINDENT
|
||||
|
||||
|
||||
@pytest.mark.sphinx('dummy', testroot='domain-js')
|
||||
@ -242,3 +243,263 @@ def test_module_content_line_number(app):
|
||||
source, line = docutils.utils.get_source_line(xrefs[0])
|
||||
assert 'index.rst' in source
|
||||
assert line == 3
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'javascript_maximum_signature_line_length': len("hello(name)"),
|
||||
})
|
||||
def test_jsfunction_signature_with_javascript_maximum_signature_line_length_equal(app):
|
||||
text = ".. js:function:: hello(name)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, ([desc_sig_name, "hello"])],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], desc, desctype="function",
|
||||
domain="js", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1],
|
||||
[desc_parameterlist, desc_parameter, ([desc_sig_name, "name"])])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'javascript_maximum_signature_line_length': len("hello(name)"),
|
||||
})
|
||||
def test_jsfunction_signature_with_javascript_maximum_signature_line_length_force_single(app):
|
||||
text = (".. js:function:: hello(names)\n"
|
||||
" :single-line-parameter-list:")
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, ([desc_sig_name, "hello"])],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], desc, desctype="function",
|
||||
domain="js", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1],
|
||||
[desc_parameterlist, desc_parameter, ([desc_sig_name, "names"])])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'javascript_maximum_signature_line_length': len("hello(name)"),
|
||||
})
|
||||
def test_jsfunction_signature_with_javascript_maximum_signature_line_length_break(app):
|
||||
text = ".. js:function:: hello(names)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, ([desc_sig_name, "hello"])],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], desc, desctype="function",
|
||||
domain="js", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1],
|
||||
[desc_parameterlist, desc_parameter, ([desc_sig_name, "names"])])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("hello(name)"),
|
||||
})
|
||||
def test_jsfunction_signature_with_maximum_signature_line_length_equal(app):
|
||||
text = ".. js:function:: hello(name)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, ([desc_sig_name, "hello"])],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], desc, desctype="function",
|
||||
domain="js", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1],
|
||||
[desc_parameterlist, desc_parameter, ([desc_sig_name, "name"])])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("hello(name)"),
|
||||
})
|
||||
def test_jsfunction_signature_with_maximum_signature_line_length_force_single(app):
|
||||
text = (".. js:function:: hello(names)\n"
|
||||
" :single-line-parameter-list:")
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, ([desc_sig_name, "hello"])],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], desc, desctype="function",
|
||||
domain="js", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1],
|
||||
[desc_parameterlist, desc_parameter, ([desc_sig_name, "names"])])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("hello(name)"),
|
||||
})
|
||||
def test_jsfunction_signature_with_maximum_signature_line_length_break(app):
|
||||
text = ".. js:function:: hello(names)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, ([desc_sig_name, "hello"])],
|
||||
desc_parameterlist,
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], desc, desctype="function",
|
||||
domain="js", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1],
|
||||
[desc_parameterlist, desc_parameter, ([desc_sig_name, "names"])])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
confoverrides={
|
||||
'javascript_maximum_signature_line_length': len("hello(name)"),
|
||||
'maximum_signature_line_length': 1,
|
||||
},
|
||||
)
|
||||
def test_javascript_maximum_signature_line_length_overrides_global(app):
|
||||
text = ".. js:function:: hello(name)"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
expected_doctree = (addnodes.index,
|
||||
[desc, ([desc_signature, ([desc_name, ([desc_sig_name, "hello"])],
|
||||
desc_parameterlist)],
|
||||
desc_content)])
|
||||
assert_node(doctree, expected_doctree)
|
||||
assert_node(doctree[1], desc, desctype="function",
|
||||
domain="js", objtype="function", noindex=False)
|
||||
expected_sig = [desc_parameterlist, desc_parameter, [desc_sig_name, "name"]]
|
||||
assert_node(doctree[1][0][1], expected_sig)
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html', testroot='domain-js-javascript_maximum_signature_line_length',
|
||||
)
|
||||
def test_domain_js_javascript_maximum_signature_line_length_in_html(app, status, warning):
|
||||
app.build()
|
||||
content = (app.outdir / 'index.html').read_text(encoding='utf8')
|
||||
expected_parameter_list_hello = """\
|
||||
|
||||
<dl>
|
||||
<dd>\
|
||||
<em class="sig-param">\
|
||||
<span class="n"><span class="pre">name</span></span>\
|
||||
</em>,\
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<span class="sig-paren">)</span>\
|
||||
<a class="headerlink" href="#hello" title="Permalink to this definition">¶</a>\
|
||||
</dt>\
|
||||
"""
|
||||
assert expected_parameter_list_hello in content
|
||||
|
||||
param_line_fmt = '<dd>{}</dd>\n'
|
||||
param_name_fmt = (
|
||||
'<em class="sig-param"><span class="n"><span class="pre">{}</span></span></em>'
|
||||
)
|
||||
optional_fmt = '<span class="optional">{}</span>'
|
||||
|
||||
expected_a = param_line_fmt.format(
|
||||
optional_fmt.format("[") + param_name_fmt.format("a") + "," + optional_fmt.format("["),
|
||||
)
|
||||
assert expected_a in content
|
||||
|
||||
expected_b = param_line_fmt.format(
|
||||
param_name_fmt.format("b") + "," + optional_fmt.format("]") + optional_fmt.format("]"),
|
||||
)
|
||||
assert expected_b in content
|
||||
|
||||
expected_c = param_line_fmt.format(param_name_fmt.format("c") + ",")
|
||||
assert expected_c in content
|
||||
|
||||
expected_d = param_line_fmt.format(param_name_fmt.format("d") + optional_fmt.format("[") + ",")
|
||||
assert expected_d in content
|
||||
|
||||
expected_e = param_line_fmt.format(param_name_fmt.format("e") + ",")
|
||||
assert expected_e in content
|
||||
|
||||
expected_f = param_line_fmt.format(param_name_fmt.format("f") + "," + optional_fmt.format("]"))
|
||||
assert expected_f in content
|
||||
|
||||
expected_parameter_list_foo = """\
|
||||
|
||||
<dl>
|
||||
{}{}{}{}{}{}</dl>
|
||||
|
||||
<span class="sig-paren">)</span>\
|
||||
<a class="headerlink" href="#foo" title="Permalink to this definition">¶</a>\
|
||||
</dt>\
|
||||
""".format(expected_a, expected_b, expected_c, expected_d, expected_e, expected_f)
|
||||
assert expected_parameter_list_foo in content
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'text', testroot='domain-js-javascript_maximum_signature_line_length',
|
||||
)
|
||||
def test_domain_js_javascript_maximum_signature_line_length_in_text(app, status, warning):
|
||||
app.build()
|
||||
content = (app.outdir / 'index.txt').read_text(encoding='utf8')
|
||||
param_line_fmt = STDINDENT * " " + "{}\n"
|
||||
|
||||
expected_parameter_list_hello = "(\n{})".format(param_line_fmt.format("name,"))
|
||||
|
||||
assert expected_parameter_list_hello in content
|
||||
|
||||
expected_a = param_line_fmt.format("[a,[")
|
||||
assert expected_a in content
|
||||
|
||||
expected_b = param_line_fmt.format("b,]]")
|
||||
assert expected_b in content
|
||||
|
||||
expected_c = param_line_fmt.format("c,")
|
||||
assert expected_c in content
|
||||
|
||||
expected_d = param_line_fmt.format("d[,")
|
||||
assert expected_d in content
|
||||
|
||||
expected_e = param_line_fmt.format("e,")
|
||||
assert expected_e in content
|
||||
|
||||
expected_f = param_line_fmt.format("f,]")
|
||||
assert expected_f in content
|
||||
|
||||
expected_parameter_list_foo = "(\n{}{}{}{}{}{})".format(
|
||||
expected_a, expected_b, expected_c, expected_d, expected_e, expected_f,
|
||||
)
|
||||
assert expected_parameter_list_foo in content
|
||||
|
@ -38,6 +38,7 @@ from sphinx.domains.python import (
|
||||
)
|
||||
from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
from sphinx.writers.text import STDINDENT
|
||||
|
||||
|
||||
def parse(sig):
|
||||
@ -1460,6 +1461,308 @@ def test_signature_line_number(app, include_options):
|
||||
assert line == 1
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'python_maximum_signature_line_length': len("hello(name: str) -> str"),
|
||||
})
|
||||
def test_pyfunction_signature_with_python_maximum_signature_line_length_equal(app):
|
||||
text = ".. py:function:: hello(name: str) -> str"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, "hello"],
|
||||
desc_parameterlist,
|
||||
[desc_returns, pending_xref, "str"],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="py", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1], [desc_parameterlist, desc_parameter, (
|
||||
[desc_sig_name, "name"],
|
||||
[desc_sig_punctuation, ":"],
|
||||
desc_sig_space,
|
||||
[nodes.inline, pending_xref, "str"],
|
||||
)])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'python_maximum_signature_line_length': len("hello(name: str) -> str"),
|
||||
})
|
||||
def test_pyfunction_signature_with_python_maximum_signature_line_length_force_single(app):
|
||||
text = (".. py:function:: hello(names: str) -> str\n"
|
||||
" :single-line-parameter-list:")
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, "hello"],
|
||||
desc_parameterlist,
|
||||
[desc_returns, pending_xref, "str"],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="py", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1], [desc_parameterlist, desc_parameter, (
|
||||
[desc_sig_name, "names"],
|
||||
[desc_sig_punctuation, ":"],
|
||||
desc_sig_space,
|
||||
[nodes.inline, pending_xref, "str"],
|
||||
)])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'python_maximum_signature_line_length': len("hello(name: str) -> str"),
|
||||
})
|
||||
def test_pyfunction_signature_with_python_maximum_signature_line_length_break(app):
|
||||
text = ".. py:function:: hello(names: str) -> str"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, "hello"],
|
||||
desc_parameterlist,
|
||||
[desc_returns, pending_xref, "str"],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="py", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1], [desc_parameterlist, desc_parameter, (
|
||||
[desc_sig_name, "names"],
|
||||
[desc_sig_punctuation, ":"],
|
||||
desc_sig_space,
|
||||
[nodes.inline, pending_xref, "str"],
|
||||
)])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("hello(name: str) -> str"),
|
||||
})
|
||||
def test_pyfunction_signature_with_maximum_signature_line_length_equal(app):
|
||||
text = ".. py:function:: hello(name: str) -> str"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, "hello"],
|
||||
desc_parameterlist,
|
||||
[desc_returns, pending_xref, "str"],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="py", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1], [desc_parameterlist, desc_parameter, (
|
||||
[desc_sig_name, "name"],
|
||||
[desc_sig_punctuation, ":"],
|
||||
desc_sig_space,
|
||||
[nodes.inline, pending_xref, "str"],
|
||||
)])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("hello(name: str) -> str"),
|
||||
})
|
||||
def test_pyfunction_signature_with_maximum_signature_line_length_force_single(app):
|
||||
text = (".. py:function:: hello(names: str) -> str\n"
|
||||
" :single-line-parameter-list:")
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, "hello"],
|
||||
desc_parameterlist,
|
||||
[desc_returns, pending_xref, "str"],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="py", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1], [desc_parameterlist, desc_parameter, (
|
||||
[desc_sig_name, "names"],
|
||||
[desc_sig_punctuation, ":"],
|
||||
desc_sig_space,
|
||||
[nodes.inline, pending_xref, "str"],
|
||||
)])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', confoverrides={
|
||||
'maximum_signature_line_length': len("hello(name: str) -> str"),
|
||||
})
|
||||
def test_pyfunction_signature_with_maximum_signature_line_length_break(app):
|
||||
text = ".. py:function:: hello(names: str) -> str"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree, (
|
||||
addnodes.index,
|
||||
[desc, (
|
||||
[desc_signature, (
|
||||
[desc_name, "hello"],
|
||||
desc_parameterlist,
|
||||
[desc_returns, pending_xref, "str"],
|
||||
)],
|
||||
desc_content,
|
||||
)],
|
||||
))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="py", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][1], [desc_parameterlist, desc_parameter, (
|
||||
[desc_sig_name, "names"],
|
||||
[desc_sig_punctuation, ":"],
|
||||
desc_sig_space,
|
||||
[nodes.inline, pending_xref, "str"],
|
||||
)])
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=True)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
confoverrides={
|
||||
'python_maximum_signature_line_length': len("hello(name: str) -> str"),
|
||||
'maximum_signature_line_length': 1,
|
||||
},
|
||||
)
|
||||
def test_python_maximum_signature_line_length_overrides_global(app):
|
||||
text = ".. py:function:: hello(name: str) -> str"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
expected_doctree = (addnodes.index,
|
||||
[desc, ([desc_signature, ([desc_name, "hello"],
|
||||
desc_parameterlist,
|
||||
[desc_returns, pending_xref, "str"])],
|
||||
desc_content)])
|
||||
assert_node(doctree, expected_doctree)
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="py", objtype="function", noindex=False)
|
||||
signame_node = [desc_sig_name, "name"]
|
||||
expected_sig = [desc_parameterlist, desc_parameter, (signame_node,
|
||||
[desc_sig_punctuation, ":"],
|
||||
desc_sig_space,
|
||||
[nodes.inline, pending_xref, "str"])]
|
||||
assert_node(doctree[1][0][1], expected_sig)
|
||||
assert_node(doctree[1][0][1], desc_parameterlist, multi_line_parameter_list=False)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html', testroot='domain-py-python_maximum_signature_line_length',
|
||||
)
|
||||
def test_domain_py_python_maximum_signature_line_length_in_html(app, status, warning):
|
||||
app.build()
|
||||
content = (app.outdir / 'index.html').read_text(encoding='utf8')
|
||||
expected_parameter_list_hello = """\
|
||||
|
||||
<dl>
|
||||
<dd>\
|
||||
<em class="sig-param">\
|
||||
<span class="n"><span class="pre">name</span></span>\
|
||||
<span class="p"><span class="pre">:</span></span>\
|
||||
<span class="w"> </span>\
|
||||
<span class="n"><span class="pre">str</span></span>\
|
||||
</em>,\
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<span class="sig-paren">)</span> \
|
||||
<span class="sig-return">\
|
||||
<span class="sig-return-icon">→</span> \
|
||||
<span class="sig-return-typehint"><span class="pre">str</span></span>\
|
||||
</span>\
|
||||
<a class="headerlink" href="#hello" title="Permalink to this definition">¶</a>\
|
||||
</dt>\
|
||||
"""
|
||||
assert expected_parameter_list_hello in content
|
||||
|
||||
param_line_fmt = '<dd>{}</dd>\n'
|
||||
param_name_fmt = (
|
||||
'<em class="sig-param"><span class="n"><span class="pre">{}</span></span></em>'
|
||||
)
|
||||
optional_fmt = '<span class="optional">{}</span>'
|
||||
|
||||
expected_a = param_line_fmt.format(
|
||||
optional_fmt.format("[") + param_name_fmt.format("a") + "," + optional_fmt.format("["),
|
||||
)
|
||||
assert expected_a in content
|
||||
|
||||
expected_b = param_line_fmt.format(
|
||||
param_name_fmt.format("b") + "," + optional_fmt.format("]") + optional_fmt.format("]"),
|
||||
)
|
||||
assert expected_b in content
|
||||
|
||||
expected_c = param_line_fmt.format(param_name_fmt.format("c") + ",")
|
||||
assert expected_c in content
|
||||
|
||||
expected_d = param_line_fmt.format(param_name_fmt.format("d") + optional_fmt.format("[") + ",")
|
||||
assert expected_d in content
|
||||
|
||||
expected_e = param_line_fmt.format(param_name_fmt.format("e") + ",")
|
||||
assert expected_e in content
|
||||
|
||||
expected_f = param_line_fmt.format(param_name_fmt.format("f") + "," + optional_fmt.format("]"))
|
||||
assert expected_f in content
|
||||
|
||||
expected_parameter_list_foo = """\
|
||||
|
||||
<dl>
|
||||
{}{}{}{}{}{}</dl>
|
||||
|
||||
<span class="sig-paren">)</span>\
|
||||
<a class="headerlink" href="#foo" title="Permalink to this definition">¶</a>\
|
||||
</dt>\
|
||||
""".format(expected_a, expected_b, expected_c, expected_d, expected_e, expected_f)
|
||||
assert expected_parameter_list_foo in content
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'text', testroot='domain-py-python_maximum_signature_line_length',
|
||||
)
|
||||
def test_domain_py_python_maximum_signature_line_length_in_text(app, status, warning):
|
||||
app.build()
|
||||
content = (app.outdir / 'index.txt').read_text(encoding='utf8')
|
||||
param_line_fmt = STDINDENT * " " + "{}\n"
|
||||
|
||||
expected_parameter_list_hello = "(\n{}) -> str".format(param_line_fmt.format("name: str,"))
|
||||
|
||||
assert expected_parameter_list_hello in content
|
||||
|
||||
expected_a = param_line_fmt.format("[a,[")
|
||||
assert expected_a in content
|
||||
|
||||
expected_b = param_line_fmt.format("b,]]")
|
||||
assert expected_b in content
|
||||
|
||||
expected_c = param_line_fmt.format("c,")
|
||||
assert expected_c in content
|
||||
|
||||
expected_d = param_line_fmt.format("d[,")
|
||||
assert expected_d in content
|
||||
|
||||
expected_e = param_line_fmt.format("e,")
|
||||
assert expected_e in content
|
||||
|
||||
expected_f = param_line_fmt.format("f,]")
|
||||
assert expected_f in content
|
||||
|
||||
expected_parameter_list_foo = "(\n{}{}{}{}{}{})".format(
|
||||
expected_a, expected_b, expected_c, expected_d, expected_e, expected_f,
|
||||
)
|
||||
assert expected_parameter_list_foo in content
|
||||
|
||||
|
||||
def test_module_content_line_number(app):
|
||||
text = (".. py:module:: foo\n" +
|
||||
"\n" +
|
||||
|
Loading…
Reference in New Issue
Block a user