Skip to content

Commit 650fbc5

Browse files
aiudirogpre-commit-ci[bot]gaborbernat
authored
Fix KeyError with type hints on the first arg of bound methods (#200)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Bernát Gábor <[email protected]>
1 parent d50a24e commit 650fbc5

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## dev
44

55
- Fixed `normalize_source_lines()` messing with the indentation of methods with decorators that have parameters starting with `def`.
6+
- Handle `ValueError` or `TypeError` being raised when signature of an object cannot be determined
7+
- Fix `KeyError` being thrown when argument is not documented (e.g. `cls` argument for class methods, and `self` for methods)
68

79
## 1.14.0
810

src/sphinx_autodoc_typehints/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,10 @@ def process_docstring(
454454
for arg_name, annotation in type_hints.items():
455455
if arg_name == "return":
456456
continue # this is handled separately later
457-
default = inspect.Parameter.empty if signature is None else signature.parameters[arg_name].default
457+
if signature is None or arg_name not in signature.parameters:
458+
default = inspect.Parameter.empty
459+
else:
460+
default = signature.parameters[arg_name].default
458461
if arg_name.endswith("_"):
459462
arg_name = f"{arg_name[:-1]}\\_"
460463

tests/test_sphinx_autodoc_typehints.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from functools import cmp_to_key
88
from io import StringIO
99
from textwrap import dedent, indent
10-
from types import ModuleType
10+
from types import FunctionType, ModuleType
1111
from typing import (
1212
IO,
1313
Any,
@@ -54,7 +54,7 @@ def get_type(self) -> type:
5454
return type(self)
5555

5656
class Inner:
57-
pass
57+
...
5858

5959

6060
class B(Generic[T]):
@@ -63,23 +63,32 @@ class B(Generic[T]):
6363

6464

6565
class C(B[str]):
66-
pass
66+
...
6767

6868

6969
class D(typing_extensions.Protocol):
70-
pass
70+
...
7171

7272

7373
class E(typing_extensions.Protocol[T]): # type: ignore # Invariant type variable "T" used in protocol where covariant
74-
pass
74+
...
7575

7676

7777
class Slotted:
7878
__slots__ = ()
7979

8080

8181
class Metaclass(type):
82-
pass
82+
...
83+
84+
85+
class HintedMethods:
86+
@classmethod
87+
def from_magic(cls: type[T]) -> T:
88+
...
89+
90+
def method(self: T) -> T:
91+
...
8392

8493

8594
PY310_PLUS = sys.version_info >= (3, 10)
@@ -673,13 +682,13 @@ def test_normalize_source_lines_async_def() -> None:
673682
source = """
674683
async def async_function():
675684
class InnerClass:
676-
def __init__(self): pass
685+
def __init__(self): ...
677686
"""
678687

679688
expected = """
680689
async def async_function():
681690
class InnerClass:
682-
def __init__(self): pass
691+
def __init__(self): ...
683692
"""
684693

685694
assert normalize_source_lines(dedent(source)) == dedent(expected)
@@ -699,7 +708,7 @@ def test_normalize_source_lines_def_starting_decorator_parameter() -> None:
699708
),
700709
)
701710
def __init__(bound_args): # noqa: N805
702-
pass
711+
...
703712
"""
704713

705714
expected = """
@@ -715,7 +724,7 @@ def __init__(bound_args): # noqa: N805
715724
),
716725
)
717726
def __init__(bound_args): # noqa: N805
718-
pass
727+
...
719728
"""
720729

721730
assert normalize_source_lines(dedent(source)) == dedent(expected)
@@ -728,3 +737,17 @@ def test_default_no_signature(obj: Any) -> None:
728737
lines: list[str] = []
729738
process_docstring(app, "what", "name", obj, None, lines)
730739
assert lines == []
740+
741+
742+
@pytest.mark.parametrize("method", [HintedMethods.from_magic, HintedMethods().method])
743+
def test_bound_class_method(method: FunctionType) -> None:
744+
config = create_autospec(
745+
Config,
746+
typehints_fully_qualified=False,
747+
simplify_optional_unions=False,
748+
typehints_document_rtype=False,
749+
always_document_param_types=True,
750+
typehints_defaults=True,
751+
)
752+
app: Sphinx = create_autospec(Sphinx, config=config)
753+
process_docstring(app, "class", method.__qualname__, method, None, [])

0 commit comments

Comments
 (0)