Repository: tox-dev/sphinx-autodoc-typehints
Pull request #198 (2022-01-06 14:26:22)

Fixed normalize_source_lines messing with the indentation of method
 Fixed normalize_source_lines messing with the indentation of method with decorator that has parameter starting with `def`.

`normalize_source_lines` was breaking a method like the following:

```python
    @_with_parameters(
        _Parameter("self", _Parameter.POSITIONAL_OR_KEYWORD),
        *_proxy_instantiation_parameters,
        _project_id,
        _Parameter(
            "node_numbers",
            _Parameter.POSITIONAL_OR_KEYWORD,
            default=None,
            annotation=Optional[Iterable[int]],
        ),
    )
    def __init__(bound_args):  # noqa: N805
        ...
```

Note the decorator parameter `default=None,` starts with `def` and confuses the function.

I got to this fix from #139.

scganterh: > Needs a test and changelog entry.

I am not sure how to add the changelog entry. Should I add a new version?
gaborbernat: > I am not sure how to add the changelog entry. Should I add a new version?

 Just use version name dev 👍 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb3426f..20c6f18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## dev
+
+- Fixed `normalize_source_lines()` messing with the indentation of methods with decorators that have parameters starting with `def`.
+
 ## 1.14.0
 
 - Added `typehints_defaults` config option allowing to automatically annotate parameter defaults.
diff --git a/src/sphinx_autodoc_typehints/__init__.py b/src/sphinx_autodoc_typehints/__init__.py
index 35e642e..477f074 100644
--- a/src/sphinx_autodoc_typehints/__init__.py
+++ b/src/sphinx_autodoc_typehints/__init__.py
@@ -176,7 +176,7 @@ def normalize_source_lines(source_lines: str) -> str:
 
     # Find the line and line number containing the function definition
     for i, l in enumerate(lines):
-        if l.lstrip().startswith("def"):
+        if l.lstrip().startswith("def "):
             idx = i
             whitespace_separator = "def"
             break


Test patch:
diff --git a/tests/test_sphinx_autodoc_typehints.py b/tests/test_sphinx_autodoc_typehints.py
index 9b398a9..8290443 100644
--- a/tests/test_sphinx_autodoc_typehints.py
+++ b/tests/test_sphinx_autodoc_typehints.py
@@ -679,3 +679,39 @@ def test_normalize_source_lines_async_def() -> None:
     """
 
     assert normalize_source_lines(dedent(source)) == dedent(expected)
+
+
+def test_normalize_source_lines_def_starting_decorator_parameter() -> None:
+    source = """
+    @_with_parameters(
+        _Parameter("self", _Parameter.POSITIONAL_OR_KEYWORD),
+        *_proxy_instantiation_parameters,
+        _project_id,
+        _Parameter(
+            "node_numbers",
+            _Parameter.POSITIONAL_OR_KEYWORD,
+            default=None,
+            annotation=Optional[Iterable[int]],
+        ),
+    )
+    def __init__(bound_args):  # noqa: N805
+        pass
+    """
+
+    expected = """
+    @_with_parameters(
+        _Parameter("self", _Parameter.POSITIONAL_OR_KEYWORD),
+        *_proxy_instantiation_parameters,
+        _project_id,
+        _Parameter(
+            "node_numbers",
+            _Parameter.POSITIONAL_OR_KEYWORD,
+            default=None,
+            annotation=Optional[Iterable[int]],
+        ),
+    )
+    def __init__(bound_args):  # noqa: N805
+        pass
+    """
+
+    assert normalize_source_lines(dedent(source)) == dedent(expected)