mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Allow configuration of trailing commas in multi-line signatures (#12975)
Stop outputting trailing commas for C and C++, as it is invalid syntax. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com> Co-authored-by: Jakob Lykke Andersen <jakobandersen@users.noreply.github.com>
This commit is contained in:
parent
fe06909e32
commit
1418339eb9
@ -55,6 +55,11 @@ Features added
|
||||
* #7630, #4824: autodoc: Use :file:`.pyi` type stub files
|
||||
to auto-document native modules.
|
||||
Patch by Adam Turner, partially based on work by Allie Fitter.
|
||||
* #12975: Enable configuration of trailing commas in multi-line signatures
|
||||
in the Python and Javascript domains, via the new
|
||||
:confval:`python_trailing_comma_in_multi_line_signatures` and
|
||||
:confval:`javascript_trailing_comma_in_multi_line_signatures`
|
||||
configuration options.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@ -86,6 +91,7 @@ Bugs fixed
|
||||
before static methods, which themselves are rendered before regular
|
||||
methods and attributes.
|
||||
Patch by Bénédikt Tran.
|
||||
* #12975: Avoid rendering a trailing comma in C and C++ multi-line signatures.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
@ -4092,6 +4092,14 @@ Options for the Javascript domain
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. confval:: javascript_trailing_comma_in_multi_line_signatures
|
||||
:type: :code-py:`bool`
|
||||
:default: :code-py:`True`
|
||||
|
||||
Use a trailing comma in parameter lists spanning multiple lines, if true.
|
||||
|
||||
.. versionadded:: 8.2
|
||||
|
||||
|
||||
Options for the Python domain
|
||||
-----------------------------
|
||||
@ -4181,6 +4189,14 @@ Options for the Python domain
|
||||
|
||||
.. versionadded:: 7.1
|
||||
|
||||
.. confval:: python_trailing_comma_in_multi_line_signatures
|
||||
:type: :code-py:`bool`
|
||||
:default: :code-py:`True`
|
||||
|
||||
Use a trailing comma in parameter lists spanning multiple lines, if true.
|
||||
|
||||
.. versionadded:: 8.2
|
||||
|
||||
.. confval:: python_use_unqualified_type_names
|
||||
:type: :code-py:`bool`
|
||||
:default: :code-py:`False`
|
||||
|
@ -259,6 +259,8 @@ class desc_parameterlist(nodes.Part, nodes.Inline, nodes.FixedTextElement):
|
||||
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.
|
||||
A trailing comma will be added on the last line
|
||||
if ``multi_line_trailing_comma`` is True.
|
||||
"""
|
||||
|
||||
child_text_separator = ', '
|
||||
@ -273,6 +275,8 @@ class desc_type_parameter_list(nodes.Part, nodes.Inline, nodes.FixedTextElement)
|
||||
As default the type parameters list is written in line with the rest of the signature.
|
||||
Set ``multi_line_parameter_list = True`` to describe a multi-line type parameters list.
|
||||
In that case each type parameter will then be written on its own, indented line.
|
||||
A trailing comma will be added on the last line
|
||||
if ``multi_line_trailing_comma`` is True.
|
||||
"""
|
||||
|
||||
child_text_separator = ', '
|
||||
|
@ -109,6 +109,10 @@ class JSObject(ObjectDescription[tuple[str, str]]):
|
||||
and (len(sig) > max_len > 0)
|
||||
)
|
||||
|
||||
trailing_comma = (
|
||||
self.env.config.javascript_trailing_comma_in_multi_line_signatures
|
||||
)
|
||||
|
||||
display_prefix = self.get_display_prefix()
|
||||
if display_prefix:
|
||||
signode += addnodes.desc_annotation('', '', *display_prefix)
|
||||
@ -129,7 +133,12 @@ class JSObject(ObjectDescription[tuple[str, str]]):
|
||||
if not arglist:
|
||||
signode += addnodes.desc_parameterlist()
|
||||
else:
|
||||
_pseudo_parse_arglist(signode, arglist, multi_line_parameter_list)
|
||||
_pseudo_parse_arglist(
|
||||
signode,
|
||||
arglist,
|
||||
multi_line_parameter_list,
|
||||
trailing_comma,
|
||||
)
|
||||
return fullname, prefix
|
||||
|
||||
def _object_hierarchy_parts(self, sig_node: desc_signature) -> tuple[str, ...]:
|
||||
@ -564,6 +573,12 @@ def setup(app: Sphinx) -> ExtensionMetadata:
|
||||
'env',
|
||||
types=frozenset({int, type(None)}),
|
||||
)
|
||||
app.add_config_value(
|
||||
'javascript_trailing_comma_in_multi_line_signatures',
|
||||
True,
|
||||
'env',
|
||||
types=frozenset({bool}),
|
||||
)
|
||||
return {
|
||||
'version': 'builtin',
|
||||
'env_version': 3,
|
||||
|
@ -1078,6 +1078,12 @@ def setup(app: Sphinx) -> ExtensionMetadata:
|
||||
'env',
|
||||
types=frozenset({int, type(None)}),
|
||||
)
|
||||
app.add_config_value(
|
||||
'python_trailing_comma_in_multi_line_signatures',
|
||||
True,
|
||||
'env',
|
||||
types=frozenset({bool}),
|
||||
)
|
||||
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)
|
||||
|
@ -400,11 +400,15 @@ class _TypeParameterListParser(TokenProcessor):
|
||||
|
||||
|
||||
def _parse_type_list(
|
||||
tp_list: str, env: BuildEnvironment, multi_line_parameter_list: bool = False
|
||||
tp_list: str,
|
||||
env: BuildEnvironment,
|
||||
multi_line_parameter_list: bool = False,
|
||||
trailing_comma: bool = True,
|
||||
) -> addnodes.desc_type_parameter_list:
|
||||
"""Parse a list of type parameters according to PEP 695."""
|
||||
type_params = addnodes.desc_type_parameter_list(tp_list)
|
||||
type_params['multi_line_parameter_list'] = multi_line_parameter_list
|
||||
type_params['multi_line_trailing_comma'] = trailing_comma
|
||||
# formal parameter names are interpreted as type parameter names and
|
||||
# type annotations are interpreted as type parameter bound or constraints
|
||||
parser = _TypeParameterListParser(tp_list)
|
||||
@ -462,11 +466,15 @@ def _parse_type_list(
|
||||
|
||||
|
||||
def _parse_arglist(
|
||||
arglist: str, env: BuildEnvironment, multi_line_parameter_list: bool = False
|
||||
arglist: str,
|
||||
env: BuildEnvironment,
|
||||
multi_line_parameter_list: bool = False,
|
||||
trailing_comma: bool = True,
|
||||
) -> 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
|
||||
params['multi_line_trailing_comma'] = trailing_comma
|
||||
sig = signature_from_str('(%s)' % arglist)
|
||||
last_kind = None
|
||||
for param in sig.parameters.values():
|
||||
@ -522,7 +530,10 @@ def _parse_arglist(
|
||||
|
||||
|
||||
def _pseudo_parse_arglist(
|
||||
signode: desc_signature, arglist: str, multi_line_parameter_list: bool = False
|
||||
signode: desc_signature,
|
||||
arglist: str,
|
||||
multi_line_parameter_list: bool = False,
|
||||
trailing_comma: bool = True,
|
||||
) -> None:
|
||||
"""'Parse' a list of arguments separated by commas.
|
||||
|
||||
@ -532,6 +543,7 @@ def _pseudo_parse_arglist(
|
||||
"""
|
||||
paramlist = addnodes.desc_parameterlist()
|
||||
paramlist['multi_line_parameter_list'] = multi_line_parameter_list
|
||||
paramlist['multi_line_trailing_comma'] = trailing_comma
|
||||
stack: list[Element] = [paramlist]
|
||||
try:
|
||||
for argument in arglist.split(','):
|
||||
|
@ -310,6 +310,7 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
||||
and (sig_len - (arglist_span[1] - arglist_span[0])) > max_len > 0
|
||||
)
|
||||
|
||||
trailing_comma = self.env.config.python_trailing_comma_in_multi_line_signatures
|
||||
sig_prefix = self.get_signature_prefix(sig)
|
||||
if sig_prefix:
|
||||
if type(sig_prefix) is str:
|
||||
@ -332,7 +333,10 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
||||
if tp_list:
|
||||
try:
|
||||
signode += _parse_type_list(
|
||||
tp_list, self.env, multi_line_type_parameter_list
|
||||
tp_list,
|
||||
self.env,
|
||||
multi_line_type_parameter_list,
|
||||
trailing_comma,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
@ -341,19 +345,34 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
||||
|
||||
if arglist:
|
||||
try:
|
||||
signode += _parse_arglist(arglist, self.env, multi_line_parameter_list)
|
||||
signode += _parse_arglist(
|
||||
arglist,
|
||||
self.env,
|
||||
multi_line_parameter_list,
|
||||
trailing_comma,
|
||||
)
|
||||
except SyntaxError:
|
||||
# fallback to parse arglist original parser
|
||||
# (this may happen if the argument list is incorrectly used
|
||||
# as a list of bases when documenting a class)
|
||||
# it supports to represent optional arguments (ex. "func(foo [, bar])")
|
||||
_pseudo_parse_arglist(signode, arglist, multi_line_parameter_list)
|
||||
_pseudo_parse_arglist(
|
||||
signode,
|
||||
arglist,
|
||||
multi_line_parameter_list,
|
||||
trailing_comma,
|
||||
)
|
||||
except (NotImplementedError, ValueError) as exc:
|
||||
# duplicated parameter names raise ValueError and not a SyntaxError
|
||||
logger.warning(
|
||||
'could not parse arglist (%r): %s', arglist, exc, location=signode
|
||||
)
|
||||
_pseudo_parse_arglist(signode, arglist, multi_line_parameter_list)
|
||||
_pseudo_parse_arglist(
|
||||
signode,
|
||||
arglist,
|
||||
multi_line_parameter_list,
|
||||
trailing_comma,
|
||||
)
|
||||
else:
|
||||
if self.needs_arglist():
|
||||
# for callables, add an empty parameter list
|
||||
|
@ -174,6 +174,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
|
||||
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)
|
||||
self.trailing_comma = node.get('multi_line_trailing_comma', False)
|
||||
if self.multi_line_parameter_list:
|
||||
self.body.append('\n\n')
|
||||
self.body.append(self.starttag(node, 'dl'))
|
||||
@ -238,7 +239,8 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
|
||||
or is_required
|
||||
and (is_last_group or next_is_required)
|
||||
):
|
||||
self.body.append(self.param_separator)
|
||||
if not is_last_group or opt_param_left_at_level or self.trailing_comma:
|
||||
self.body.append(self.param_separator)
|
||||
self.body.append('</dd>\n')
|
||||
|
||||
elif self.required_params_left:
|
||||
@ -281,19 +283,26 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): # type: ignore[misc]
|
||||
|
||||
def depart_desc_optional(self, node: Element) -> None:
|
||||
self.optional_param_level -= 1
|
||||
level = self.optional_param_level
|
||||
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:
|
||||
max_level = self.max_optional_param_level
|
||||
len_lirp = len(self.list_is_required_param)
|
||||
is_last_group = self.param_group_index + 1 == len_lirp
|
||||
# If it's the first time we go down one level, add the separator before the
|
||||
# bracket, except if this is the last parameter and the parameter list
|
||||
# should not feature a trailing comma.
|
||||
if level == max_level - 1 and (
|
||||
not is_last_group or level > 0 or self.trailing_comma
|
||||
):
|
||||
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:
|
||||
if level == 0:
|
||||
self.body.append('</dd>\n')
|
||||
else:
|
||||
self.body.append('<span class="optional">]</span>')
|
||||
if self.optional_param_level == 0:
|
||||
if level == 0:
|
||||
self.param_group_index += 1
|
||||
|
||||
def visit_desc_annotation(self, node: Element) -> None:
|
||||
|
@ -954,6 +954,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
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)
|
||||
self.trailing_comma = node.get('multi_line_trailing_comma', False)
|
||||
|
||||
def visit_desc_parameterlist(self, node: Element) -> None:
|
||||
if self.has_tp_list:
|
||||
@ -1013,7 +1014,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if (
|
||||
opt_param_left_at_level
|
||||
or is_required
|
||||
and (is_last_group or next_is_required)
|
||||
and (next_is_required or self.trailing_comma)
|
||||
):
|
||||
self.body.append(self.param_separator)
|
||||
|
||||
@ -1055,13 +1056,20 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
|
||||
def depart_desc_optional(self, node: Element) -> None:
|
||||
self.optional_param_level -= 1
|
||||
level = self.optional_param_level
|
||||
if self.multi_line_parameter_list:
|
||||
max_level = self.max_optional_param_level
|
||||
len_lirp = len(self.list_is_required_param)
|
||||
is_last_group = self.param_group_index + 1 == len_lirp
|
||||
# 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:
|
||||
# bracket, except if this is the last parameter and the parameter list
|
||||
# should not feature a trailing comma.
|
||||
if level == max_level - 1 and (
|
||||
not is_last_group or level > 0 or self.trailing_comma
|
||||
):
|
||||
self.body.append(self.param_separator)
|
||||
self.body.append('}')
|
||||
if self.optional_param_level == 0:
|
||||
if level == 0:
|
||||
self.param_group_index += 1
|
||||
|
||||
def visit_desc_annotation(self, node: Element) -> None:
|
||||
|
@ -648,6 +648,7 @@ class TextTranslator(SphinxTranslator):
|
||||
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)
|
||||
self.trailing_comma = node.get('multi_line_trailing_comma', False)
|
||||
if self.multi_line_parameter_list:
|
||||
self.param_separator = self.param_separator.rstrip()
|
||||
self.context.append(sig_close_paren)
|
||||
@ -699,7 +700,8 @@ class TextTranslator(SphinxTranslator):
|
||||
or is_required
|
||||
and (is_last_group or next_is_required)
|
||||
):
|
||||
self.add_text(self.param_separator)
|
||||
if not is_last_group or opt_param_left_at_level or self.trailing_comma:
|
||||
self.add_text(self.param_separator)
|
||||
self.end_state(wrap=False, end=None)
|
||||
|
||||
elif self.required_params_left:
|
||||
@ -740,20 +742,27 @@ class TextTranslator(SphinxTranslator):
|
||||
|
||||
def depart_desc_optional(self, node: Element) -> None:
|
||||
self.optional_param_level -= 1
|
||||
level = self.optional_param_level
|
||||
if self.multi_line_parameter_list:
|
||||
max_level = self.max_optional_param_level
|
||||
len_lirp = len(self.list_is_required_param)
|
||||
is_last_group = self.param_group_index + 1 == len_lirp
|
||||
# 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:
|
||||
# bracket, except if this is the last parameter and the parameter list
|
||||
# should not feature a trailing comma.
|
||||
if level == max_level - 1 and (
|
||||
not is_last_group or level > 0 or self.trailing_comma
|
||||
):
|
||||
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:
|
||||
if level == 0:
|
||||
self.end_state(wrap=False, end=None)
|
||||
|
||||
else:
|
||||
self.add_text(']')
|
||||
if self.optional_param_level == 0:
|
||||
if level == 0:
|
||||
self.param_group_index += 1
|
||||
|
||||
def visit_desc_annotation(self, node: Element) -> None:
|
||||
|
@ -12,6 +12,7 @@ import pytest
|
||||
from sphinx._cli.util.errors import strip_escape_sequences
|
||||
from sphinx.builders.html import validate_html_extra_path, validate_html_static_path
|
||||
from sphinx.errors import ConfigError
|
||||
from sphinx.testing.util import etree_parse
|
||||
from sphinx.util.inventory import InventoryFile, _InventoryItem
|
||||
|
||||
from tests.test_builders.xpath_data import FIGURE_CAPTION
|
||||
@ -657,3 +658,60 @@ def test_html_pep_695_one_type_per_line(app, cached_etree_parse):
|
||||
r'.//dt[@id="MyList"][1]',
|
||||
chk('class MyList[\nT,\n](list[T])'),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='domain-py-python_maximum_signature_line_length',
|
||||
confoverrides={
|
||||
'python_maximum_signature_line_length': 1,
|
||||
'python_trailing_comma_in_multi_line_signatures': False,
|
||||
},
|
||||
)
|
||||
def test_html_pep_695_trailing_comma_in_multi_line_signatures(app):
|
||||
app.build()
|
||||
fname = app.outdir / 'index.html'
|
||||
etree = etree_parse(fname)
|
||||
|
||||
class chk:
|
||||
def __init__(self, expect: str) -> None:
|
||||
self.expect = expect
|
||||
|
||||
def __call__(self, nodes):
|
||||
assert len(nodes) == 1, nodes
|
||||
objnode = ''.join(nodes[0].itertext()).replace('\n\n', '')
|
||||
objnode = objnode.rstrip(chr(182)) # remove '¶' symbol
|
||||
objnode = objnode.strip('\n') # remove surrounding new lines
|
||||
assert objnode == self.expect
|
||||
|
||||
# each signature has a dangling ',' at the end of its parameters lists
|
||||
check_xpath(
|
||||
etree,
|
||||
fname,
|
||||
r'.//dt[@id="generic_foo"][1]',
|
||||
chk('generic_foo[\nT\n]()'),
|
||||
)
|
||||
check_xpath(
|
||||
etree,
|
||||
fname,
|
||||
r'.//dt[@id="generic_bar"][1]',
|
||||
chk('generic_bar[\nT\n](\nx: list[T]\n)'),
|
||||
)
|
||||
check_xpath(
|
||||
etree,
|
||||
fname,
|
||||
r'.//dt[@id="generic_ret"][1]',
|
||||
chk('generic_ret[\nR\n]() → R'),
|
||||
)
|
||||
check_xpath(
|
||||
etree,
|
||||
fname,
|
||||
r'.//dt[@id="MyGenericClass"][1]',
|
||||
chk('class MyGenericClass[\nX\n]'),
|
||||
)
|
||||
check_xpath(
|
||||
etree,
|
||||
fname,
|
||||
r'.//dt[@id="MyList"][1]',
|
||||
chk('class MyList[\nT\n](list[T])'),
|
||||
)
|
||||
|
@ -2214,7 +2214,6 @@ def test_one_parameter_per_line(app):
|
||||
app.build(force_all=True)
|
||||
result = (app.outdir / 'projectnamenotset.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\n'
|
||||
@ -2227,6 +2226,7 @@ def test_one_parameter_per_line(app):
|
||||
'{\\sphinxbfcode{\\sphinxupquote{foo}}}\n'
|
||||
'{\\sphinxoptional{\\sphinxparam{' in result
|
||||
)
|
||||
assert r'\sphinxparam{\DUrole{n}{f}}\sphinxparamcomma' in result
|
||||
|
||||
# generic_arg[T]
|
||||
assert (
|
||||
@ -2283,6 +2283,22 @@ def test_one_parameter_per_line(app):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'latex',
|
||||
testroot='domain-py-python_maximum_signature_line_length',
|
||||
confoverrides={
|
||||
'python_maximum_signature_line_length': 23,
|
||||
'python_trailing_comma_in_multi_line_signatures': False,
|
||||
},
|
||||
)
|
||||
def test_one_parameter_per_line_without_trailing_comma(app):
|
||||
app.build(force_all=True)
|
||||
result = (app.outdir / 'projectnamenotset.tex').read_text(encoding='utf8')
|
||||
|
||||
assert r'\sphinxparam{\DUrole{n}{f}}\sphinxparamcomma' not in result
|
||||
assert r'\sphinxparam{\DUrole{n}{f}}}}' in result
|
||||
|
||||
|
||||
@pytest.mark.sphinx('latex', testroot='markup-rubric')
|
||||
def test_latex_rubric(app):
|
||||
app.build()
|
||||
|
@ -1374,7 +1374,7 @@ def test_domain_c_c_maximum_signature_line_length_in_html(app):
|
||||
<dd>\
|
||||
<span class="n"><span class="pre">str</span></span>\
|
||||
<span class="w"> </span>\
|
||||
<span class="n"><span class="pre">name</span></span>,\
|
||||
<span class="n"><span class="pre">name</span></span>\
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
@ -1395,6 +1395,6 @@ def test_domain_c_c_maximum_signature_line_length_in_text(app):
|
||||
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,'))
|
||||
expected_parameter_list_hello = '(\n{})'.format(param_line_fmt.format('str name'))
|
||||
|
||||
assert expected_parameter_list_hello in content
|
||||
|
@ -2426,7 +2426,7 @@ def test_domain_cpp_cpp_maximum_signature_line_length_in_html(app):
|
||||
<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>,\
|
||||
<span class="n sig-param"><span class="pre">name</span></span>\
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
@ -2445,6 +2445,6 @@ def test_domain_cpp_cpp_maximum_signature_line_length_in_text(app):
|
||||
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,'))
|
||||
expected_parameter_list_hello = '(\n{})'.format(param_line_fmt.format('str name'))
|
||||
|
||||
assert expected_parameter_list_hello in content
|
||||
|
@ -755,3 +755,121 @@ def test_domain_js_javascript_maximum_signature_line_length_in_text(app):
|
||||
expected_f,
|
||||
)
|
||||
assert expected_parameter_list_foo in content
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='domain-js-javascript_maximum_signature_line_length',
|
||||
confoverrides={'javascript_trailing_comma_in_multi_line_signatures': False},
|
||||
)
|
||||
def test_domain_js_javascript_trailing_comma_in_multi_line_signatures_in_html(app):
|
||||
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="Link 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="Link 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',
|
||||
freshenv=True,
|
||||
confoverrides={'javascript_trailing_comma_in_multi_line_signatures': False},
|
||||
)
|
||||
def test_domain_js_javascript_trailing_comma_in_multi_line_signatures_in_text(app):
|
||||
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
|
||||
|
@ -1073,6 +1073,133 @@ def test_domain_py_python_maximum_signature_line_length_in_text(app):
|
||||
assert expected_parameter_list_foo in content
|
||||
|
||||
|
||||
@pytest.mark.sphinx(
|
||||
'html',
|
||||
testroot='domain-py-python_maximum_signature_line_length',
|
||||
confoverrides={'python_trailing_comma_in_multi_line_signatures': False},
|
||||
)
|
||||
def test_domain_py_python_trailing_comma_in_multi_line_signatures_in_html(app):
|
||||
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="Link 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="Link 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',
|
||||
freshenv=True,
|
||||
confoverrides={'python_trailing_comma_in_multi_line_signatures': False},
|
||||
)
|
||||
def test_domain_py_python_trailing_comma_in_multi_line_signatures_in_text(app):
|
||||
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
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='root')
|
||||
def test_module_content_line_number(app):
|
||||
text = '.. py:module:: foo\n\n Some link here: :ref:`abc`\n'
|
||||
|
Loading…
Reference in New Issue
Block a user