@@ -251,21 +251,22 @@ def _unparse_pep_604_annotation(node: ast.Subscript) -> list[Node]:
251251
252252
253253def _parse_arglist (
254- arglist : str , env : BuildEnvironment | None = None
254+ arglist : str , env : BuildEnvironment | None = None , multiline = False
255255) -> addnodes .desc_parameterlist :
256256 """Parse a list of arguments using AST parser"""
257257 params = addnodes .desc_parameterlist (arglist )
258258 sig = signature_from_str ('(%s)' % arglist )
259259 last_kind = None
260260 for param in sig .parameters .values ():
261+ param_node = addnodes .desc_compact_content () if multiline else params
261262 if param .kind != param .POSITIONAL_ONLY and last_kind == param .POSITIONAL_ONLY :
262263 # PEP-570: Separator for Positional Only Parameter: /
263- params += addnodes .desc_parameter ('' , '' , addnodes .desc_sig_operator ('' , '/' ))
264+ param_node += addnodes .desc_parameter ('' , '' , addnodes .desc_sig_operator ('' , '/' ))
264265 if param .kind == param .KEYWORD_ONLY and last_kind in (param .POSITIONAL_OR_KEYWORD ,
265266 param .POSITIONAL_ONLY ,
266267 None ):
267268 # PEP-3102: Separator for Keyword Only Parameter: *
268- params += addnodes .desc_parameter ('' , '' , addnodes .desc_sig_operator ('' , '*' ))
269+ param_node += addnodes .desc_parameter ('' , '' , addnodes .desc_sig_operator ('' , '*' ))
269270
270271 node = addnodes .desc_parameter ()
271272 if param .kind == param .VAR_POSITIONAL :
@@ -292,7 +293,9 @@ def _parse_arglist(
292293 node += nodes .inline ('' , param .default , classes = ['default_value' ],
293294 support_smartquotes = False )
294295
295- params += node
296+ param_node += node
297+ if multiline :
298+ params += param_node
296299 last_kind = param .kind
297300
298301 if last_kind == Parameter .POSITIONAL_ONLY :
@@ -452,6 +455,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
452455 'noindex' : directives .flag ,
453456 'noindexentry' : directives .flag ,
454457 'nocontentsentry' : directives .flag ,
458+ 'singlelinesig' : directives .flag ,
455459 'module' : directives .unchanged ,
456460 'canonical' : directives .unchanged ,
457461 'annotation' : directives .unchanged ,
@@ -533,6 +537,13 @@ def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]
533537 signode ['module' ] = modname
534538 signode ['class' ] = classname
535539 signode ['fullname' ] = fullname
540+ max_len = self .env .config .python_maximum_signature_line_length
541+ multiline = (
542+ max_len >= 0
543+ and 'singlelinesig' not in self .options
544+ and len (sig ) > max_len
545+ )
546+ signode ['is_multiline' ] = multiline
536547
537548 sig_prefix = self .get_signature_prefix (sig )
538549 if sig_prefix :
@@ -553,7 +564,7 @@ def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]
553564 signode += addnodes .desc_name (name , name )
554565 if arglist :
555566 try :
556- signode += _parse_arglist (arglist , self .env )
567+ signode += _parse_arglist (arglist , self .env , multiline = multiline )
557568 except SyntaxError :
558569 # fallback to parse arglist original parser.
559570 # it supports to represent optional arguments (ex. "func(foo [, bar])")
@@ -1510,6 +1521,7 @@ def setup(app: Sphinx) -> dict[str, Any]:
15101521
15111522 app .add_domain (PythonDomain )
15121523 app .add_config_value ('python_use_unqualified_type_names' , False , 'env' )
1524+ app .add_config_value ('python_maximum_signature_line_length' , - 1 , 'env' )
15131525 app .connect ('object-description-transform' , filter_meta_fields )
15141526 app .connect ('missing-reference' , builtin_resolver , priority = 900 )
15151527
0 commit comments