diff --git a/README.md b/README.md index fb8cd3cd..324647a7 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ The following configuration options are accepted: - `typehints_formatter` (default: `None`): If set to a function, this function will be called with `annotation` as first argument and `sphinx.config.Config` argument second. The function is expected to return a string with reStructuredText code or `None` to fall back to the default formatter. +- `typehints_use_signature` (default: `False`): If `True`, typehints for parameters in the signature are shown. +- `typehints_use_signature_return` (default: `False`): If `True`, return annotations in the signature are shown. ## How it works diff --git a/src/sphinx_autodoc_typehints/__init__.py b/src/sphinx_autodoc_typehints/__init__.py index 6c60ff56..ae679d0d 100644 --- a/src/sphinx_autodoc_typehints/__init__.py +++ b/src/sphinx_autodoc_typehints/__init__.py @@ -254,7 +254,11 @@ def process_signature( obj = inspect.unwrap(obj) sph_signature = sphinx_signature(obj) - parameters = [param.replace(annotation=inspect.Parameter.empty) for param in sph_signature.parameters.values()] + + if app.config.typehints_use_signature: + parameters = list(sph_signature.parameters.values()) + else: + parameters = [param.replace(annotation=inspect.Parameter.empty) for param in sph_signature.parameters.values()] # if we have parameters we may need to delete first argument that's not documented, e.g. self start = 0 @@ -277,7 +281,10 @@ def process_signature( if not isinstance(method_object, (classmethod, staticmethod)): start = 1 - sph_signature = sph_signature.replace(parameters=parameters[start:], return_annotation=inspect.Signature.empty) + sph_signature = sph_signature.replace(parameters=parameters[start:]) + if not app.config.typehints_use_signature_return: + sph_signature = sph_signature.replace(return_annotation=inspect.Signature.empty) + return stringify_signature(sph_signature).replace("\\", "\\\\"), None @@ -634,6 +641,8 @@ def setup(app: Sphinx) -> dict[str, bool]: app.add_config_value("typehints_defaults", None, "env") app.add_config_value("simplify_optional_unions", True, "env") app.add_config_value("typehints_formatter", None, "env") + app.add_config_value("typehints_use_signature", False, "env") + app.add_config_value("typehints_use_signature_return", False, "env") app.connect("env-before-read-docs", validate_config) # config may be changed after “config-inited” event app.connect("autodoc-process-signature", process_signature) app.connect("autodoc-process-docstring", process_docstring) diff --git a/tests/test_sphinx_autodoc_typehints.py b/tests/test_sphinx_autodoc_typehints.py index 2e5fd8c0..8fd463bb 100644 --- a/tests/test_sphinx_autodoc_typehints.py +++ b/tests/test_sphinx_autodoc_typehints.py @@ -1033,3 +1033,91 @@ def test_sphinx_output_formatter_no_use_rtype(app: SphinxTestApp, status: String "str" -- A string """ assert text_contents == dedent(expected_contents) + + +@pytest.mark.sphinx("text", testroot="dummy") +@patch("sphinx.writers.text.MAXWIDTH", 2000) +def test_sphinx_output_with_use_signature(app: SphinxTestApp, status: StringIO) -> None: + set_python_path() + app.config.master_doc = "simple" # type: ignore # create flag + app.config.typehints_use_signature = True # type: ignore + app.build() + assert "build succeeded" in status.getvalue() + text_path = pathlib.Path(app.srcdir) / "_build" / "text" / "simple.txt" + text_contents = text_path.read_text().replace("–", "--") + expected_contents = """\ + Simple Module + ************* + + dummy_module_simple.function(x: bool, y: int = 1) + + Function docstring. + + Parameters: + * **x** ("bool") -- foo + + * **y** ("int") -- bar + + Return type: + "str" + """ + assert text_contents == dedent(expected_contents) + + +@pytest.mark.sphinx("text", testroot="dummy") +@patch("sphinx.writers.text.MAXWIDTH", 2000) +def test_sphinx_output_with_use_signature_return(app: SphinxTestApp, status: StringIO) -> None: + set_python_path() + app.config.master_doc = "simple" # type: ignore # create flag + app.config.typehints_use_signature_return = True # type: ignore + app.build() + assert "build succeeded" in status.getvalue() + text_path = pathlib.Path(app.srcdir) / "_build" / "text" / "simple.txt" + text_contents = text_path.read_text().replace("–", "--") + expected_contents = """\ + Simple Module + ************* + + dummy_module_simple.function(x, y=1) -> str + + Function docstring. + + Parameters: + * **x** ("bool") -- foo + + * **y** ("int") -- bar + + Return type: + "str" + """ + assert text_contents == dedent(expected_contents) + + +@pytest.mark.sphinx("text", testroot="dummy") +@patch("sphinx.writers.text.MAXWIDTH", 2000) +def test_sphinx_output_with_use_signature_and_return(app: SphinxTestApp, status: StringIO) -> None: + set_python_path() + app.config.master_doc = "simple" # type: ignore # create flag + app.config.typehints_use_signature = True # type: ignore + app.config.typehints_use_signature_return = True # type: ignore + app.build() + assert "build succeeded" in status.getvalue() + text_path = pathlib.Path(app.srcdir) / "_build" / "text" / "simple.txt" + text_contents = text_path.read_text().replace("–", "--") + expected_contents = """\ + Simple Module + ************* + + dummy_module_simple.function(x: bool, y: int = 1) -> str + + Function docstring. + + Parameters: + * **x** ("bool") -- foo + + * **y** ("int") -- bar + + Return type: + "str" + """ + assert text_contents == dedent(expected_contents)