@@ -225,21 +225,22 @@ def unparse(node: ast.AST) -> List[Node]:
225225
226226
227227def _parse_arglist (
228- arglist : str , env : Optional [BuildEnvironment ] = None
228+ arglist : str , env : Optional [BuildEnvironment ] = None , multiline = False
229229) -> addnodes .desc_parameterlist :
230230 """Parse a list of arguments using AST parser"""
231231 params = addnodes .desc_parameterlist (arglist )
232232 sig = signature_from_str ('(%s)' % arglist )
233233 last_kind = None
234234 for param in sig .parameters .values ():
235+ param_node = addnodes .desc_compact_content () if multiline else params
235236 if param .kind != param .POSITIONAL_ONLY and last_kind == param .POSITIONAL_ONLY :
236237 # PEP-570: Separator for Positional Only Parameter: /
237- params += addnodes .desc_parameter ('' , '' , addnodes .desc_sig_operator ('' , '/' ))
238+ param_node += addnodes .desc_parameter ('' , '' , addnodes .desc_sig_operator ('' , '/' ))
238239 if param .kind == param .KEYWORD_ONLY and last_kind in (param .POSITIONAL_OR_KEYWORD ,
239240 param .POSITIONAL_ONLY ,
240241 None ):
241242 # PEP-3102: Separator for Keyword Only Parameter: *
242- params += addnodes .desc_parameter ('' , '' , addnodes .desc_sig_operator ('' , '*' ))
243+ param_node += addnodes .desc_parameter ('' , '' , addnodes .desc_sig_operator ('' , '*' ))
243244
244245 node = addnodes .desc_parameter ()
245246 if param .kind == param .VAR_POSITIONAL :
@@ -266,7 +267,9 @@ def _parse_arglist(
266267 node += nodes .inline ('' , param .default , classes = ['default_value' ],
267268 support_smartquotes = False )
268269
269- params += node
270+ param_node += node
271+ if multiline :
272+ params += param_node
270273 last_kind = param .kind
271274
272275 if last_kind == Parameter .POSITIONAL_ONLY :
@@ -412,6 +415,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
412415 'noindex' : directives .flag ,
413416 'noindexentry' : directives .flag ,
414417 'nocontentsentry' : directives .flag ,
418+ 'singlelinesig' : directives .flag ,
415419 'module' : directives .unchanged ,
416420 'canonical' : directives .unchanged ,
417421 'annotation' : directives .unchanged ,
@@ -493,6 +497,13 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]
493497 signode ['module' ] = modname
494498 signode ['class' ] = classname
495499 signode ['fullname' ] = fullname
500+ max_len = self .env .config .python_maximum_signature_line_length
501+ multiline = (
502+ max_len >= 0
503+ and 'singlelinesig' not in self .options
504+ and len (sig ) > max_len
505+ )
506+ signode ['is_multiline' ] = multiline
496507
497508 sig_prefix = self .get_signature_prefix (sig )
498509 if sig_prefix :
@@ -513,7 +524,7 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]
513524 signode += addnodes .desc_name (name , name )
514525 if arglist :
515526 try :
516- signode += _parse_arglist (arglist , self .env )
527+ signode += _parse_arglist (arglist , self .env , multiline = multiline )
517528 except SyntaxError :
518529 # fallback to parse arglist original parser.
519530 # it supports to represent optional arguments (ex. "func(foo [, bar])")
@@ -1470,6 +1481,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
14701481
14711482 app .add_domain (PythonDomain )
14721483 app .add_config_value ('python_use_unqualified_type_names' , False , 'env' )
1484+ app .add_config_value ('python_maximum_signature_line_length' , - 1 , 'env' )
14731485 app .connect ('object-description-transform' , filter_meta_fields )
14741486 app .connect ('missing-reference' , builtin_resolver , priority = 900 )
14751487
0 commit comments