Skip to content

Commit f4ff61a

Browse files
AA-Turnerpicnixz
andcommitted
Validate modes in sphinx.util.typing
Co-authored-by: Bénédikt Tran <[email protected]>
1 parent 827e020 commit f4ff61a

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

sphinx/ext/autodoc/typehints.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ def record_typehints(app: Sphinx, objtype: str, name: str, obj: Any,
3535
sig = inspect.signature(obj, type_aliases=app.config.autodoc_type_aliases)
3636
for param in sig.parameters.values():
3737
if param.annotation is not param.empty:
38-
annotation[param.name] = stringify_annotation(param.annotation, mode)
38+
annotation[param.name] = stringify_annotation(param.annotation, mode) # type: ignore[arg-type]
3939
if sig.return_annotation is not sig.empty:
40-
annotation['return'] = stringify_annotation(sig.return_annotation, mode)
40+
annotation['return'] = stringify_annotation(sig.return_annotation, mode) # type: ignore[arg-type]
4141
except (TypeError, ValueError):
4242
pass
4343

sphinx/util/inspect.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ def stringify_signature(
752752

753753
if show_annotation and param.annotation is not EMPTY:
754754
arg.write(': ')
755-
arg.write(stringify_annotation(param.annotation, mode))
755+
arg.write(stringify_annotation(param.annotation, mode)) # type: ignore[arg-type]
756756
if param.default is not EMPTY:
757757
if show_annotation and param.annotation is not EMPTY:
758758
arg.write(' = ')
@@ -771,7 +771,7 @@ def stringify_signature(
771771
if sig.return_annotation is EMPTY or not show_annotation or not show_return_annotation:
772772
return f'({concatenated_args})'
773773
else:
774-
retann = stringify_annotation(sig.return_annotation, mode)
774+
retann = stringify_annotation(sig.return_annotation, mode) # type: ignore[arg-type]
775775
return f'({concatenated_args}) -> {retann}'
776776

777777

sphinx/util/typing.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,22 @@
1414
from docutils.parsers.rst.states import Inliner
1515

1616
if TYPE_CHECKING:
17+
from typing import Literal
18+
19+
from typing_extensions import TypeAlias
20+
1721
from sphinx.application import Sphinx
1822

23+
_RestifyMode: TypeAlias = Literal[
24+
'fully-qualified-except-typing',
25+
'smart',
26+
]
27+
_StringifyMode: TypeAlias = Literal[
28+
'fully-qualified-except-typing',
29+
'fully-qualified',
30+
'smart',
31+
]
32+
1933
if sys.version_info >= (3, 10):
2034
from types import UnionType
2135
else:
@@ -145,7 +159,7 @@ def is_system_TypeVar(typ: Any) -> bool:
145159
return modname == 'typing' and isinstance(typ, TypeVar)
146160

147161

148-
def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> str:
162+
def restify(cls: type | None, mode: _RestifyMode = 'fully-qualified-except-typing') -> str:
149163
"""Convert python class to a reST reference.
150164
151165
:param mode: Specify a method how annotations will be stringified.
@@ -159,6 +173,12 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st
159173
from sphinx.ext.autodoc.mock import ismock, ismockmodule # lazy loading
160174
from sphinx.util import inspect # lazy loading
161175

176+
valid_modes = {'fully-qualified-except-typing', 'smart'}
177+
if mode not in valid_modes:
178+
valid = ', '.join(map(repr, sorted(valid_modes)))
179+
msg = f'mode must be one of {valid}; got {mode!r}'
180+
raise ValueError(msg)
181+
162182
# If the mode is 'smart', we always use '~'.
163183
# If the mode is 'fully-qualified-except-typing',
164184
# we use '~' only for the objects in the ``typing`` module.
@@ -263,7 +283,7 @@ def _format_literal_arg_restify(arg: Any, /, *, mode: str) -> str:
263283
def stringify_annotation(
264284
annotation: Any,
265285
/,
266-
mode: str = 'fully-qualified-except-typing',
286+
mode: _StringifyMode = 'fully-qualified-except-typing',
267287
) -> str:
268288
"""Stringify type annotation object.
269289
@@ -281,9 +301,10 @@ def stringify_annotation(
281301
from sphinx.ext.autodoc.mock import ismock, ismockmodule # lazy loading
282302
from sphinx.util.inspect import isNewType # lazy loading
283303

284-
if mode not in {'fully-qualified-except-typing', 'fully-qualified', 'smart'}:
285-
msg = ("'mode' must be one of 'fully-qualified-except-typing', "
286-
f"'fully-qualified', or 'smart'; got {mode!r}.")
304+
valid_modes = {'fully-qualified-except-typing', 'fully-qualified', 'smart'}
305+
if mode not in valid_modes:
306+
valid = ', '.join(map(repr, sorted(valid_modes)))
307+
msg = f'mode must be one of {valid}; got {mode!r}'
287308
raise ValueError(msg)
288309

289310
if mode == 'smart':

0 commit comments

Comments
 (0)