Skip to content

Commit 56d6a10

Browse files
Preserve type information from docstrings if no type annotation is present and parameter has default value.
Fixes #574.
1 parent 62274c9 commit 56d6a10

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

src/sphinx_autodoc_typehints/__init__.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -830,8 +830,18 @@ def _inject_signature(
830830
insert_index = len(lines)
831831

832832
if insert_index is not None:
833+
update_only = False
834+
833835
if annotation is None:
836+
# If there is no type annotation, but the type happens to exist in the input
837+
# docstring, use it as a base.
834838
type_annotation = f":type {arg_name}: "
839+
for i, line in enumerate(lines):
840+
if line.startswith(type_annotation):
841+
type_annotation = line.rstrip()
842+
insert_index = i
843+
update_only = True
844+
break
835845
else:
836846
short_literals = app.config.python_display_short_literal_types
837847
formatted_annotation = add_type_css_class(
@@ -844,7 +854,10 @@ def _inject_signature(
844854
if formatted_default:
845855
type_annotation = _append_default(app, lines, insert_index, type_annotation, formatted_default)
846856

847-
lines.insert(insert_index, type_annotation)
857+
if update_only:
858+
lines[insert_index] = type_annotation
859+
else:
860+
lines.insert(insert_index, type_annotation)
848861

849862

850863
def _append_default(
@@ -864,7 +877,10 @@ def _append_default(
864877
lines[append_index] += formatted_default
865878

866879
else: # add to last param doc line
867-
type_annotation += formatted_default
880+
if type_annotation.endswith(" "):
881+
type_annotation += formatted_default
882+
else:
883+
type_annotation = f"{type_annotation}, {formatted_default}"
868884

869885
return type_annotation
870886

tests/roots/test-dummy/dummy_module_without_complete_typehints.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,14 @@ def function_with_defaults_and_some_typehints(x: int = 0, y=None) -> str: # noq
3535
:param x: foo
3636
:param y: bar
3737
"""
38+
39+
40+
def function_with_defaults_and_type_information_in_docstring(x, y=0) -> str: # noqa: ANN001
41+
"""
42+
Function docstring.
43+
44+
:type x: int
45+
:type y: int
46+
:param x: foo
47+
:param y: bar
48+
"""

tests/test_sphinx_autodoc_typehints.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,18 @@ def test_default_annotation_without_typehints(app: SphinxTestApp, status: String
10741074
10751075
Return type:
10761076
"str"
1077+
1078+
dummy_module_without_complete_typehints.function_with_defaults_and_type_information_in_docstring(x, y=0)
1079+
1080+
Function docstring.
1081+
1082+
Parameters:
1083+
* **x** ("int") -- foo
1084+
1085+
* **y** ("int", default: "0") -- bar
1086+
1087+
Return type:
1088+
"str"
10771089
"""
10781090
assert text_contents == dedent(expected_contents)
10791091

0 commit comments

Comments
 (0)