mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
This is a more flexible approach that does not require importing several modules and types into ``sphinx.util.typing``.
1042 lines
40 KiB
Python
1042 lines
40 KiB
Python
"""Tests util.typing functions."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ctypes
|
|
import dataclasses
|
|
import sys
|
|
import typing as t
|
|
import zipfile
|
|
from collections import abc
|
|
from contextvars import Context, ContextVar, Token
|
|
from enum import Enum
|
|
from io import (
|
|
BufferedRandom,
|
|
BufferedReader,
|
|
BufferedRWPair,
|
|
BufferedWriter,
|
|
BytesIO,
|
|
FileIO,
|
|
StringIO,
|
|
TextIOWrapper,
|
|
)
|
|
from json import JSONDecoder, JSONEncoder
|
|
from lzma import LZMACompressor, LZMADecompressor
|
|
from multiprocessing import Process
|
|
from numbers import Integral
|
|
from pathlib import (
|
|
Path,
|
|
PosixPath,
|
|
PurePath,
|
|
PurePosixPath,
|
|
PureWindowsPath,
|
|
WindowsPath,
|
|
)
|
|
from pickle import Pickler, Unpickler
|
|
from struct import Struct
|
|
from types import (
|
|
AsyncGeneratorType,
|
|
BuiltinFunctionType,
|
|
BuiltinMethodType,
|
|
CellType,
|
|
ClassMethodDescriptorType,
|
|
CodeType,
|
|
CoroutineType,
|
|
EllipsisType,
|
|
FrameType,
|
|
FunctionType,
|
|
GeneratorType,
|
|
GetSetDescriptorType,
|
|
LambdaType,
|
|
MappingProxyType,
|
|
MemberDescriptorType,
|
|
MethodDescriptorType,
|
|
MethodType,
|
|
MethodWrapperType,
|
|
ModuleType,
|
|
NoneType,
|
|
NotImplementedType,
|
|
TracebackType,
|
|
WrapperDescriptorType,
|
|
)
|
|
from typing import (
|
|
Annotated,
|
|
Any,
|
|
Dict,
|
|
ForwardRef,
|
|
List,
|
|
Literal,
|
|
NewType,
|
|
Optional,
|
|
ParamSpec,
|
|
Tuple,
|
|
TypeVar,
|
|
Union,
|
|
)
|
|
from weakref import WeakSet
|
|
|
|
from sphinx.ext.autodoc.mock import mock
|
|
from sphinx.util.typing import _INVALID_BUILTIN_CLASSES, restify, stringify_annotation
|
|
|
|
|
|
class MyClass1:
|
|
pass
|
|
|
|
|
|
class MyClass2(MyClass1):
|
|
__qualname__ = '<MyClass2>'
|
|
|
|
|
|
class MyEnum(Enum):
|
|
a = 1
|
|
|
|
|
|
T = TypeVar('T')
|
|
MyInt = NewType('MyInt', int)
|
|
|
|
|
|
class MyList(List[T]):
|
|
pass
|
|
|
|
|
|
class BrokenType:
|
|
__args__ = int
|
|
|
|
|
|
@dataclasses.dataclass(frozen=True)
|
|
class Gt:
|
|
gt: float
|
|
|
|
|
|
def test_restify():
|
|
assert restify(int) == ':py:class:`int`'
|
|
assert restify(int, 'smart') == ':py:class:`int`'
|
|
|
|
assert restify(str) == ':py:class:`str`'
|
|
assert restify(str, 'smart') == ':py:class:`str`'
|
|
|
|
assert restify(None) == ':py:obj:`None`'
|
|
assert restify(None, 'smart') == ':py:obj:`None`'
|
|
|
|
assert restify(Integral) == ':py:class:`numbers.Integral`'
|
|
assert restify(Integral, 'smart') == ':py:class:`~numbers.Integral`'
|
|
|
|
assert restify(Struct) == ':py:class:`struct.Struct`'
|
|
assert restify(Struct, 'smart') == ':py:class:`~struct.Struct`'
|
|
|
|
assert restify(TracebackType) == ':py:class:`types.TracebackType`'
|
|
assert restify(TracebackType, 'smart') == ':py:class:`~types.TracebackType`'
|
|
|
|
assert restify(Path) == ':py:class:`pathlib.Path`'
|
|
assert restify(Path, 'smart') == ':py:class:`~pathlib.Path`'
|
|
|
|
assert restify(Any) == ':py:obj:`~typing.Any`'
|
|
assert restify(Any, 'smart') == ':py:obj:`~typing.Any`'
|
|
|
|
assert restify('str') == 'str'
|
|
assert restify('str', 'smart') == 'str'
|
|
|
|
|
|
def test_is_invalid_builtin_class():
|
|
# if these tests start failing, it means that the __module__
|
|
# of one of these classes has changed, and _INVALID_BUILTIN_CLASSES
|
|
# in sphinx.util.typing needs to be updated.
|
|
invalid_types = (
|
|
# contextvars
|
|
Context,
|
|
ContextVar,
|
|
Token,
|
|
# ctypes
|
|
ctypes.Array,
|
|
ctypes.Structure,
|
|
ctypes.Union,
|
|
# io
|
|
FileIO,
|
|
BytesIO,
|
|
StringIO,
|
|
BufferedReader,
|
|
BufferedWriter,
|
|
BufferedRWPair,
|
|
BufferedRandom,
|
|
TextIOWrapper,
|
|
# json
|
|
JSONDecoder,
|
|
JSONEncoder,
|
|
# lzma
|
|
LZMACompressor,
|
|
LZMADecompressor,
|
|
# multiprocessing
|
|
Process,
|
|
# pickle
|
|
Pickler,
|
|
Unpickler,
|
|
# struct
|
|
Struct,
|
|
# types
|
|
AsyncGeneratorType,
|
|
BuiltinFunctionType,
|
|
BuiltinMethodType,
|
|
CellType,
|
|
ClassMethodDescriptorType,
|
|
CodeType,
|
|
CoroutineType,
|
|
EllipsisType,
|
|
FrameType,
|
|
FunctionType,
|
|
GeneratorType,
|
|
GetSetDescriptorType,
|
|
LambdaType,
|
|
MappingProxyType,
|
|
MemberDescriptorType,
|
|
MethodDescriptorType,
|
|
MethodType,
|
|
MethodWrapperType,
|
|
ModuleType,
|
|
NoneType,
|
|
NotImplementedType,
|
|
TracebackType,
|
|
WrapperDescriptorType,
|
|
# weakref
|
|
WeakSet,
|
|
)
|
|
if sys.version_info[:2] >= (3, 12):
|
|
invalid_types += (
|
|
# zipfile
|
|
zipfile.Path,
|
|
zipfile.CompleteDirs,
|
|
)
|
|
if sys.version_info[:2] >= (3, 13):
|
|
invalid_types += (
|
|
# pathlib
|
|
Path,
|
|
PosixPath,
|
|
PurePath,
|
|
PurePosixPath,
|
|
PureWindowsPath,
|
|
WindowsPath,
|
|
)
|
|
|
|
invalid_names = {(cls.__module__, cls.__qualname__) for cls in invalid_types}
|
|
if sys.version_info[:2] < (3, 13):
|
|
invalid_names |= {
|
|
('pathlib._local', 'Path'),
|
|
('pathlib._local', 'PosixPath'),
|
|
('pathlib._local', 'PurePath'),
|
|
('pathlib._local', 'PurePosixPath'),
|
|
('pathlib._local', 'PureWindowsPath'),
|
|
('pathlib._local', 'WindowsPath'),
|
|
}
|
|
if sys.version_info[:2] < (3, 12):
|
|
invalid_names |= {
|
|
('zipfile._path', 'Path'),
|
|
('zipfile._path', 'CompleteDirs'),
|
|
}
|
|
assert _INVALID_BUILTIN_CLASSES.keys() == invalid_names
|
|
|
|
|
|
def test_restify_type_hints_containers():
|
|
assert restify(List) == ':py:class:`~typing.List`'
|
|
assert restify(Dict) == ':py:class:`~typing.Dict`'
|
|
assert restify(List[int]) == ':py:class:`~typing.List`\\ [:py:class:`int`]'
|
|
assert restify(List[str]) == ':py:class:`~typing.List`\\ [:py:class:`str`]'
|
|
assert restify(Dict[str, float]) == (
|
|
':py:class:`~typing.Dict`\\ [:py:class:`str`, :py:class:`float`]'
|
|
)
|
|
assert restify(Tuple[str, str, str]) == (
|
|
':py:class:`~typing.Tuple`\\ '
|
|
'[:py:class:`str`, :py:class:`str`, '
|
|
':py:class:`str`]'
|
|
)
|
|
ann_rst = restify(Tuple[str, ...])
|
|
assert ann_rst == ':py:class:`~typing.Tuple`\\ [:py:class:`str`, ...]'
|
|
|
|
assert restify(Tuple[()]) == ':py:class:`~typing.Tuple`'
|
|
|
|
assert restify(List[Dict[str, Tuple]]) == (
|
|
':py:class:`~typing.List`\\ '
|
|
'[:py:class:`~typing.Dict`\\ '
|
|
'[:py:class:`str`, :py:class:`~typing.Tuple`]]'
|
|
)
|
|
assert restify(MyList[Tuple[int, int]]) == (
|
|
':py:class:`tests.test_util.test_util_typing.MyList`\\ '
|
|
'[:py:class:`~typing.Tuple`\\ '
|
|
'[:py:class:`int`, :py:class:`int`]]'
|
|
)
|
|
assert restify(t.Generator[None, None, None]) == (
|
|
':py:class:`~typing.Generator`\\ '
|
|
'[:py:obj:`None`, :py:obj:`None`, '
|
|
':py:obj:`None`]'
|
|
)
|
|
assert restify(abc.Generator[None, None, None]) == (
|
|
':py:class:`collections.abc.Generator`\\ '
|
|
'[:py:obj:`None`, :py:obj:`None`, '
|
|
':py:obj:`None`]'
|
|
)
|
|
assert restify(t.Iterator[None]) == (
|
|
':py:class:`~typing.Iterator`\\ [:py:obj:`None`]'
|
|
)
|
|
assert restify(abc.Iterator[None]) == (
|
|
':py:class:`collections.abc.Iterator`\\ [:py:obj:`None`]'
|
|
)
|
|
|
|
|
|
def test_restify_Annotated():
|
|
ann_rst = restify(Annotated[str, 'foo', 'bar'])
|
|
assert ann_rst == (
|
|
":py:class:`~typing.Annotated`\\ [:py:class:`str`, 'foo', 'bar']"
|
|
)
|
|
ann_rst = restify(Annotated[str, 'foo', 'bar'], 'smart')
|
|
assert ann_rst == (
|
|
":py:class:`~typing.Annotated`\\ [:py:class:`str`, 'foo', 'bar']"
|
|
)
|
|
ann_rst = restify(Annotated[float, Gt(-10.0)])
|
|
assert ann_rst == (
|
|
':py:class:`~typing.Annotated`\\ [:py:class:`float`, :py:class:`tests.test_util.test_util_typing.Gt`\\ (gt=\\ -10.0)]'
|
|
)
|
|
ann_rst = restify(Annotated[float, Gt(-10.0)], 'smart')
|
|
assert ann_rst == (
|
|
':py:class:`~typing.Annotated`\\ [:py:class:`float`, :py:class:`~tests.test_util.test_util_typing.Gt`\\ (gt=\\ -10.0)]'
|
|
)
|
|
|
|
|
|
def test_restify_type_hints_Callable():
|
|
assert restify(t.Callable) == ':py:class:`~typing.Callable`'
|
|
assert restify(t.Callable[[str], int]) == (
|
|
':py:class:`~typing.Callable`\\ [[:py:class:`str`], :py:class:`int`]'
|
|
)
|
|
assert restify(t.Callable[..., int]) == (
|
|
':py:class:`~typing.Callable`\\ [[...], :py:class:`int`]'
|
|
)
|
|
assert restify(abc.Callable) == ':py:class:`collections.abc.Callable`'
|
|
assert restify(abc.Callable[[str], int]) == (
|
|
':py:class:`collections.abc.Callable`\\ [[:py:class:`str`], :py:class:`int`]'
|
|
)
|
|
assert restify(abc.Callable[..., int]) == (
|
|
':py:class:`collections.abc.Callable`\\ [[...], :py:class:`int`]'
|
|
)
|
|
|
|
|
|
def test_restify_type_hints_Union():
|
|
assert restify(Union[int]) == ':py:class:`int`'
|
|
assert restify(Union[int, str]) == ':py:class:`int` | :py:class:`str`'
|
|
assert restify(Optional[int]) == ':py:class:`int` | :py:obj:`None`'
|
|
|
|
assert restify(Union[str, None]) == ':py:class:`str` | :py:obj:`None`'
|
|
assert restify(Union[None, str]) == ':py:obj:`None` | :py:class:`str`'
|
|
assert restify(Optional[str]) == ':py:class:`str` | :py:obj:`None`'
|
|
|
|
assert restify(Union[int, str, None]) == (
|
|
':py:class:`int` | :py:class:`str` | :py:obj:`None`'
|
|
)
|
|
assert restify(Optional[Union[int, str]]) in {
|
|
':py:class:`str` | :py:class:`int` | :py:obj:`None`',
|
|
':py:class:`int` | :py:class:`str` | :py:obj:`None`',
|
|
}
|
|
|
|
assert restify(Union[int, Integral]) == (
|
|
':py:class:`int` | :py:class:`numbers.Integral`'
|
|
)
|
|
assert restify(Union[int, Integral], 'smart') == (
|
|
':py:class:`int` | :py:class:`~numbers.Integral`'
|
|
)
|
|
|
|
assert restify(Union[MyClass1, MyClass2]) == (
|
|
':py:class:`tests.test_util.test_util_typing.MyClass1`'
|
|
' | :py:class:`tests.test_util.test_util_typing.<MyClass2>`'
|
|
)
|
|
assert restify(Union[MyClass1, MyClass2], 'smart') == (
|
|
':py:class:`~tests.test_util.test_util_typing.MyClass1`'
|
|
' | :py:class:`~tests.test_util.test_util_typing.<MyClass2>`'
|
|
)
|
|
|
|
assert restify(Optional[Union[MyClass1, MyClass2]]) == (
|
|
':py:class:`tests.test_util.test_util_typing.MyClass1`'
|
|
' | :py:class:`tests.test_util.test_util_typing.<MyClass2>`'
|
|
' | :py:obj:`None`'
|
|
)
|
|
assert restify(Optional[Union[MyClass1, MyClass2]], 'smart') == (
|
|
':py:class:`~tests.test_util.test_util_typing.MyClass1`'
|
|
' | :py:class:`~tests.test_util.test_util_typing.<MyClass2>`'
|
|
' | :py:obj:`None`'
|
|
)
|
|
|
|
|
|
def test_restify_type_hints_typevars():
|
|
T = TypeVar('T')
|
|
T_co = TypeVar('T_co', covariant=True)
|
|
T_contra = TypeVar('T_contra', contravariant=True)
|
|
|
|
assert restify(T) == ':py:obj:`tests.test_util.test_util_typing.T`'
|
|
assert restify(T, 'smart') == ':py:obj:`~tests.test_util.test_util_typing.T`'
|
|
|
|
assert restify(T_co) == ':py:obj:`tests.test_util.test_util_typing.T_co`'
|
|
assert restify(T_co, 'smart') == ':py:obj:`~tests.test_util.test_util_typing.T_co`'
|
|
|
|
assert restify(T_contra) == ':py:obj:`tests.test_util.test_util_typing.T_contra`'
|
|
ann_rst = restify(T_contra, 'smart')
|
|
assert ann_rst == ':py:obj:`~tests.test_util.test_util_typing.T_contra`'
|
|
|
|
ann_rst = restify(List[T])
|
|
assert ann_rst == (
|
|
':py:class:`~typing.List`\\ [:py:obj:`tests.test_util.test_util_typing.T`]'
|
|
)
|
|
ann_rst = restify(List[T], 'smart')
|
|
assert ann_rst == (
|
|
':py:class:`~typing.List`\\ [:py:obj:`~tests.test_util.test_util_typing.T`]'
|
|
)
|
|
|
|
ann_rst = restify(list[T])
|
|
assert ann_rst == (
|
|
':py:class:`list`\\ [:py:obj:`tests.test_util.test_util_typing.T`]'
|
|
)
|
|
ann_rst = restify(list[T], 'smart')
|
|
assert ann_rst == (
|
|
':py:class:`list`\\ [:py:obj:`~tests.test_util.test_util_typing.T`]'
|
|
)
|
|
|
|
assert restify(MyInt) == ':py:class:`tests.test_util.test_util_typing.MyInt`'
|
|
ann_rst = restify(MyInt, 'smart')
|
|
assert ann_rst == ':py:class:`~tests.test_util.test_util_typing.MyInt`'
|
|
|
|
|
|
def test_restify_type_hints_custom_class():
|
|
assert restify(MyClass1) == ':py:class:`tests.test_util.test_util_typing.MyClass1`'
|
|
ann_rst = restify(MyClass1, 'smart')
|
|
assert ann_rst == ':py:class:`~tests.test_util.test_util_typing.MyClass1`'
|
|
|
|
ann_rst = restify(MyClass2)
|
|
assert ann_rst == ':py:class:`tests.test_util.test_util_typing.<MyClass2>`'
|
|
ann_rst = restify(MyClass2, 'smart')
|
|
assert ann_rst == ':py:class:`~tests.test_util.test_util_typing.<MyClass2>`'
|
|
|
|
|
|
def test_restify_type_hints_alias():
|
|
MyStr = str
|
|
MyTypingTuple = Tuple[str, str]
|
|
MyTuple = tuple[str, str]
|
|
assert restify(MyStr) == ':py:class:`str`'
|
|
ann_rst = restify(MyTypingTuple)
|
|
assert ann_rst == ':py:class:`~typing.Tuple`\\ [:py:class:`str`, :py:class:`str`]'
|
|
assert restify(MyTuple) == ':py:class:`tuple`\\ [:py:class:`str`, :py:class:`str`]'
|
|
|
|
|
|
def test_restify_type_ForwardRef():
|
|
assert restify(ForwardRef('MyInt')) == ':py:class:`MyInt`'
|
|
|
|
assert (
|
|
restify(list[ForwardRef('MyInt')]) == ':py:class:`list`\\ [:py:class:`MyInt`]'
|
|
)
|
|
|
|
ann_rst = restify(Tuple[dict[ForwardRef('MyInt'), str], list[List[int]]])
|
|
assert ann_rst == (
|
|
':py:class:`~typing.Tuple`\\ [:py:class:`dict`\\ [:py:class:`MyInt`, :py:class:`str`], :py:class:`list`\\ [:py:class:`~typing.List`\\ [:py:class:`int`]]]'
|
|
)
|
|
|
|
|
|
def test_restify_type_Literal():
|
|
ann_rst = restify(Literal[1, '2', '\r'])
|
|
assert ann_rst == ":py:obj:`~typing.Literal`\\ [1, '2', '\\r']"
|
|
|
|
ann_rst = restify(Literal[MyEnum.a], 'fully-qualified-except-typing')
|
|
assert ann_rst == (
|
|
':py:obj:`~typing.Literal`\\ [:py:attr:`tests.test_util.test_util_typing.MyEnum.a`]'
|
|
)
|
|
ann_rst = restify(Literal[MyEnum.a], 'smart')
|
|
assert ann_rst == (
|
|
':py:obj:`~typing.Literal`\\ [:py:attr:`~tests.test_util.test_util_typing.MyEnum.a`]'
|
|
)
|
|
|
|
|
|
def test_restify_pep_585():
|
|
assert restify(list[str]) == ':py:class:`list`\\ [:py:class:`str`]'
|
|
ann_rst = restify(dict[str, str])
|
|
assert ann_rst == ':py:class:`dict`\\ [:py:class:`str`, :py:class:`str`]'
|
|
assert restify(tuple[str, ...]) == ':py:class:`tuple`\\ [:py:class:`str`, ...]'
|
|
assert restify(tuple[str, str, str]) == (
|
|
':py:class:`tuple`\\ [:py:class:`str`, :py:class:`str`, :py:class:`str`]'
|
|
)
|
|
ann_rst = restify(dict[str, tuple[int, ...]])
|
|
assert ann_rst == (
|
|
':py:class:`dict`\\ '
|
|
'[:py:class:`str`, :py:class:`tuple`\\ '
|
|
'[:py:class:`int`, ...]]'
|
|
)
|
|
|
|
assert restify(tuple[()]) == ':py:class:`tuple`\\ [()]'
|
|
|
|
# Mix old typing with PEP 585
|
|
assert restify(List[dict[str, Tuple[str, ...]]]) == (
|
|
':py:class:`~typing.List`\\ '
|
|
'[:py:class:`dict`\\ '
|
|
'[:py:class:`str`, :py:class:`~typing.Tuple`\\ '
|
|
'[:py:class:`str`, ...]]]'
|
|
)
|
|
assert restify(tuple[MyList[list[int]], int]) == (
|
|
':py:class:`tuple`\\ ['
|
|
':py:class:`tests.test_util.test_util_typing.MyList`\\ '
|
|
'[:py:class:`list`\\ [:py:class:`int`]], '
|
|
':py:class:`int`]'
|
|
)
|
|
|
|
|
|
def test_restify_Unpack():
|
|
from typing_extensions import Unpack as UnpackCompat
|
|
|
|
class X(t.TypedDict):
|
|
x: int
|
|
y: int
|
|
label: str
|
|
|
|
# Unpack is considered as typing special form so we always have '~'
|
|
if sys.version_info[:2] >= (3, 12):
|
|
expect = r':py:obj:`~typing.Unpack`\ [:py:class:`X`]'
|
|
assert restify(UnpackCompat['X'], 'fully-qualified-except-typing') == expect
|
|
assert restify(UnpackCompat['X'], 'smart') == expect
|
|
else:
|
|
expect = r':py:obj:`~typing_extensions.Unpack`\ [:py:class:`X`]'
|
|
assert restify(UnpackCompat['X'], 'fully-qualified-except-typing') == expect
|
|
assert restify(UnpackCompat['X'], 'smart') == expect
|
|
|
|
expect = r':py:obj:`~typing.Unpack`\ [:py:class:`X`]'
|
|
assert restify(t.Unpack['X'], 'fully-qualified-except-typing') == expect
|
|
assert restify(t.Unpack['X'], 'smart') == expect
|
|
|
|
|
|
def test_restify_type_union_operator():
|
|
assert restify(int | None) == ':py:class:`int` | :py:obj:`None`'
|
|
assert restify(None | int) == ':py:obj:`None` | :py:class:`int`'
|
|
assert restify(int | str) == ':py:class:`int` | :py:class:`str`'
|
|
ann_rst = restify(int | str | None)
|
|
assert ann_rst == ':py:class:`int` | :py:class:`str` | :py:obj:`None`'
|
|
|
|
|
|
def test_restify_broken_type_hints():
|
|
ann_rst = restify(BrokenType)
|
|
assert ann_rst == ':py:class:`tests.test_util.test_util_typing.BrokenType`'
|
|
ann_rst = restify(BrokenType, 'smart')
|
|
assert ann_rst == ':py:class:`~tests.test_util.test_util_typing.BrokenType`'
|
|
|
|
|
|
def test_restify_mock():
|
|
with mock(['unknown']):
|
|
import unknown # type: ignore[import-not-found]
|
|
|
|
assert restify(unknown) == ':py:class:`unknown`'
|
|
assert restify(unknown.secret.Class) == ':py:class:`unknown.secret.Class`'
|
|
ann_rst = restify(unknown.secret.Class, 'smart')
|
|
assert ann_rst == ':py:class:`~unknown.secret.Class`'
|
|
|
|
|
|
def test_restify_type_hints_paramspec():
|
|
P = ParamSpec('P')
|
|
|
|
assert restify(P) == ':py:obj:`tests.test_util.test_util_typing.P`'
|
|
assert restify(P, 'smart') == ':py:obj:`~tests.test_util.test_util_typing.P`'
|
|
|
|
assert restify(P.args) == 'P.args'
|
|
assert restify(P.args, 'smart') == 'P.args'
|
|
|
|
assert restify(P.kwargs) == 'P.kwargs'
|
|
assert restify(P.kwargs, 'smart') == 'P.kwargs'
|
|
|
|
|
|
def test_stringify_annotation():
|
|
assert stringify_annotation(int, 'fully-qualified-except-typing') == 'int'
|
|
assert stringify_annotation(int, 'smart') == 'int'
|
|
|
|
assert stringify_annotation(str, 'fully-qualified-except-typing') == 'str'
|
|
assert stringify_annotation(str, 'smart') == 'str'
|
|
|
|
assert stringify_annotation(None, 'fully-qualified-except-typing') == 'None'
|
|
assert stringify_annotation(None, 'smart') == 'None'
|
|
|
|
ann_str = stringify_annotation(Integral, 'fully-qualified-except-typing')
|
|
assert ann_str == 'numbers.Integral'
|
|
assert stringify_annotation(Integral, 'smart') == '~numbers.Integral'
|
|
|
|
ann_str = stringify_annotation(Struct, 'fully-qualified-except-typing')
|
|
assert ann_str == 'struct.Struct'
|
|
assert stringify_annotation(Struct, 'smart') == '~struct.Struct'
|
|
|
|
ann_str = stringify_annotation(TracebackType, 'fully-qualified-except-typing')
|
|
assert ann_str == 'types.TracebackType'
|
|
assert stringify_annotation(TracebackType, 'smart') == '~types.TracebackType'
|
|
|
|
ann_str = stringify_annotation(Path, 'fully-qualified-except-typing')
|
|
assert ann_str == 'pathlib.Path'
|
|
assert stringify_annotation(Path, 'smart') == '~pathlib.Path'
|
|
|
|
assert stringify_annotation(Any, 'fully-qualified-except-typing') == 'Any'
|
|
assert stringify_annotation(Any, 'fully-qualified') == 'typing.Any'
|
|
assert stringify_annotation(Any, 'smart') == '~typing.Any'
|
|
|
|
|
|
def test_stringify_type_hints_containers():
|
|
assert stringify_annotation(List, 'fully-qualified-except-typing') == 'List'
|
|
assert stringify_annotation(List, 'fully-qualified') == 'typing.List'
|
|
assert stringify_annotation(List, 'smart') == '~typing.List'
|
|
|
|
assert stringify_annotation(Dict, 'fully-qualified-except-typing') == 'Dict'
|
|
assert stringify_annotation(Dict, 'fully-qualified') == 'typing.Dict'
|
|
assert stringify_annotation(Dict, 'smart') == '~typing.Dict'
|
|
|
|
ann_str = stringify_annotation(List[int], 'fully-qualified-except-typing')
|
|
assert ann_str == 'List[int]'
|
|
assert stringify_annotation(List[int], 'fully-qualified') == 'typing.List[int]'
|
|
assert stringify_annotation(List[int], 'smart') == '~typing.List[int]'
|
|
|
|
ann_str = stringify_annotation(List[str], 'fully-qualified-except-typing')
|
|
assert ann_str == 'List[str]'
|
|
assert stringify_annotation(List[str], 'fully-qualified') == 'typing.List[str]'
|
|
assert stringify_annotation(List[str], 'smart') == '~typing.List[str]'
|
|
|
|
ann_str = stringify_annotation(Dict[str, float], 'fully-qualified-except-typing')
|
|
assert ann_str == 'Dict[str, float]'
|
|
ann_str = stringify_annotation(Dict[str, float], 'fully-qualified')
|
|
assert ann_str == 'typing.Dict[str, float]'
|
|
assert stringify_annotation(Dict[str, float], 'smart') == '~typing.Dict[str, float]'
|
|
|
|
ann_str = stringify_annotation(
|
|
Tuple[str, str, str], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'Tuple[str, str, str]'
|
|
ann_str = stringify_annotation(Tuple[str, str, str], 'fully-qualified')
|
|
assert ann_str == 'typing.Tuple[str, str, str]'
|
|
ann_str = stringify_annotation(Tuple[str, str, str], 'smart')
|
|
assert ann_str == '~typing.Tuple[str, str, str]'
|
|
|
|
ann_str = stringify_annotation(Tuple[str, ...], 'fully-qualified-except-typing')
|
|
assert ann_str == 'Tuple[str, ...]'
|
|
ann_str = stringify_annotation(Tuple[str, ...], 'fully-qualified')
|
|
assert ann_str == 'typing.Tuple[str, ...]'
|
|
assert stringify_annotation(Tuple[str, ...], 'smart') == '~typing.Tuple[str, ...]'
|
|
|
|
assert stringify_annotation(Tuple[()], 'fully-qualified-except-typing') == 'Tuple'
|
|
assert stringify_annotation(Tuple[()], 'fully-qualified') == 'typing.Tuple'
|
|
assert stringify_annotation(Tuple[()], 'smart') == '~typing.Tuple'
|
|
|
|
ann_str = stringify_annotation(
|
|
List[Dict[str, Tuple]], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'List[Dict[str, Tuple]]'
|
|
ann_str = stringify_annotation(List[Dict[str, Tuple]], 'fully-qualified')
|
|
assert ann_str == 'typing.List[typing.Dict[str, typing.Tuple]]'
|
|
ann_str = stringify_annotation(List[Dict[str, Tuple]], 'smart')
|
|
assert ann_str == '~typing.List[~typing.Dict[str, ~typing.Tuple]]'
|
|
|
|
ann_str = stringify_annotation(
|
|
MyList[Tuple[int, int]], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'tests.test_util.test_util_typing.MyList[Tuple[int, int]]'
|
|
ann_str = stringify_annotation(MyList[Tuple[int, int]], 'fully-qualified')
|
|
assert ann_str == (
|
|
'tests.test_util.test_util_typing.MyList[typing.Tuple[int, int]]'
|
|
)
|
|
ann_str = stringify_annotation(MyList[Tuple[int, int]], 'smart')
|
|
assert ann_str == (
|
|
'~tests.test_util.test_util_typing.MyList[~typing.Tuple[int, int]]'
|
|
)
|
|
|
|
ann_str = stringify_annotation(
|
|
t.Generator[None, None, None], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'Generator[None, None, None]'
|
|
ann_str = stringify_annotation(t.Generator[None, None, None], 'fully-qualified')
|
|
assert ann_str == 'typing.Generator[None, None, None]'
|
|
ann_str = stringify_annotation(t.Generator[None, None, None], 'smart')
|
|
assert ann_str == '~typing.Generator[None, None, None]'
|
|
|
|
ann_str = stringify_annotation(
|
|
abc.Generator[None, None, None], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'collections.abc.Generator[None, None, None]'
|
|
ann_str = stringify_annotation(abc.Generator[None, None, None], 'fully-qualified')
|
|
assert ann_str == 'collections.abc.Generator[None, None, None]'
|
|
ann_str = stringify_annotation(abc.Generator[None, None, None], 'smart')
|
|
assert ann_str == '~collections.abc.Generator[None, None, None]'
|
|
|
|
ann_str = stringify_annotation(t.Iterator[None], 'fully-qualified-except-typing')
|
|
assert ann_str == 'Iterator[None]'
|
|
ann_str = stringify_annotation(t.Iterator[None], 'fully-qualified')
|
|
assert ann_str == 'typing.Iterator[None]'
|
|
assert stringify_annotation(t.Iterator[None], 'smart') == '~typing.Iterator[None]'
|
|
|
|
ann_str = stringify_annotation(abc.Iterator[None], 'fully-qualified-except-typing')
|
|
assert ann_str == 'collections.abc.Iterator[None]'
|
|
ann_str = stringify_annotation(abc.Iterator[None], 'fully-qualified')
|
|
assert ann_str == 'collections.abc.Iterator[None]'
|
|
ann_str = stringify_annotation(abc.Iterator[None], 'smart')
|
|
assert ann_str == '~collections.abc.Iterator[None]'
|
|
|
|
|
|
def test_stringify_type_hints_pep_585():
|
|
ann_str = stringify_annotation(list[int], 'fully-qualified-except-typing')
|
|
assert ann_str == 'list[int]'
|
|
assert stringify_annotation(list[int], 'smart') == 'list[int]'
|
|
|
|
ann_str = stringify_annotation(list[str], 'fully-qualified-except-typing')
|
|
assert ann_str == 'list[str]'
|
|
assert stringify_annotation(list[str], 'smart') == 'list[str]'
|
|
|
|
ann_str = stringify_annotation(dict[str, float], 'fully-qualified-except-typing')
|
|
assert ann_str == 'dict[str, float]'
|
|
assert stringify_annotation(dict[str, float], 'smart') == 'dict[str, float]'
|
|
|
|
ann_str = stringify_annotation(
|
|
tuple[str, str, str], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'tuple[str, str, str]'
|
|
assert stringify_annotation(tuple[str, str, str], 'smart') == 'tuple[str, str, str]'
|
|
|
|
ann_str = stringify_annotation(tuple[str, ...], 'fully-qualified-except-typing')
|
|
assert ann_str == 'tuple[str, ...]'
|
|
assert stringify_annotation(tuple[str, ...], 'smart') == 'tuple[str, ...]'
|
|
|
|
assert (
|
|
stringify_annotation(tuple[()], 'fully-qualified-except-typing') == 'tuple[()]'
|
|
)
|
|
assert stringify_annotation(tuple[()], 'smart') == 'tuple[()]'
|
|
|
|
ann_str = stringify_annotation(
|
|
list[dict[str, tuple]], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'list[dict[str, tuple]]'
|
|
ann_str = stringify_annotation(list[dict[str, tuple]], 'smart')
|
|
assert ann_str == 'list[dict[str, tuple]]'
|
|
|
|
ann_str = stringify_annotation(
|
|
MyList[tuple[int, int]], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'tests.test_util.test_util_typing.MyList[tuple[int, int]]'
|
|
ann_str = stringify_annotation(MyList[tuple[int, int]], 'fully-qualified')
|
|
assert ann_str == 'tests.test_util.test_util_typing.MyList[tuple[int, int]]'
|
|
ann_str = stringify_annotation(MyList[tuple[int, int]], 'smart')
|
|
assert ann_str == '~tests.test_util.test_util_typing.MyList[tuple[int, int]]'
|
|
|
|
ann_str = stringify_annotation(type[int], 'fully-qualified-except-typing')
|
|
assert ann_str == 'type[int]'
|
|
assert stringify_annotation(type[int], 'smart') == 'type[int]'
|
|
|
|
# Mix typing and pep 585
|
|
ann_str = stringify_annotation(
|
|
tuple[List[dict[int, str]], str, ...], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'tuple[List[dict[int, str]], str, ...]'
|
|
ann_str = stringify_annotation(tuple[List[dict[int, str]], str, ...], 'smart')
|
|
assert ann_str == 'tuple[~typing.List[dict[int, str]], str, ...]'
|
|
|
|
|
|
def test_stringify_Annotated():
|
|
ann_str = stringify_annotation(
|
|
Annotated[str, 'foo', 'bar'], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == "Annotated[str, 'foo', 'bar']"
|
|
ann_str = stringify_annotation(Annotated[str, 'foo', 'bar'], 'smart')
|
|
assert ann_str == "~typing.Annotated[str, 'foo', 'bar']"
|
|
ann_str = stringify_annotation(
|
|
Annotated[float, Gt(-10.0)], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == (
|
|
'Annotated[float, tests.test_util.test_util_typing.Gt(gt=-10.0)]'
|
|
)
|
|
ann_str = stringify_annotation(Annotated[float, Gt(-10.0)], 'smart')
|
|
assert ann_str == (
|
|
'~typing.Annotated[float, ~tests.test_util.test_util_typing.Gt(gt=-10.0)]'
|
|
)
|
|
|
|
|
|
def test_stringify_Unpack():
|
|
class X(t.TypedDict):
|
|
x: int
|
|
y: int
|
|
label: str
|
|
|
|
assert stringify_annotation(t.Unpack['X']) == 'Unpack[X]'
|
|
assert stringify_annotation(t.Unpack['X'], 'smart') == '~typing.Unpack[X]'
|
|
|
|
|
|
def test_stringify_type_hints_string():
|
|
assert stringify_annotation('int', 'fully-qualified-except-typing') == 'int'
|
|
assert stringify_annotation('int', 'fully-qualified') == 'int'
|
|
assert stringify_annotation('int', 'smart') == 'int'
|
|
|
|
assert stringify_annotation('str', 'fully-qualified-except-typing') == 'str'
|
|
assert stringify_annotation('str', 'fully-qualified') == 'str'
|
|
assert stringify_annotation('str', 'smart') == 'str'
|
|
|
|
ann_str = stringify_annotation(List['int'], 'fully-qualified-except-typing')
|
|
assert ann_str == 'List[int]'
|
|
assert stringify_annotation(List['int'], 'fully-qualified') == 'typing.List[int]'
|
|
assert stringify_annotation(List['int'], 'smart') == '~typing.List[int]'
|
|
|
|
ann_str = stringify_annotation(list['int'], 'fully-qualified-except-typing')
|
|
assert ann_str == 'list[int]'
|
|
assert stringify_annotation(list['int'], 'fully-qualified') == 'list[int]'
|
|
assert stringify_annotation(list['int'], 'smart') == 'list[int]'
|
|
|
|
ann_str = stringify_annotation('Tuple[str]', 'fully-qualified-except-typing')
|
|
assert ann_str == 'Tuple[str]'
|
|
assert stringify_annotation('Tuple[str]', 'fully-qualified') == 'Tuple[str]'
|
|
assert stringify_annotation('Tuple[str]', 'smart') == 'Tuple[str]'
|
|
|
|
ann_str = stringify_annotation('tuple[str]', 'fully-qualified-except-typing')
|
|
assert ann_str == 'tuple[str]'
|
|
assert stringify_annotation('tuple[str]', 'fully-qualified') == 'tuple[str]'
|
|
assert stringify_annotation('tuple[str]', 'smart') == 'tuple[str]'
|
|
|
|
assert stringify_annotation('unknown', 'fully-qualified-except-typing') == 'unknown'
|
|
assert stringify_annotation('unknown', 'fully-qualified') == 'unknown'
|
|
assert stringify_annotation('unknown', 'smart') == 'unknown'
|
|
|
|
|
|
def test_stringify_type_hints_Callable():
|
|
ann_str = stringify_annotation(t.Callable, 'fully-qualified-except-typing')
|
|
assert ann_str == 'Callable'
|
|
assert stringify_annotation(t.Callable, 'fully-qualified') == 'typing.Callable'
|
|
assert stringify_annotation(t.Callable, 'smart') == '~typing.Callable'
|
|
|
|
ann_str = stringify_annotation(
|
|
t.Callable[[str], int], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'Callable[[str], int]'
|
|
ann_str = stringify_annotation(t.Callable[[str], int], 'fully-qualified')
|
|
assert ann_str == 'typing.Callable[[str], int]'
|
|
ann_str = stringify_annotation(t.Callable[[str], int], 'smart')
|
|
assert ann_str == '~typing.Callable[[str], int]'
|
|
|
|
ann_str = stringify_annotation(
|
|
t.Callable[..., int], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'Callable[[...], int]'
|
|
ann_str = stringify_annotation(t.Callable[..., int], 'fully-qualified')
|
|
assert ann_str == 'typing.Callable[[...], int]'
|
|
ann_str = stringify_annotation(t.Callable[..., int], 'smart')
|
|
assert ann_str == '~typing.Callable[[...], int]'
|
|
|
|
ann_str = stringify_annotation(abc.Callable, 'fully-qualified-except-typing')
|
|
assert ann_str == 'collections.abc.Callable'
|
|
ann_str = stringify_annotation(abc.Callable, 'fully-qualified')
|
|
assert ann_str == 'collections.abc.Callable'
|
|
assert stringify_annotation(abc.Callable, 'smart') == '~collections.abc.Callable'
|
|
|
|
ann_str = stringify_annotation(
|
|
abc.Callable[[str], int], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'collections.abc.Callable[[str], int]'
|
|
ann_str = stringify_annotation(abc.Callable[[str], int], 'fully-qualified')
|
|
assert ann_str == 'collections.abc.Callable[[str], int]'
|
|
ann_str = stringify_annotation(abc.Callable[[str], int], 'smart')
|
|
assert ann_str == '~collections.abc.Callable[[str], int]'
|
|
|
|
ann_str = stringify_annotation(
|
|
abc.Callable[..., int], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'collections.abc.Callable[[...], int]'
|
|
ann_str = stringify_annotation(abc.Callable[..., int], 'fully-qualified')
|
|
assert ann_str == 'collections.abc.Callable[[...], int]'
|
|
ann_str = stringify_annotation(abc.Callable[..., int], 'smart')
|
|
assert ann_str == '~collections.abc.Callable[[...], int]'
|
|
|
|
|
|
def test_stringify_type_hints_Union():
|
|
ann_str = stringify_annotation(Optional[int], 'fully-qualified-except-typing')
|
|
assert ann_str == 'int | None'
|
|
assert stringify_annotation(Optional[int], 'fully-qualified') == 'int | None'
|
|
assert stringify_annotation(Optional[int], 'smart') == 'int | None'
|
|
|
|
ann_str = stringify_annotation(Union[int, None], 'fully-qualified-except-typing')
|
|
assert ann_str == 'int | None'
|
|
ann_str = stringify_annotation(Union[None, int], 'fully-qualified-except-typing')
|
|
assert ann_str == 'None | int'
|
|
assert stringify_annotation(Union[int, None], 'fully-qualified') == 'int | None'
|
|
assert stringify_annotation(Union[None, int], 'fully-qualified') == 'None | int'
|
|
assert stringify_annotation(Union[int, None], 'smart') == 'int | None'
|
|
assert stringify_annotation(Union[None, int], 'smart') == 'None | int'
|
|
|
|
ann_str = stringify_annotation(Union[int, str], 'fully-qualified-except-typing')
|
|
assert ann_str == 'int | str'
|
|
assert stringify_annotation(Union[int, str], 'fully-qualified') == 'int | str'
|
|
assert stringify_annotation(Union[int, str], 'smart') == 'int | str'
|
|
|
|
ann_str = stringify_annotation(
|
|
Union[int, Integral], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'int | numbers.Integral'
|
|
ann_str = stringify_annotation(Union[int, Integral], 'fully-qualified')
|
|
assert ann_str == 'int | numbers.Integral'
|
|
ann_str = stringify_annotation(Union[int, Integral], 'smart')
|
|
assert ann_str == 'int | ~numbers.Integral'
|
|
|
|
ann_str = stringify_annotation(
|
|
Union[MyClass1, MyClass2], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == (
|
|
'tests.test_util.test_util_typing.MyClass1 | tests.test_util.test_util_typing.<MyClass2>'
|
|
)
|
|
ann_str = stringify_annotation(Union[MyClass1, MyClass2], 'fully-qualified')
|
|
assert ann_str == (
|
|
'tests.test_util.test_util_typing.MyClass1 | tests.test_util.test_util_typing.<MyClass2>'
|
|
)
|
|
ann_str = stringify_annotation(Union[MyClass1, MyClass2], 'smart')
|
|
assert ann_str == (
|
|
'~tests.test_util.test_util_typing.MyClass1 | ~tests.test_util.test_util_typing.<MyClass2>'
|
|
)
|
|
|
|
|
|
def test_stringify_type_hints_typevars():
|
|
T = TypeVar('T')
|
|
T_co = TypeVar('T_co', covariant=True)
|
|
T_contra = TypeVar('T_contra', contravariant=True)
|
|
|
|
ann_str = stringify_annotation(T, 'fully-qualified-except-typing')
|
|
assert ann_str == 'tests.test_util.test_util_typing.T'
|
|
assert stringify_annotation(T, 'smart') == '~tests.test_util.test_util_typing.T'
|
|
|
|
ann_str = stringify_annotation(T_co, 'fully-qualified-except-typing')
|
|
assert ann_str == 'tests.test_util.test_util_typing.T_co'
|
|
ann_str = stringify_annotation(T_co, 'smart')
|
|
assert ann_str == '~tests.test_util.test_util_typing.T_co'
|
|
|
|
ann_str = stringify_annotation(T_contra, 'fully-qualified-except-typing')
|
|
assert ann_str == 'tests.test_util.test_util_typing.T_contra'
|
|
ann_str = stringify_annotation(T_contra, 'smart')
|
|
assert ann_str == '~tests.test_util.test_util_typing.T_contra'
|
|
|
|
ann_str = stringify_annotation(List[T], 'fully-qualified-except-typing')
|
|
assert ann_str == 'List[tests.test_util.test_util_typing.T]'
|
|
ann_str = stringify_annotation(List[T], 'smart')
|
|
assert ann_str == '~typing.List[~tests.test_util.test_util_typing.T]'
|
|
|
|
ann_str = stringify_annotation(list[T], 'fully-qualified-except-typing')
|
|
assert ann_str == 'list[tests.test_util.test_util_typing.T]'
|
|
ann_str = stringify_annotation(list[T], 'smart')
|
|
assert ann_str == 'list[~tests.test_util.test_util_typing.T]'
|
|
|
|
ann_str = stringify_annotation(MyInt, 'fully-qualified-except-typing')
|
|
assert ann_str == 'tests.test_util.test_util_typing.MyInt'
|
|
ann_str = stringify_annotation(MyInt, 'smart')
|
|
assert ann_str == '~tests.test_util.test_util_typing.MyInt'
|
|
|
|
|
|
def test_stringify_type_hints_custom_class():
|
|
ann_str = stringify_annotation(MyClass1, 'fully-qualified-except-typing')
|
|
assert ann_str == 'tests.test_util.test_util_typing.MyClass1'
|
|
ann_str = stringify_annotation(MyClass1, 'smart')
|
|
assert ann_str == '~tests.test_util.test_util_typing.MyClass1'
|
|
|
|
ann_str = stringify_annotation(MyClass2, 'fully-qualified-except-typing')
|
|
assert ann_str == 'tests.test_util.test_util_typing.<MyClass2>'
|
|
ann_str = stringify_annotation(MyClass2, 'smart')
|
|
assert ann_str == '~tests.test_util.test_util_typing.<MyClass2>'
|
|
|
|
|
|
def test_stringify_type_hints_alias():
|
|
MyStr = str
|
|
MyTuple = Tuple[str, str]
|
|
|
|
assert stringify_annotation(MyStr, 'fully-qualified-except-typing') == 'str'
|
|
assert stringify_annotation(MyStr, 'smart') == 'str'
|
|
|
|
assert stringify_annotation(MyTuple) == 'Tuple[str, str]'
|
|
assert stringify_annotation(MyTuple, 'smart') == '~typing.Tuple[str, str]'
|
|
|
|
|
|
def test_stringify_type_Literal():
|
|
ann_str = stringify_annotation(
|
|
Literal[1, '2', '\r'], 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == "Literal[1, '2', '\\r']"
|
|
ann_str = stringify_annotation(Literal[1, '2', '\r'], 'fully-qualified')
|
|
assert ann_str == "typing.Literal[1, '2', '\\r']"
|
|
ann_str = stringify_annotation(Literal[1, '2', '\r'], 'smart')
|
|
assert ann_str == "~typing.Literal[1, '2', '\\r']"
|
|
|
|
ann_str = stringify_annotation(Literal[MyEnum.a], 'fully-qualified-except-typing')
|
|
assert ann_str == 'Literal[tests.test_util.test_util_typing.MyEnum.a]'
|
|
ann_str = stringify_annotation(Literal[MyEnum.a], 'fully-qualified')
|
|
assert ann_str == 'typing.Literal[tests.test_util.test_util_typing.MyEnum.a]'
|
|
ann_str = stringify_annotation(Literal[MyEnum.a], 'smart')
|
|
assert ann_str == '~typing.Literal[MyEnum.a]'
|
|
|
|
|
|
def test_stringify_type_union_operator():
|
|
assert stringify_annotation(int | None) == 'int | None'
|
|
assert stringify_annotation(int | None, 'smart') == 'int | None'
|
|
|
|
assert stringify_annotation(int | str) == 'int | str'
|
|
assert stringify_annotation(int | str, 'smart') == 'int | str'
|
|
|
|
assert stringify_annotation(int | str | None) == 'int | str | None'
|
|
assert stringify_annotation(int | str | None, 'smart') == 'int | str | None'
|
|
|
|
ann_str = stringify_annotation(
|
|
int | tuple[dict[str, int | None], list[int | str]] | None
|
|
)
|
|
assert ann_str == 'int | tuple[dict[str, int | None], list[int | str]] | None'
|
|
ann_str = stringify_annotation(
|
|
int | tuple[dict[str, int | None], list[int | str]] | None, 'smart'
|
|
)
|
|
assert ann_str == 'int | tuple[dict[str, int | None], list[int | str]] | None'
|
|
|
|
assert stringify_annotation(int | Struct) == 'int | struct.Struct'
|
|
assert stringify_annotation(int | Struct, 'smart') == 'int | ~struct.Struct'
|
|
|
|
|
|
def test_stringify_broken_type_hints():
|
|
ann_str = stringify_annotation(BrokenType, 'fully-qualified-except-typing')
|
|
assert ann_str == 'tests.test_util.test_util_typing.BrokenType'
|
|
ann_str = stringify_annotation(BrokenType, 'smart')
|
|
assert ann_str == '~tests.test_util.test_util_typing.BrokenType'
|
|
|
|
|
|
def test_stringify_mock():
|
|
with mock(['unknown']):
|
|
import unknown
|
|
|
|
ann_str = stringify_annotation(unknown, 'fully-qualified-except-typing')
|
|
assert ann_str == 'unknown'
|
|
ann_str = stringify_annotation(
|
|
unknown.secret.Class, 'fully-qualified-except-typing'
|
|
)
|
|
assert ann_str == 'unknown.secret.Class'
|
|
ann_str = stringify_annotation(unknown.secret.Class, 'smart')
|
|
assert ann_str == 'unknown.secret.Class'
|
|
|
|
|
|
def test_stringify_type_ForwardRef():
|
|
assert stringify_annotation(ForwardRef('MyInt')) == 'MyInt'
|
|
assert stringify_annotation(ForwardRef('MyInt'), 'smart') == 'MyInt'
|
|
|
|
assert stringify_annotation(list[ForwardRef('MyInt')]) == 'list[MyInt]'
|
|
assert stringify_annotation(list[ForwardRef('MyInt')], 'smart') == 'list[MyInt]'
|
|
|
|
ann_str = stringify_annotation(
|
|
Tuple[dict[ForwardRef('MyInt'), str], list[List[int]]]
|
|
)
|
|
assert ann_str == 'Tuple[dict[MyInt, str], list[List[int]]]'
|
|
ann_str = stringify_annotation(
|
|
Tuple[dict[ForwardRef('MyInt'), str], list[List[int]]],
|
|
'fully-qualified-except-typing',
|
|
)
|
|
assert ann_str == 'Tuple[dict[MyInt, str], list[List[int]]]'
|
|
ann_str = stringify_annotation(
|
|
Tuple[dict[ForwardRef('MyInt'), str], list[List[int]]], 'smart'
|
|
)
|
|
assert ann_str == '~typing.Tuple[dict[MyInt, str], list[~typing.List[int]]]'
|
|
|
|
|
|
def test_stringify_type_hints_paramspec():
|
|
P = ParamSpec('P')
|
|
|
|
assert stringify_annotation(P, 'fully-qualified') == '~P'
|
|
assert stringify_annotation(P, 'fully-qualified-except-typing') == '~P'
|
|
assert stringify_annotation(P, 'smart') == '~P'
|
|
|
|
assert stringify_annotation(P.args, 'fully-qualified') == 'typing.~P'
|
|
assert stringify_annotation(P.args, 'fully-qualified-except-typing') == '~P'
|
|
assert stringify_annotation(P.args, 'smart') == '~typing.~P'
|
|
|
|
assert stringify_annotation(P.kwargs, 'fully-qualified') == 'typing.~P'
|
|
assert stringify_annotation(P.kwargs, 'fully-qualified-except-typing') == '~P'
|
|
assert stringify_annotation(P.kwargs, 'smart') == '~typing.~P'
|