Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LaTeX: Fix #12735 about siglines with typing but no parameter list #12737

Merged
merged 13 commits into from
Aug 24, 2024
35 changes: 22 additions & 13 deletions sphinx/writers/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -743,26 +743,30 @@ def has_multi_line(e: Element) -> bool:

if multi_tp_list:
if multi_arglist:
self.body.append(CR + r'\pysigwithonelineperargwithonelinepertparg{')
self.body.append(CR + r'\pysigwithonelineperargwithonelinepertparg'
+ CR + '{')
else:
self.body.append(CR + r'\pysiglinewithargsretwithonelinepertparg{')
self.body.append(CR + r'\pysiglinewithargsretwithonelinepertparg'
+ CR + '{')
else:
if multi_arglist:
self.body.append(CR + r'\pysigwithonelineperargwithtypelist{')
self.body.append(CR + r'\pysigwithonelineperargwithtypelist'
+ CR + '{')
else:
self.body.append(CR + r'\pysiglinewithargsretwithtypelist{')
self.body.append(CR + r'\pysiglinewithargsretwithtypelist'
+ CR + '{')
break

if isinstance(child, addnodes.desc_parameterlist):
# arglist only: \macro{name}{arglist}{retann}
if has_multi_line(child):
self.body.append(CR + r'\pysigwithonelineperarg{')
self.body.append(CR + r'\pysigwithonelineperarg' + CR + '{')
else:
self.body.append(CR + r'\pysiglinewithargsret{')
self.body.append(CR + r'\pysiglinewithargsret' + CR + '{')
break
else:
# no tp_list, no arglist: \macro{name}
self.body.append(CR + r'\pysigline{')
self.body.append(CR + r'\pysigline' + CR + '{')

def _depart_signature_line(self, node: Element) -> None:
self.body.append('}')
Expand Down Expand Up @@ -863,26 +867,31 @@ def visit_desc_parameterlist(self, node: Element) -> None:
if self.has_tp_list:
if self.orphan_tp_list:
# close type parameters list (#2)
self.body.append('}{')
self.body.append('}' + CR + '{')
# empty parameters list argument (#3)
return
else:
# close name argument (#1), open parameters list argument (#2)
self.body.append('}{')
self.body.append('}' + CR + '{')
self._visit_sig_parameter_list(node, addnodes.desc_parameter)

def depart_desc_parameterlist(self, node: Element) -> None:
# close parameterlist, open return annotation
self.body.append('}{')
self.body.append('}' + CR + '{')
jfbu marked this conversation as resolved.
Show resolved Hide resolved

def visit_desc_type_parameter_list(self, node: Element) -> None:
# close name argument (#1), open type parameters list argument (#2)
self.body.append('}{')
self.body.append('}' + CR + '{')
self._visit_sig_parameter_list(node, addnodes.desc_type_parameter)

def depart_desc_type_parameter_list(self, node: Element) -> None:
# close type parameters list, open parameters list argument (#3)
self.body.append('}{')
if self.orphan_tp_list:
# this node next sibling isn't a desc_parameterlist, there are no parameters:
# close the type list, output an empty parameter list, and open return annotation.
jfbu marked this conversation as resolved.
Show resolved Hide resolved
self.body.append('}' + CR + '{}' + CR + '{')
else:
# close type parameters list, open parameters list argument (#3)
self.body.append('}' + CR + '{')

def _visit_sig_parameter(self, node: Element, parameter_macro: str) -> None:
if self.is_first_param:
Expand Down
64 changes: 46 additions & 18 deletions tests/test_builders/test_build_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -2227,43 +2227,71 @@ def test_one_parameter_per_line(app):

# 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 (
'\\pysiglinewithargsret\n'
'{\\sphinxbfcode{\\sphinxupquote{hello}}}\n'
'{\\sphinxparam{' in result
)

assert '\\pysigwithonelineperarg{\\sphinxbfcode{\\sphinxupquote{foo}}}' in result
assert (
'\\pysigwithonelineperarg\n'
'{\\sphinxbfcode{\\sphinxupquote{foo}}}\n'
'{\\sphinxoptional{\\sphinxparam{' in result
)

# generic_arg[T]
assert (
'\\pysiglinewithargsretwithtypelist{\\sphinxbfcode{\\sphinxupquote{generic\\_arg}}}'
'{\\sphinxtypeparam{\\DUrole{n}{T}}}{}{}'
) in result
'\\pysiglinewithargsretwithtypelist\n'
'{\\sphinxbfcode{\\sphinxupquote{generic\\_arg}}}\n'
'{\\sphinxtypeparam{\\DUrole{n}{T}}}\n'
'{}\n'
'{}\n' in result
)

# generic_foo[T]()
assert (
'\\pysiglinewithargsretwithtypelist{\\sphinxbfcode{\\sphinxupquote{generic\\_foo}}}'
) in result
'\\pysiglinewithargsretwithtypelist\n'
'{\\sphinxbfcode{\\sphinxupquote{generic\\_foo}}}\n'
'{\\sphinxtypeparam{\\DUrole{n}{T}}}\n'
'{}\n'
'{}\n' in result
)

# generic_bar[T](x: list[T])
assert (
'\\pysigwithonelineperargwithtypelist{\\sphinxbfcode{\\sphinxupquote{generic\\_bar}}}'
) in result
'\\pysigwithonelineperargwithtypelist\n'
'{\\sphinxbfcode{\\sphinxupquote{generic\\_bar}}}\n'
'{\\sphinxtypeparam{' in result
)

# generic_ret[R]() -> R
assert (
'\\pysiglinewithargsretwithtypelist{\\sphinxbfcode{\\sphinxupquote{generic\\_ret}}}'
'{\\sphinxtypeparam{\\DUrole{n}{R}}}{}{{ $\\rightarrow$ R}}'
) in result
'\\pysiglinewithargsretwithtypelist\n'
'{\\sphinxbfcode{\\sphinxupquote{generic\\_ret}}}\n'
'{\\sphinxtypeparam{\\DUrole{n}{R}}}\n'
'{}\n'
'{{ $\\rightarrow$ R}}\n' in result
)

# MyGenericClass[X]
assert (
'\\pysiglinewithargsretwithtypelist{\\sphinxbfcode{\\sphinxupquote{class\\DUrole{w}{ '
'}}}\\sphinxbfcode{\\sphinxupquote{MyGenericClass}}}'
) in result
'\\pysiglinewithargsretwithtypelist\n'
'{\\sphinxbfcode{\\sphinxupquote{class\\DUrole{w}{ }}}'
'\\sphinxbfcode{\\sphinxupquote{MyGenericClass}}}\n'
'{\\sphinxtypeparam{\\DUrole{n}{X}}}\n'
'{}\n'
'{}\n' in result
)

# MyList[T](list[T])
assert (
'\\pysiglinewithargsretwithtypelist{\\sphinxbfcode{\\sphinxupquote{class\\DUrole{w}{ '
'}}}\\sphinxbfcode{\\sphinxupquote{MyList}}}'
) in result
'\\pysiglinewithargsretwithtypelist\n'
'{\\sphinxbfcode{\\sphinxupquote{class\\DUrole{w}{ }}}'
'\\sphinxbfcode{\\sphinxupquote{MyList}}}\n'
'{\\sphinxtypeparam{\\DUrole{n}{T}}}\n'
'{\\sphinxparam{list{[}T{]}}}\n'
'{}\n' in result
)


@pytest.mark.sphinx('latex', testroot='markup-rubric')
Expand Down