mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Collapse unions of `Literal
types in
stringify_annotation
` (#12325)
This commit is contained in:
parent
7953798074
commit
938d3732f8
@ -18,6 +18,9 @@ Features added
|
||||
Patch by James Addison and Adam Turner
|
||||
|
||||
.. _officially recommended: https://jinja.palletsprojects.com/en/latest/templates/#template-file-extension
|
||||
* Flatten ``Union[Literal[T], Literal[U], ...]`` to ``Literal[T, U, ...]``
|
||||
when turning annotations into strings.
|
||||
Patch by Adam Turner.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
@ -439,6 +439,15 @@ def stringify_annotation(
|
||||
# They must be a list or a tuple, otherwise they are considered 'broken'.
|
||||
annotation_args = getattr(annotation, '__args__', ())
|
||||
if annotation_args and isinstance(annotation_args, (list, tuple)):
|
||||
if (
|
||||
qualname in {'Union', 'types.UnionType'}
|
||||
and all(getattr(a, '__origin__', ...) is typing.Literal for a in annotation_args)
|
||||
):
|
||||
# special case to flatten a Union of Literals into a literal
|
||||
flattened_args = typing.Literal[annotation_args].__args__ # type: ignore[attr-defined]
|
||||
args = ', '.join(_format_literal_arg_stringify(a, mode=mode)
|
||||
for a in flattened_args)
|
||||
return f'{module_prefix}Literal[{args}]'
|
||||
if qualname in {'Optional', 'Union', 'types.UnionType'}:
|
||||
return ' | '.join(stringify_annotation(a, mode) for a in annotation_args)
|
||||
elif qualname == 'Callable':
|
||||
|
@ -359,6 +359,10 @@ def test_signature_annotations():
|
||||
sig = inspect.signature(mod.f25)
|
||||
assert stringify_signature(sig) == '(a, b, /)'
|
||||
|
||||
# collapse Literal types
|
||||
sig = inspect.signature(mod.f26)
|
||||
assert stringify_signature(sig) == "(x: typing.Literal[1, 2, 3] = 1, y: typing.Literal['a', 'b'] = 'a') -> None"
|
||||
|
||||
|
||||
def test_signature_from_str_basic():
|
||||
signature = '(a, b, *args, c=0, d="blah", **kwargs)'
|
||||
|
@ -1,6 +1,6 @@
|
||||
from inspect import Signature
|
||||
from numbers import Integral
|
||||
from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, Union
|
||||
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, TypeVar, Union
|
||||
|
||||
|
||||
def f0(x: int, y: Integral) -> None:
|
||||
@ -121,6 +121,10 @@ def f25(a, b, /):
|
||||
pass
|
||||
|
||||
|
||||
def f26(x: Literal[1, 2, 3] = 1, y: Union[Literal["a"], Literal["b"]] = "a") -> None:
|
||||
pass
|
||||
|
||||
|
||||
class Node:
|
||||
def __init__(self, parent: Optional['Node']) -> None:
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user