refactor: Merge arguments of sphinx.util.typing:stringify()

This commit is contained in:
Takeshi KOMIYA
2021-12-26 02:03:59 +09:00
parent bdbad40f57
commit 2ea9118181
4 changed files with 207 additions and 198 deletions

View File

@@ -752,6 +752,11 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True,
:param unqualified_typehints: Show annotations as unqualified
(ex. io.StringIO -> StringIO)
"""
if unqualified_typehints:
mode = 'smart'
else:
mode = 'fully-qualified'
args = []
last_kind = None
for param in sig.parameters.values():
@@ -774,7 +779,7 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True,
if show_annotation and param.annotation is not param.empty:
arg.write(': ')
arg.write(stringify_annotation(param.annotation, unqualified_typehints, True))
arg.write(stringify_annotation(param.annotation, mode))
if param.default is not param.empty:
if show_annotation and param.annotation is not param.empty:
arg.write(' = ')
@@ -794,7 +799,7 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True,
show_return_annotation is False):
return '(%s)' % ', '.join(args)
else:
annotation = stringify_annotation(sig.return_annotation, unqualified_typehints, True)
annotation = stringify_annotation(sig.return_annotation, mode)
return '(%s) -> %s' % (', '.join(args), annotation)

View File

@@ -299,19 +299,25 @@ def _restify_py36(cls: Optional[Type]) -> str:
return ':py:obj:`%s.%s`' % (cls.__module__, qualname)
def stringify(annotation: Any, smartref: bool = False, show_typing: bool = False) -> str:
def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
"""Stringify type annotation object.
:param smartref: If true, add "~" prefix to the result to remove the leading
module and class names from the reference text
:param show_typing: If true, do not suppress the "typing" module name
:param mode: Specify a method how annotations will be stringified.
'fully-qualified-except-typing'
Show the module name and qualified name of the annotation except
the "typing" module.
'smart'
Show the name of the annotation.
'fully-qualified'
Show the module name and qualified name of the annotation.
"""
from sphinx.util import inspect # lazy loading
if smartref:
prefix = '~'
if mode == 'smart':
modprefix = '~'
else:
prefix = ''
modprefix = ''
if isinstance(annotation, str):
if annotation.startswith("'") and annotation.endswith("'"):
@@ -320,14 +326,15 @@ def stringify(annotation: Any, smartref: bool = False, show_typing: bool = False
else:
return annotation
elif isinstance(annotation, TypeVar):
if show_typing is False and annotation.__module__ == 'typing':
if (annotation.__module__ == 'typing' and
mode in ('fully-qualified-except-typing', 'smart')):
return annotation.__name__
else:
return prefix + '.'.join([annotation.__module__, annotation.__name__])
return modprefix + '.'.join([annotation.__module__, annotation.__name__])
elif inspect.isNewType(annotation):
if sys.version_info > (3, 10):
# newtypes have correct module info since Python 3.10+
return prefix + '%s.%s' % (annotation.__module__, annotation.__name__)
return modprefix + '%s.%s' % (annotation.__module__, annotation.__name__)
else:
return annotation.__name__
elif not annotation:
@@ -335,7 +342,7 @@ def stringify(annotation: Any, smartref: bool = False, show_typing: bool = False
elif annotation is NoneType:
return 'None'
elif annotation in INVALID_BUILTIN_CLASSES:
return prefix + INVALID_BUILTIN_CLASSES[annotation]
return modprefix + INVALID_BUILTIN_CLASSES[annotation]
elif str(annotation).startswith('typing.Annotated'): # for py310+
pass
elif (getattr(annotation, '__module__', None) == 'builtins' and
@@ -348,12 +355,12 @@ def stringify(annotation: Any, smartref: bool = False, show_typing: bool = False
return '...'
if sys.version_info >= (3, 7): # py37+
return _stringify_py37(annotation, smartref, show_typing)
return _stringify_py37(annotation, mode)
else:
return _stringify_py36(annotation, smartref, show_typing)
return _stringify_py36(annotation, mode)
def _stringify_py37(annotation: Any, smartref: bool = False, show_typing: bool = False) -> str:
def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
"""stringify() for py37+."""
module = getattr(annotation, '__module__', None)
modprefix = ''
@@ -367,19 +374,19 @@ def _stringify_py37(annotation: Any, smartref: bool = False, show_typing: bool =
else:
qualname = stringify(annotation.__origin__).replace('typing.', '') # ex. Union
if smartref:
if mode == 'smart':
modprefix = '~%s.' % module
elif show_typing:
elif mode == 'fully-qualified':
modprefix = '%s.' % module
elif hasattr(annotation, '__qualname__'):
if smartref:
if mode == 'smart':
modprefix = '~%s.' % module
else:
modprefix = '%s.' % module
qualname = annotation.__qualname__
elif hasattr(annotation, '__origin__'):
# instantiated generic provided by a user
qualname = stringify(annotation.__origin__, smartref, show_typing)
qualname = stringify(annotation.__origin__, mode)
elif UnionType and isinstance(annotation, UnionType): # types.Union (for py3.10+)
qualname = 'types.Union'
else:
@@ -394,15 +401,13 @@ def _stringify_py37(annotation: Any, smartref: bool = False, show_typing: bool =
elif qualname in ('Optional', 'Union'):
if len(annotation.__args__) > 1 and annotation.__args__[-1] is NoneType:
if len(annotation.__args__) > 2:
args = ', '.join(stringify(a, smartref, show_typing) for a
in annotation.__args__[:-1])
args = ', '.join(stringify(a, mode) for a in annotation.__args__[:-1])
return '%sOptional[%sUnion[%s]]' % (modprefix, modprefix, args)
else:
return '%sOptional[%s]' % (modprefix, stringify(annotation.__args__[0],
smartref, show_typing))
return '%sOptional[%s]' % (modprefix,
stringify(annotation.__args__[0], mode))
else:
args = ', '.join(stringify(a, smartref, show_typing) for a
in annotation.__args__)
args = ', '.join(stringify(a, mode) for a in annotation.__args__)
return '%sUnion[%s]' % (modprefix, args)
elif qualname == 'types.Union':
if len(annotation.__args__) > 1 and None in annotation.__args__:
@@ -411,27 +416,25 @@ def _stringify_py37(annotation: Any, smartref: bool = False, show_typing: bool =
else:
return ' | '.join(stringify(a) for a in annotation.__args__)
elif qualname == 'Callable':
args = ', '.join(stringify(a, smartref, show_typing) for a
in annotation.__args__[:-1])
returns = stringify(annotation.__args__[-1], smartref, show_typing)
args = ', '.join(stringify(a, mode) for a in annotation.__args__[:-1])
returns = stringify(annotation.__args__[-1], mode)
return '%s%s[[%s], %s]' % (modprefix, qualname, args, returns)
elif qualname == 'Literal':
args = ', '.join(repr(a) for a in annotation.__args__)
return '%s%s[%s]' % (modprefix, qualname, args)
elif str(annotation).startswith('typing.Annotated'): # for py39+
return stringify(annotation.__args__[0], smartref, show_typing)
return stringify(annotation.__args__[0], mode)
elif all(is_system_TypeVar(a) for a in annotation.__args__):
# Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT])
return modprefix + qualname
else:
args = ', '.join(stringify(a, smartref, show_typing) for a
in annotation.__args__)
args = ', '.join(stringify(a, mode) for a in annotation.__args__)
return '%s%s[%s]' % (modprefix, qualname, args)
return modprefix + qualname
def _stringify_py36(annotation: Any, smartref: bool = False, show_typing: bool = False) -> str:
def _stringify_py36(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
"""stringify() for py36."""
module = getattr(annotation, '__module__', None)
modprefix = ''
@@ -447,12 +450,12 @@ def _stringify_py36(annotation: Any, smartref: bool = False, show_typing: bool =
else:
qualname = repr(annotation).replace('typing.', '')
if smartref:
if mode == 'smart':
modprefix = '~%s.' % module
elif show_typing:
elif mode == 'fully-qualified':
modprefix = '%s.' % module
elif hasattr(annotation, '__qualname__'):
if smartref:
if mode == 'smart':
modprefix = '~%s.' % module
else:
modprefix = '%s.' % module
@@ -464,7 +467,7 @@ def _stringify_py36(annotation: Any, smartref: bool = False, show_typing: bool =
not hasattr(annotation, '__tuple_params__')): # for Python 3.6
params = annotation.__args__
if params:
param_str = ', '.join(stringify(p, smartref, show_typing) for p in params)
param_str = ', '.join(stringify(p, mode) for p in params)
return '%s%s[%s]' % (modprefix, qualname, param_str)
else:
return modprefix + qualname
@@ -475,12 +478,12 @@ def _stringify_py36(annotation: Any, smartref: bool = False, show_typing: bool =
elif annotation.__origin__ == Generator: # type: ignore
params = annotation.__args__ # type: ignore
else: # typing.Callable
args = ', '.join(stringify(arg, smartref, show_typing) for arg
args = ', '.join(stringify(arg, mode) for arg
in annotation.__args__[:-1]) # type: ignore
result = stringify(annotation.__args__[-1]) # type: ignore
return '%s%s[[%s], %s]' % (modprefix, qualname, args, result)
if params is not None:
param_str = ', '.join(stringify(p, smartref, show_typing) for p in params)
param_str = ', '.join(stringify(p, mode) for p in params)
return '%s%s[%s]' % (modprefix, qualname, param_str)
elif (hasattr(annotation, '__origin__') and
annotation.__origin__ is typing.Union):
@@ -488,13 +491,12 @@ def _stringify_py36(annotation: Any, smartref: bool = False, show_typing: bool =
if params is not None:
if len(params) > 1 and params[-1] is NoneType:
if len(params) > 2:
param_str = ", ".join(stringify(p, smartref, show_typing) for p
in params[:-1])
param_str = ", ".join(stringify(p, mode) for p in params[:-1])
return '%sOptional[%sUnion[%s]]' % (modprefix, modprefix, param_str)
else:
return '%sOptional[%s]' % (modprefix, stringify(params[0]))
return '%sOptional[%s]' % (modprefix, stringify(params[0], mode))
else:
param_str = ', '.join(stringify(p, smartref, show_typing) for p in params)
param_str = ', '.join(stringify(p, mode) for p in params)
return '%sUnion[%s]' % (modprefix, param_str)
return modprefix + qualname

View File

@@ -162,8 +162,10 @@ def test_signature_annotations():
# TypeVars and generic types with TypeVars
sig = inspect.signature(f2)
if sys.version_info < (3, 7):
assert stringify_signature(sig) == ('(x: typing.List[T], y: typing.List[T_co], z: T) '
'-> typing.List[T_contra]')
assert stringify_signature(sig) == ('(x: typing.List[typing.T],'
' y: typing.List[typing.T_co],'
' z: typing.T'
') -> typing.List[typing.T_contra]')
else:
assert stringify_signature(sig) == ('(x: typing.List[tests.typing_test_data.T],'
' y: typing.List[tests.typing_test_data.T_co],'

View File

@@ -178,181 +178,181 @@ def test_restify_mock():
def test_stringify():
assert stringify(int, False) == "int"
assert stringify(int, True) == "int"
assert stringify(int) == "int"
assert stringify(int, "smart") == "int"
assert stringify(str, False) == "str"
assert stringify(str, True) == "str"
assert stringify(str) == "str"
assert stringify(str, "smart") == "str"
assert stringify(None, False) == "None"
assert stringify(None, True) == "None"
assert stringify(None) == "None"
assert stringify(None, "smart") == "None"
assert stringify(Integral, False) == "numbers.Integral"
assert stringify(Integral, True) == "~numbers.Integral"
assert stringify(Integral) == "numbers.Integral"
assert stringify(Integral, "smart") == "~numbers.Integral"
assert stringify(Struct, False) == "struct.Struct"
assert stringify(Struct, True) == "~struct.Struct"
assert stringify(Struct) == "struct.Struct"
assert stringify(Struct, "smart") == "~struct.Struct"
assert stringify(TracebackType, False) == "types.TracebackType"
assert stringify(TracebackType, True) == "~types.TracebackType"
assert stringify(TracebackType) == "types.TracebackType"
assert stringify(TracebackType, "smart") == "~types.TracebackType"
assert stringify(Any, False) == "Any"
assert stringify(Any, False, True) == "typing.Any"
assert stringify(Any, True) == "~typing.Any"
assert stringify(Any) == "Any"
assert stringify(Any, "fully-qualified") == "typing.Any"
assert stringify(Any, "smart") == "~typing.Any"
def test_stringify_type_hints_containers():
assert stringify(List, False) == "List"
assert stringify(List, False, True) == "typing.List"
assert stringify(List, True) == "~typing.List"
assert stringify(List) == "List"
assert stringify(List, "fully-qualified") == "typing.List"
assert stringify(List, "smart") == "~typing.List"
assert stringify(Dict, False) == "Dict"
assert stringify(Dict, False, True) == "typing.Dict"
assert stringify(Dict, True) == "~typing.Dict"
assert stringify(Dict) == "Dict"
assert stringify(Dict, "fully-qualified") == "typing.Dict"
assert stringify(Dict, "smart") == "~typing.Dict"
assert stringify(List[int], False) == "List[int]"
assert stringify(List[int], False, True) == "typing.List[int]"
assert stringify(List[int], True) == "~typing.List[int]"
assert stringify(List[int]) == "List[int]"
assert stringify(List[int], "fully-qualified") == "typing.List[int]"
assert stringify(List[int], "smart") == "~typing.List[int]"
assert stringify(List[str], False) == "List[str]"
assert stringify(List[str], False, True) == "typing.List[str]"
assert stringify(List[str], True) == "~typing.List[str]"
assert stringify(List[str]) == "List[str]"
assert stringify(List[str], "fully-qualified") == "typing.List[str]"
assert stringify(List[str], "smart") == "~typing.List[str]"
assert stringify(Dict[str, float], False) == "Dict[str, float]"
assert stringify(Dict[str, float], False, True) == "typing.Dict[str, float]"
assert stringify(Dict[str, float], True) == "~typing.Dict[str, float]"
assert stringify(Dict[str, float]) == "Dict[str, float]"
assert stringify(Dict[str, float], "fully-qualified") == "typing.Dict[str, float]"
assert stringify(Dict[str, float], "smart") == "~typing.Dict[str, float]"
assert stringify(Tuple[str, str, str], False) == "Tuple[str, str, str]"
assert stringify(Tuple[str, str, str], False, True) == "typing.Tuple[str, str, str]"
assert stringify(Tuple[str, str, str], True) == "~typing.Tuple[str, str, str]"
assert stringify(Tuple[str, str, str]) == "Tuple[str, str, str]"
assert stringify(Tuple[str, str, str], "fully-qualified") == "typing.Tuple[str, str, str]"
assert stringify(Tuple[str, str, str], "smart") == "~typing.Tuple[str, str, str]"
assert stringify(Tuple[str, ...], False) == "Tuple[str, ...]"
assert stringify(Tuple[str, ...], False, True) == "typing.Tuple[str, ...]"
assert stringify(Tuple[str, ...], True) == "~typing.Tuple[str, ...]"
assert stringify(Tuple[str, ...]) == "Tuple[str, ...]"
assert stringify(Tuple[str, ...], "fully-qualified") == "typing.Tuple[str, ...]"
assert stringify(Tuple[str, ...], "smart") == "~typing.Tuple[str, ...]"
assert stringify(Tuple[()], False) == "Tuple[()]"
assert stringify(Tuple[()], False, True) == "typing.Tuple[()]"
assert stringify(Tuple[()], True) == "~typing.Tuple[()]"
assert stringify(Tuple[()]) == "Tuple[()]"
assert stringify(Tuple[()], "fully-qualified") == "typing.Tuple[()]"
assert stringify(Tuple[()], "smart") == "~typing.Tuple[()]"
assert stringify(List[Dict[str, Tuple]], False) == "List[Dict[str, Tuple]]"
assert stringify(List[Dict[str, Tuple]], False, True) == "typing.List[typing.Dict[str, typing.Tuple]]"
assert stringify(List[Dict[str, Tuple]], True) == "~typing.List[~typing.Dict[str, ~typing.Tuple]]"
assert stringify(List[Dict[str, Tuple]]) == "List[Dict[str, Tuple]]"
assert stringify(List[Dict[str, Tuple]], "fully-qualified") == "typing.List[typing.Dict[str, typing.Tuple]]"
assert stringify(List[Dict[str, Tuple]], "smart") == "~typing.List[~typing.Dict[str, ~typing.Tuple]]"
assert stringify(MyList[Tuple[int, int]], False) == "tests.test_util_typing.MyList[Tuple[int, int]]"
assert stringify(MyList[Tuple[int, int]], False, True) == "tests.test_util_typing.MyList[typing.Tuple[int, int]]"
assert stringify(MyList[Tuple[int, int]], True) == "~tests.test_util_typing.MyList[~typing.Tuple[int, int]]"
assert stringify(MyList[Tuple[int, int]]) == "tests.test_util_typing.MyList[Tuple[int, int]]"
assert stringify(MyList[Tuple[int, int]], "fully-qualified") == "tests.test_util_typing.MyList[typing.Tuple[int, int]]"
assert stringify(MyList[Tuple[int, int]], "smart") == "~tests.test_util_typing.MyList[~typing.Tuple[int, int]]"
assert stringify(Generator[None, None, None], False) == "Generator[None, None, None]"
assert stringify(Generator[None, None, None], False, True) == "typing.Generator[None, None, None]"
assert stringify(Generator[None, None, None], True) == "~typing.Generator[None, None, None]"
assert stringify(Generator[None, None, None]) == "Generator[None, None, None]"
assert stringify(Generator[None, None, None], "fully-qualified") == "typing.Generator[None, None, None]"
assert stringify(Generator[None, None, None], "smart") == "~typing.Generator[None, None, None]"
@pytest.mark.skipif(sys.version_info < (3, 9), reason='python 3.9+ is required.')
def test_stringify_type_hints_pep_585():
assert stringify(list[int], False) == "list[int]"
assert stringify(list[int], True) == "list[int]"
assert stringify(list[int]) == "list[int]"
assert stringify(list[int], "smart") == "list[int]"
assert stringify(list[str], False) == "list[str]"
assert stringify(list[str], True) == "list[str]"
assert stringify(list[str]) == "list[str]"
assert stringify(list[str], "smart") == "list[str]"
assert stringify(dict[str, float], False) == "dict[str, float]"
assert stringify(dict[str, float], True) == "dict[str, float]"
assert stringify(dict[str, float]) == "dict[str, float]"
assert stringify(dict[str, float], "smart") == "dict[str, float]"
assert stringify(tuple[str, str, str], False) == "tuple[str, str, str]"
assert stringify(tuple[str, str, str], True) == "tuple[str, str, str]"
assert stringify(tuple[str, str, str]) == "tuple[str, str, str]"
assert stringify(tuple[str, str, str], "smart") == "tuple[str, str, str]"
assert stringify(tuple[str, ...], False) == "tuple[str, ...]"
assert stringify(tuple[str, ...], True) == "tuple[str, ...]"
assert stringify(tuple[str, ...]) == "tuple[str, ...]"
assert stringify(tuple[str, ...], "smart") == "tuple[str, ...]"
assert stringify(tuple[()], False) == "tuple[()]"
assert stringify(tuple[()], True) == "tuple[()]"
assert stringify(tuple[()]) == "tuple[()]"
assert stringify(tuple[()], "smart") == "tuple[()]"
assert stringify(list[dict[str, tuple]], False) == "list[dict[str, tuple]]"
assert stringify(list[dict[str, tuple]], True) == "list[dict[str, tuple]]"
assert stringify(list[dict[str, tuple]]) == "list[dict[str, tuple]]"
assert stringify(list[dict[str, tuple]], "smart") == "list[dict[str, tuple]]"
assert stringify(type[int], False) == "type[int]"
assert stringify(type[int], True) == "type[int]"
assert stringify(type[int]) == "type[int]"
assert stringify(type[int], "smart") == "type[int]"
@pytest.mark.skipif(sys.version_info < (3, 9), reason='python 3.9+ is required.')
def test_stringify_Annotated():
from typing import Annotated # type: ignore
assert stringify(Annotated[str, "foo", "bar"], False) == "str" # NOQA
assert stringify(Annotated[str, "foo", "bar"], True) == "str" # NOQA
assert stringify(Annotated[str, "foo", "bar"]) == "str" # NOQA
assert stringify(Annotated[str, "foo", "bar"], "smart") == "str" # NOQA
def test_stringify_type_hints_string():
assert stringify("int", False) == "int"
assert stringify("int", True) == "int"
assert stringify("int") == "int"
assert stringify("int", "smart") == "int"
assert stringify("str", False) == "str"
assert stringify("str", True) == "str"
assert stringify("str") == "str"
assert stringify("str", "smart") == "str"
assert stringify(List["int"], False) == "List[int]"
assert stringify(List["int"], True) == "~typing.List[int]"
assert stringify(List["int"]) == "List[int]"
assert stringify(List["int"], "smart") == "~typing.List[int]"
assert stringify("Tuple[str]", False) == "Tuple[str]"
assert stringify("Tuple[str]", True) == "Tuple[str]"
assert stringify("Tuple[str]") == "Tuple[str]"
assert stringify("Tuple[str]", "smart") == "Tuple[str]"
assert stringify("unknown", False) == "unknown"
assert stringify("unknown", True) == "unknown"
assert stringify("unknown") == "unknown"
assert stringify("unknown", "smart") == "unknown"
def test_stringify_type_hints_Callable():
assert stringify(Callable, False) == "Callable"
assert stringify(Callable, False, True) == "typing.Callable"
assert stringify(Callable, True) == "~typing.Callable"
assert stringify(Callable) == "Callable"
assert stringify(Callable, "fully-qualified") == "typing.Callable"
assert stringify(Callable, "smart") == "~typing.Callable"
if sys.version_info >= (3, 7):
assert stringify(Callable[[str], int], False) == "Callable[[str], int]"
assert stringify(Callable[[str], int], False, True) == "typing.Callable[[str], int]"
assert stringify(Callable[[str], int], True) == "~typing.Callable[[str], int]"
assert stringify(Callable[[str], int]) == "Callable[[str], int]"
assert stringify(Callable[[str], int], "fully-qualified") == "typing.Callable[[str], int]"
assert stringify(Callable[[str], int], "smart") == "~typing.Callable[[str], int]"
assert stringify(Callable[..., int], False) == "Callable[[...], int]"
assert stringify(Callable[..., int], False, True) == "typing.Callable[[...], int]"
assert stringify(Callable[..., int], True) == "~typing.Callable[[...], int]"
assert stringify(Callable[..., int]) == "Callable[[...], int]"
assert stringify(Callable[..., int], "fully-qualified") == "typing.Callable[[...], int]"
assert stringify(Callable[..., int], "smart") == "~typing.Callable[[...], int]"
else:
assert stringify(Callable[[str], int], False) == "Callable[str, int]"
assert stringify(Callable[[str], int], False, True) == "typing.Callable[str, int]"
assert stringify(Callable[[str], int], True) == "~typing.Callable[str, int]"
assert stringify(Callable[[str], int]) == "Callable[str, int]"
assert stringify(Callable[[str], int], "fully-qualified") == "typing.Callable[str, int]"
assert stringify(Callable[[str], int], "smart") == "~typing.Callable[str, int]"
assert stringify(Callable[..., int], False) == "Callable[..., int]"
assert stringify(Callable[..., int], False, True) == "typing.Callable[..., int]"
assert stringify(Callable[..., int], True) == "~typing.Callable[..., int]"
assert stringify(Callable[..., int]) == "Callable[..., int]"
assert stringify(Callable[..., int], "fully-qualified") == "typing.Callable[..., int]"
assert stringify(Callable[..., int], "smart") == "~typing.Callable[..., int]"
def test_stringify_type_hints_Union():
assert stringify(Optional[int], False) == "Optional[int]"
assert stringify(Optional[int], False, True) == "typing.Optional[int]"
assert stringify(Optional[int], True) == "~typing.Optional[int]"
assert stringify(Optional[int]) == "Optional[int]"
assert stringify(Optional[int], "fully-qualified") == "typing.Optional[int]"
assert stringify(Optional[int], "smart") == "~typing.Optional[int]"
assert stringify(Union[str, None], False) == "Optional[str]"
assert stringify(Union[str, None], False, True) == "typing.Optional[str]"
assert stringify(Union[str, None], True) == "~typing.Optional[str]"
assert stringify(Union[str, None]) == "Optional[str]"
assert stringify(Union[str, None], "fully-qualified") == "typing.Optional[str]"
assert stringify(Union[str, None], "smart") == "~typing.Optional[str]"
assert stringify(Union[int, str], False) == "Union[int, str]"
assert stringify(Union[int, str], False, True) == "typing.Union[int, str]"
assert stringify(Union[int, str], True) == "~typing.Union[int, str]"
assert stringify(Union[int, str]) == "Union[int, str]"
assert stringify(Union[int, str], "fully-qualified") == "typing.Union[int, str]"
assert stringify(Union[int, str], "smart") == "~typing.Union[int, str]"
if sys.version_info >= (3, 7):
assert stringify(Union[int, Integral], False) == "Union[int, numbers.Integral]"
assert stringify(Union[int, Integral], False, True) == "typing.Union[int, numbers.Integral]"
assert stringify(Union[int, Integral], True) == "~typing.Union[int, ~numbers.Integral]"
assert stringify(Union[int, Integral]) == "Union[int, numbers.Integral]"
assert stringify(Union[int, Integral], "fully-qualified") == "typing.Union[int, numbers.Integral]"
assert stringify(Union[int, Integral], "smart") == "~typing.Union[int, ~numbers.Integral]"
assert (stringify(Union[MyClass1, MyClass2], False) ==
assert (stringify(Union[MyClass1, MyClass2]) ==
"Union[tests.test_util_typing.MyClass1, tests.test_util_typing.<MyClass2>]")
assert (stringify(Union[MyClass1, MyClass2], False, True) ==
assert (stringify(Union[MyClass1, MyClass2], "fully-qualified") ==
"typing.Union[tests.test_util_typing.MyClass1, tests.test_util_typing.<MyClass2>]")
assert (stringify(Union[MyClass1, MyClass2], True) ==
assert (stringify(Union[MyClass1, MyClass2], "smart") ==
"~typing.Union[~tests.test_util_typing.MyClass1, ~tests.test_util_typing.<MyClass2>]")
else:
assert stringify(Union[int, Integral], False) == "numbers.Integral"
assert stringify(Union[int, Integral], False, True) == "numbers.Integral"
assert stringify(Union[int, Integral], True) == "~numbers.Integral"
assert stringify(Union[int, Integral]) == "numbers.Integral"
assert stringify(Union[int, Integral], "fully-qualified") == "numbers.Integral"
assert stringify(Union[int, Integral], "smart") == "~numbers.Integral"
assert stringify(Union[MyClass1, MyClass2], False) == "tests.test_util_typing.MyClass1"
assert stringify(Union[MyClass1, MyClass2], False, True) == "tests.test_util_typing.MyClass1"
assert stringify(Union[MyClass1, MyClass2], True) == "~tests.test_util_typing.MyClass1"
assert stringify(Union[MyClass1, MyClass2]) == "tests.test_util_typing.MyClass1"
assert stringify(Union[MyClass1, MyClass2], "fully-qualified") == "tests.test_util_typing.MyClass1"
assert stringify(Union[MyClass1, MyClass2], "smart") == "~tests.test_util_typing.MyClass1"
def test_stringify_type_hints_typevars():
@@ -361,84 +361,84 @@ def test_stringify_type_hints_typevars():
T_contra = TypeVar('T_contra', contravariant=True)
if sys.version_info < (3, 7):
assert stringify(T, False) == "T"
assert stringify(T, True) == "T"
assert stringify(T) == "T"
assert stringify(T, "smart") == "T"
assert stringify(T_co, False) == "T_co"
assert stringify(T_co, True) == "T_co"
assert stringify(T_co) == "T_co"
assert stringify(T_co, "smart") == "T_co"
assert stringify(T_contra, False) == "T_contra"
assert stringify(T_contra, True) == "T_contra"
assert stringify(T_contra) == "T_contra"
assert stringify(T_contra, "smart") == "T_contra"
assert stringify(List[T], False) == "List[T]"
assert stringify(List[T], True) == "~typing.List[T]"
assert stringify(List[T]) == "List[T]"
assert stringify(List[T], "smart") == "~typing.List[T]"
else:
assert stringify(T, False) == "tests.test_util_typing.T"
assert stringify(T, True) == "~tests.test_util_typing.T"
assert stringify(T) == "tests.test_util_typing.T"
assert stringify(T, "smart") == "~tests.test_util_typing.T"
assert stringify(T_co, False) == "tests.test_util_typing.T_co"
assert stringify(T_co, True) == "~tests.test_util_typing.T_co"
assert stringify(T_co) == "tests.test_util_typing.T_co"
assert stringify(T_co, "smart") == "~tests.test_util_typing.T_co"
assert stringify(T_contra, False) == "tests.test_util_typing.T_contra"
assert stringify(T_contra, True) == "~tests.test_util_typing.T_contra"
assert stringify(T_contra) == "tests.test_util_typing.T_contra"
assert stringify(T_contra, "smart") == "~tests.test_util_typing.T_contra"
assert stringify(List[T], False) == "List[tests.test_util_typing.T]"
assert stringify(List[T], True) == "~typing.List[~tests.test_util_typing.T]"
assert stringify(List[T]) == "List[tests.test_util_typing.T]"
assert stringify(List[T], "smart") == "~typing.List[~tests.test_util_typing.T]"
if sys.version_info >= (3, 10):
assert stringify(MyInt, False) == "tests.test_util_typing.MyInt"
assert stringify(MyInt, True) == "~tests.test_util_typing.MyInt"
assert stringify(MyInt) == "tests.test_util_typing.MyInt"
assert stringify(MyInt, "smart") == "~tests.test_util_typing.MyInt"
else:
assert stringify(MyInt, False) == "MyInt"
assert stringify(MyInt, True) == "MyInt"
assert stringify(MyInt) == "MyInt"
assert stringify(MyInt, "smart") == "MyInt"
def test_stringify_type_hints_custom_class():
assert stringify(MyClass1, False) == "tests.test_util_typing.MyClass1"
assert stringify(MyClass1, True) == "~tests.test_util_typing.MyClass1"
assert stringify(MyClass1) == "tests.test_util_typing.MyClass1"
assert stringify(MyClass1, "smart") == "~tests.test_util_typing.MyClass1"
assert stringify(MyClass2, False) == "tests.test_util_typing.<MyClass2>"
assert stringify(MyClass2, True) == "~tests.test_util_typing.<MyClass2>"
assert stringify(MyClass2) == "tests.test_util_typing.<MyClass2>"
assert stringify(MyClass2, "smart") == "~tests.test_util_typing.<MyClass2>"
def test_stringify_type_hints_alias():
MyStr = str
MyTuple = Tuple[str, str]
assert stringify(MyStr, False) == "str"
assert stringify(MyStr, True) == "str"
assert stringify(MyStr) == "str"
assert stringify(MyStr, "smart") == "str"
assert stringify(MyTuple, False) == "Tuple[str, str]" # type: ignore
assert stringify(MyTuple, True) == "~typing.Tuple[str, str]" # type: ignore
assert stringify(MyTuple) == "Tuple[str, str]" # type: ignore
assert stringify(MyTuple, "smart") == "~typing.Tuple[str, str]" # type: ignore
@pytest.mark.skipif(sys.version_info < (3, 8), reason='python 3.8+ is required.')
def test_stringify_type_Literal():
from typing import Literal # type: ignore
assert stringify(Literal[1, "2", "\r"], False) == "Literal[1, '2', '\\r']"
assert stringify(Literal[1, "2", "\r"], False, True) == "typing.Literal[1, '2', '\\r']"
assert stringify(Literal[1, "2", "\r"], True) == "~typing.Literal[1, '2', '\\r']"
assert stringify(Literal[1, "2", "\r"]) == "Literal[1, '2', '\\r']"
assert stringify(Literal[1, "2", "\r"], "fully-qualified") == "typing.Literal[1, '2', '\\r']"
assert stringify(Literal[1, "2", "\r"], "smart") == "~typing.Literal[1, '2', '\\r']"
@pytest.mark.skipif(sys.version_info < (3, 10), reason='python 3.10+ is required.')
def test_stringify_type_union_operator():
assert stringify(int | None, False) == "int | None" # type: ignore
assert stringify(int | None, True) == "int | None" # type: ignore
assert stringify(int | None) == "int | None" # type: ignore
assert stringify(int | None, "smart") == "int | None" # type: ignore
assert stringify(int | str, False) == "int | str" # type: ignore
assert stringify(int | str, True) == "int | str" # type: ignore
assert stringify(int | str) == "int | str" # type: ignore
assert stringify(int | str, "smart") == "int | str" # type: ignore
assert stringify(int | str | None, False) == "int | str | None" # type: ignore
assert stringify(int | str | None, True) == "int | str | None" # type: ignore
assert stringify(int | str | None) == "int | str | None" # type: ignore
assert stringify(int | str | None, "smart") == "int | str | None" # type: ignore
def test_stringify_broken_type_hints():
assert stringify(BrokenType, False) == 'tests.test_util_typing.BrokenType'
assert stringify(BrokenType, True) == '~tests.test_util_typing.BrokenType'
assert stringify(BrokenType) == 'tests.test_util_typing.BrokenType'
assert stringify(BrokenType, "smart") == '~tests.test_util_typing.BrokenType'
def test_stringify_mock():
with mock(['unknown']):
import unknown
assert stringify(unknown.secret.Class, False) == 'unknown.secret.Class'
assert stringify(unknown.secret.Class, True) == 'unknown.secret.Class'
assert stringify(unknown.secret.Class) == 'unknown.secret.Class'
assert stringify(unknown.secret.Class, "smart") == 'unknown.secret.Class'