Skip to content

Commit

Permalink
Validate modes in sphinx.util.typing
Browse files Browse the repository at this point in the history
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
  • Loading branch information
AA-Turner and picnixz committed Apr 22, 2024
1 parent 9ee1f64 commit e666f99
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 9 deletions.
4 changes: 2 additions & 2 deletions sphinx/ext/autodoc/typehints.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ def record_typehints(app: Sphinx, objtype: str, name: str, obj: Any,
sig = inspect.signature(obj, type_aliases=app.config.autodoc_type_aliases)
for param in sig.parameters.values():
if param.annotation is not param.empty:
annotation[param.name] = stringify_annotation(param.annotation, mode)
annotation[param.name] = stringify_annotation(param.annotation, mode) # type: ignore[arg-type]
if sig.return_annotation is not sig.empty:
annotation['return'] = stringify_annotation(sig.return_annotation, mode)
annotation['return'] = stringify_annotation(sig.return_annotation, mode) # type: ignore[arg-type]
except (TypeError, ValueError):
pass

Expand Down
4 changes: 2 additions & 2 deletions sphinx/util/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ def stringify_signature(

if show_annotation and param.annotation is not EMPTY:
arg.write(': ')
arg.write(stringify_annotation(param.annotation, mode))
arg.write(stringify_annotation(param.annotation, mode)) # type: ignore[arg-type]
if param.default is not EMPTY:
if show_annotation and param.annotation is not EMPTY:
arg.write(' = ')
Expand All @@ -771,7 +771,7 @@ def stringify_signature(
if sig.return_annotation is EMPTY or not show_annotation or not show_return_annotation:
return f'({concatenated_args})'
else:
retann = stringify_annotation(sig.return_annotation, mode)
retann = stringify_annotation(sig.return_annotation, mode) # type: ignore[arg-type]
return f'({concatenated_args}) -> {retann}'


Expand Down
31 changes: 26 additions & 5 deletions sphinx/util/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,22 @@
from docutils.parsers.rst.states import Inliner

if TYPE_CHECKING:
from typing import Literal

from typing_extensions import TypeAlias

from sphinx.application import Sphinx

_RestifyMode: TypeAlias = Literal[
'fully-qualified-except-typing',
'smart',
]
_StringifyMode: TypeAlias = Literal[
'fully-qualified-except-typing',
'fully-qualified',
'smart',
]

if sys.version_info >= (3, 10):
from types import UnionType
else:
Expand Down Expand Up @@ -145,7 +159,7 @@ def is_system_TypeVar(typ: Any) -> bool:
return modname == 'typing' and isinstance(typ, TypeVar)


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

valid_modes = {'fully-qualified-except-typing', 'smart'}
if mode not in valid_modes:
valid = ', '.join(map(repr, sorted(valid_modes)))
msg = f'mode must be one of {valid}; got {mode!r}'
raise ValueError(msg)

# If the mode is 'smart', we always use '~'.
# If the mode is 'fully-qualified-except-typing',
# we use '~' only for the objects in the ``typing`` module.
Expand Down Expand Up @@ -263,7 +283,7 @@ def _format_literal_arg_restify(arg: Any, /, *, mode: str) -> str:
def stringify_annotation(
annotation: Any,
/,
mode: str = 'fully-qualified-except-typing',
mode: _StringifyMode = 'fully-qualified-except-typing',
) -> str:
"""Stringify type annotation object.
Expand All @@ -281,9 +301,10 @@ def stringify_annotation(
from sphinx.ext.autodoc.mock import ismock, ismockmodule # lazy loading
from sphinx.util.inspect import isNewType # lazy loading

if mode not in {'fully-qualified-except-typing', 'fully-qualified', 'smart'}:
msg = ("'mode' must be one of 'fully-qualified-except-typing', "
f"'fully-qualified', or 'smart'; got {mode!r}.")
valid_modes = {'fully-qualified-except-typing', 'fully-qualified', 'smart'}
if mode not in valid_modes:
valid = ', '.join(map(repr, sorted(valid_modes)))
msg = f'mode must be one of {valid}; got {mode!r}'
raise ValueError(msg)

if mode == 'smart':
Expand Down

0 comments on commit e666f99

Please sign in to comment.