diff --git a/CHANGES b/CHANGES index f42d1431b..a91349e5d 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,8 @@ Bugs fixed ---------- * #7886: autodoc: TypeError is raised on mocking generic-typed classes +* #7935: autodoc: function signature is not shown when the function has a + parameter having ``inspect._empty`` as its default value * #7839: autosummary: cannot handle umlauts in function names * #7865: autosummary: Failed to extract summary line when abbreviations found * #7866: autosummary: Failed to extract correct summary line when docstring diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 441f850d1..fc4e1c004 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -484,7 +484,13 @@ def signature(subject: Callable, bound_method: bool = False, follow_wrapped: boo if len(parameters) > 0: parameters.pop(0) - return inspect.Signature(parameters, return_annotation=return_annotation) + # To allow to create signature object correctly for pure python functions, + # pass an internal parameter __validate_parameters__=False to Signature + # + # For example, this helps a function having a default value `inspect._empty`. + # refs: https://github.com/sphinx-doc/sphinx/issues/7935 + return inspect.Signature(parameters, return_annotation=return_annotation, # type: ignore + __validate_parameters__=False) def stringify_signature(sig: inspect.Signature, show_annotation: bool = True, diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py index 6a14dc1ac..c21eaaa16 100644 --- a/tests/test_util_inspect.py +++ b/tests/test_util_inspect.py @@ -130,7 +130,7 @@ def test_signature_partialmethod(): def test_signature_annotations(): from typing_test_data import (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, - f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, Node) + f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, Node) # Class annotations sig = inspect.signature(f0) @@ -214,6 +214,10 @@ def test_signature_annotations(): sig = inspect.signature(f19) assert stringify_signature(sig) == '(*args: int, **kwargs: str)' + # default value is inspect.Signature.empty + sig = inspect.signature(f21) + assert stringify_signature(sig) == "(arg1='whatever', arg2)" + # type hints by string sig = inspect.signature(Node.children) if (3, 5, 0) <= sys.version_info < (3, 5, 3): diff --git a/tests/typing_test_data.py b/tests/typing_test_data.py index 70c3144a0..6c0357911 100644 --- a/tests/typing_test_data.py +++ b/tests/typing_test_data.py @@ -1,3 +1,4 @@ +from inspect import Signature from numbers import Integral from typing import Any, Dict, List, TypeVar, Union, Callable, Tuple, Optional @@ -100,6 +101,9 @@ def f20() -> Optional[Union[int, str]]: pass +def f21(arg1='whatever', arg2=Signature.empty): + pass + class Node: def __init__(self, parent: Optional['Node']) -> None: