Skip to content

Commit 6d91418

Browse files
hoodmanepre-commit-ci[bot]gaborbernat
authored
Add module name rewrite configuration option (#474)
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 c8be42f commit 6d91418

10 files changed

+66
-7
lines changed

src/sphinx_autodoc_typehints/__init__.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,18 @@ def format_internal_tuple(t: tuple[Any, ...], config: Config) -> str:
169169
return f"({', '.join(fmt)})"
170170

171171

172+
def fixup_module_name(config: Config, module: str) -> str:
173+
if getattr(config, "typehints_fixup_module_name", None):
174+
module = config.typehints_fixup_module_name(module)
175+
176+
if module == "typing_extensions":
177+
module = "typing"
178+
179+
if module == "_io":
180+
module = "io"
181+
return module
182+
183+
172184
def format_annotation(annotation: Any, config: Config) -> str: # noqa: C901, PLR0911, PLR0912, PLR0915, PLR0914
173185
"""
174186
Format the annotation.
@@ -204,13 +216,7 @@ def format_annotation(annotation: Any, config: Config) -> str: # noqa: C901, PL
204216
except ValueError:
205217
return str(annotation).strip("'")
206218

207-
# Redirect all typing_extensions types to the stdlib typing module
208-
if module == "typing_extensions":
209-
module = "typing"
210-
211-
if module == "_io":
212-
module = "io"
213-
219+
module = fixup_module_name(config, module)
214220
full_name = f"{module}.{class_name}" if module != "builtins" else class_name
215221
fully_qualified: bool = getattr(config, "typehints_fully_qualified", False)
216222
prefix = "" if fully_qualified or full_name == class_name else "~"
@@ -967,6 +973,7 @@ def setup(app: Sphinx) -> dict[str, bool]:
967973
app.add_config_value("typehints_formatter", None, "env")
968974
app.add_config_value("typehints_use_signature", False, "env") # noqa: FBT003
969975
app.add_config_value("typehints_use_signature_return", False, "env") # noqa: FBT003
976+
app.add_config_value("typehints_fixup_module_name", None, "env")
970977
app.add_role("sphinx_autodoc_typehints_type", sphinx_autodoc_typehints_type_role)
971978
app.connect("env-before-read-docs", validate_config) # config may be changed after “config-inited” event
972979
app.connect("autodoc-process-signature", process_signature)
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from __future__ import annotations
2+
3+
from wrong_module_path import A, f
4+
5+
__all__ = ["A", "f"]

tests/roots/test-dummy/future_annotations.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
:orphan:
2+
13
Dummy Module
24
============
35

tests/roots/test-dummy/simple.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
:orphan:
2+
13
Simple Module
24
=============
35

tests/roots/test-dummy/simple_default_role.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
:orphan:
2+
13
Simple Module
24
=============
35

tests/roots/test-dummy/simple_no_use_rtype.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
:orphan:
2+
13
Simple Module
24
=============
35

tests/roots/test-dummy/without_complete_typehints.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
:orphan:
2+
13
Simple Module
24
=============
35

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from __future__ import annotations
2+
3+
4+
class A:
5+
pass
6+
7+
8+
def f() -> A:
9+
pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:orphan:
2+
3+
.. class:: export_module.A
4+
5+
.. autofunction:: export_module.f

tests/test_sphinx_autodoc_typehints.py

+23
Original file line numberDiff line numberDiff line change
@@ -1123,3 +1123,26 @@ def test_default_annotation_without_typehints(app: SphinxTestApp, status: String
11231123
"str"
11241124
"""
11251125
assert text_contents == dedent(expected_contents)
1126+
1127+
1128+
@pytest.mark.sphinx("text", testroot="dummy")
1129+
@patch("sphinx.writers.text.MAXWIDTH", 2000)
1130+
def test_wrong_module_path(app: SphinxTestApp, status: StringIO, warning: StringIO) -> None:
1131+
set_python_path()
1132+
1133+
app.config.master_doc = "wrong_module_path" # create flag
1134+
app.config.default_role = "literal"
1135+
app.config.nitpicky = True
1136+
app.config.nitpick_ignore = {("py:data", "typing.Optional")}
1137+
1138+
def fixup_module_name(mod: str) -> str:
1139+
if not mod.startswith("wrong_module_path"):
1140+
return mod
1141+
return "export_module" + mod.removeprefix("wrong_module_path")
1142+
1143+
app.config.suppress_warnings = ["config.cache"]
1144+
app.config.typehints_fixup_module_name = fixup_module_name
1145+
app.build()
1146+
1147+
assert "build succeeded" in status.getvalue() # Build succeeded
1148+
assert not warning.getvalue().strip()

0 commit comments

Comments
 (0)