@@ -500,6 +500,49 @@ def process_docstring(
500
500
delattr (app .config , "_annotation_globals" )
501
501
502
502
503
+ def _get_sphinx_line_keyword_and_argument (line : str ) -> tuple [str , str | None ] | None :
504
+ """
505
+ Extract a keyword, and its optional argument out of a sphinx field option line.
506
+
507
+ For example
508
+ >>> _get_sphinx_line_keyword_and_argument(":param parameter:")
509
+ ("param", "parameter")
510
+ >>> _get_sphinx_line_keyword_and_argument(":return:")
511
+ ("return", None)
512
+ >>> _get_sphinx_line_keyword_and_argument("some invalid line")
513
+ None
514
+ """
515
+
516
+ param_line_without_description = line .split (":" , maxsplit = 2 ) # noqa: SC200
517
+ if len (param_line_without_description ) != 3 :
518
+ return None
519
+
520
+ split_directive_and_name = param_line_without_description [1 ].split (maxsplit = 1 ) # noqa: SC200
521
+ if len (split_directive_and_name ) != 2 :
522
+ return (split_directive_and_name [0 ], None )
523
+
524
+ return tuple (split_directive_and_name ) # type: ignore
525
+
526
+
527
+ def _line_is_param_line_for_arg (line : str , arg_name : str ) -> bool :
528
+ """Return True if `line` is a valid parameter line for `arg_name`, false otherwise."""
529
+ keyword_and_name = _get_sphinx_line_keyword_and_argument (line )
530
+ if keyword_and_name is None :
531
+ return False
532
+
533
+ keyword , doc_name = keyword_and_name
534
+ if doc_name is None :
535
+ return False
536
+
537
+ if keyword not in {"param" , "parameter" , "arg" , "argument" }:
538
+ return False
539
+
540
+ for prefix in ("" , r"\*" , r"\**" , r"\*\*" ):
541
+ if doc_name == prefix + arg_name :
542
+ return True
543
+ return False
544
+
545
+
503
546
def _inject_types_to_docstring (
504
547
type_hints : dict [str , Any ],
505
548
signature : inspect .Signature | None ,
@@ -521,10 +564,12 @@ def _inject_types_to_docstring(
521
564
522
565
formatted_annotation = format_annotation (annotation , app .config )
523
566
524
- search_for = {f":{ field } { arg_name } :" for field in ("param" , "parameter" , "arg" , "argument" )}
525
567
insert_index = None
526
568
for at , line in enumerate (lines ):
527
- if any (line .startswith (search_string ) for search_string in search_for ):
569
+ if _line_is_param_line_for_arg (line , arg_name ):
570
+ # Get the arg_name from the doc to match up for type in case it has a star prefix.
571
+ # Line is in the correct format so this is guaranteed to return tuple[str, str].
572
+ _ , arg_name = _get_sphinx_line_keyword_and_argument (line ) # type: ignore[assignment, misc]
528
573
insert_index = at
529
574
break
530
575
0 commit comments