aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_dataclasses/__init__.py2
-rw-r--r--Lib/test/test_functools.py2
-rw-r--r--Lib/test/test_inspect/test_inspect.py4
-rw-r--r--Lib/test/test_pydoc/test_pydoc.py16
-rw-r--r--Lib/test/test_types.py50
-rw-r--r--Lib/test/test_typing.py96
6 files changed, 111 insertions, 59 deletions
diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py
index 8209374c36b..869a043211b 100644
--- a/Lib/test/test_dataclasses/__init__.py
+++ b/Lib/test/test_dataclasses/__init__.py
@@ -2314,7 +2314,7 @@ class TestDocString(unittest.TestCase):
class C:
x: Union[int, type(None)] = None
- self.assertDocStrEqual(C.__doc__, "C(x:Optional[int]=None)")
+ self.assertDocStrEqual(C.__doc__, "C(x:int|None=None)")
def test_docstring_list_field(self):
@dataclass
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index d7404a81c23..ef85664cb78 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -3083,7 +3083,7 @@ class TestSingleDispatch(unittest.TestCase):
"Invalid annotation for 'arg'."
)
self.assertEndsWith(str(exc.exception),
- 'typing.Union[int, typing.Iterable[str]] not all arguments are classes.'
+ 'int | typing.Iterable[str] not all arguments are classes.'
)
def test_invalid_positional_argument(self):
diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py
index 03f2bacb3a4..73cf5ac64ee 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -1750,8 +1750,8 @@ class TestClassesAndFunctions(unittest.TestCase):
class TestFormatAnnotation(unittest.TestCase):
def test_typing_replacement(self):
from test.typinganndata.ann_module9 import ann, ann1
- self.assertEqual(inspect.formatannotation(ann), 'Union[List[str], int]')
- self.assertEqual(inspect.formatannotation(ann1), 'Union[List[testModule.typing.A], int]')
+ self.assertEqual(inspect.formatannotation(ann), 'List[str] | int')
+ self.assertEqual(inspect.formatannotation(ann1), 'List[testModule.typing.A] | int')
def test_forwardref(self):
fwdref = ForwardRef('fwdref')
diff --git a/Lib/test/test_pydoc/test_pydoc.py b/Lib/test/test_pydoc/test_pydoc.py
index 0abd36c5e07..2b1a4484c68 100644
--- a/Lib/test/test_pydoc/test_pydoc.py
+++ b/Lib/test/test_pydoc/test_pydoc.py
@@ -133,7 +133,7 @@ DATA
c_alias = test.test_pydoc.pydoc_mod.C[int]
list_alias1 = typing.List[int]
list_alias2 = list[int]
- type_union1 = typing.Union[int, str]
+ type_union1 = int | str
type_union2 = int | str
VERSION
@@ -223,7 +223,7 @@ Data
c_alias = test.test_pydoc.pydoc_mod.C[int]
list_alias1 = typing.List[int]
list_alias2 = list[int]
- type_union1 = typing.Union[int, str]
+ type_union1 = int | str
type_union2 = int | str
Author
@@ -1447,17 +1447,17 @@ class TestDescriptions(unittest.TestCase):
self.assertIn(list.__doc__.strip().splitlines()[0], doc)
def test_union_type(self):
- self.assertEqual(pydoc.describe(typing.Union[int, str]), '_UnionGenericAlias')
+ self.assertEqual(pydoc.describe(typing.Union[int, str]), 'Union')
doc = pydoc.render_doc(typing.Union[int, str], renderer=pydoc.plaintext)
- self.assertIn('_UnionGenericAlias in module typing', doc)
- self.assertIn('Union = typing.Union', doc)
+ self.assertIn('Union in module typing', doc)
+ self.assertIn('class Union(builtins.object)', doc)
if typing.Union.__doc__:
self.assertIn(typing.Union.__doc__.strip().splitlines()[0], doc)
- self.assertEqual(pydoc.describe(int | str), 'UnionType')
+ self.assertEqual(pydoc.describe(int | str), 'Union')
doc = pydoc.render_doc(int | str, renderer=pydoc.plaintext)
- self.assertIn('UnionType in module types object', doc)
- self.assertIn('\nclass UnionType(builtins.object)', doc)
+ self.assertIn('Union in module typing', doc)
+ self.assertIn('class Union(builtins.object)', doc)
if not MISSING_C_DOCSTRINGS:
self.assertIn(types.UnionType.__doc__.strip().splitlines()[0], doc)
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index d1161719d98..5a65b5dacaf 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -709,10 +709,6 @@ class UnionTests(unittest.TestCase):
y = int | bool
with self.assertRaises(TypeError):
x < y
- # Check that we don't crash if typing.Union does not have a tuple in __args__
- y = typing.Union[str, int]
- y.__args__ = [str, int]
- self.assertEqual(x, y)
def test_hash(self):
self.assertEqual(hash(int | str), hash(str | int))
@@ -727,17 +723,40 @@ class UnionTests(unittest.TestCase):
self.assertEqual((A | B).__args__, (A, B))
union1 = A | B
- with self.assertRaises(TypeError):
+ with self.assertRaisesRegex(TypeError, "unhashable type: 'UnhashableMeta'"):
hash(union1)
union2 = int | B
- with self.assertRaises(TypeError):
+ with self.assertRaisesRegex(TypeError, "unhashable type: 'UnhashableMeta'"):
hash(union2)
union3 = A | int
- with self.assertRaises(TypeError):
+ with self.assertRaisesRegex(TypeError, "unhashable type: 'UnhashableMeta'"):
hash(union3)
+ def test_unhashable_becomes_hashable(self):
+ is_hashable = False
+ class UnhashableMeta(type):
+ def __hash__(self):
+ if is_hashable:
+ return 1
+ else:
+ raise TypeError("not hashable")
+
+ class A(metaclass=UnhashableMeta): ...
+ class B(metaclass=UnhashableMeta): ...
+
+ union = A | B
+ self.assertEqual(union.__args__, (A, B))
+
+ with self.assertRaisesRegex(TypeError, "not hashable"):
+ hash(union)
+
+ is_hashable = True
+
+ with self.assertRaisesRegex(TypeError, "union contains 2 unhashable elements"):
+ hash(union)
+
def test_instancecheck_and_subclasscheck(self):
for x in (int | str, typing.Union[int, str]):
with self.subTest(x=x):
@@ -921,7 +940,7 @@ class UnionTests(unittest.TestCase):
self.assertEqual(typing.get_args(typing.get_type_hints(forward_after)['x']),
(int, Forward))
self.assertEqual(typing.get_args(typing.get_type_hints(forward_before)['x']),
- (int, Forward))
+ (Forward, int))
def test_or_type_operator_with_Protocol(self):
class Proto(typing.Protocol):
@@ -1015,9 +1034,14 @@ class UnionTests(unittest.TestCase):
return 1 / 0
bt = BadType('bt', (), {})
+ bt2 = BadType('bt2', (), {})
# Comparison should fail and errors should propagate out for bad types.
+ union1 = int | bt
+ union2 = int | bt2
+ with self.assertRaises(ZeroDivisionError):
+ union1 == union2
with self.assertRaises(ZeroDivisionError):
- list[int] | list[bt]
+ bt | bt2
union_ga = (list[str] | int, collections.abc.Callable[..., str] | int,
d | int)
@@ -1060,6 +1084,14 @@ class UnionTests(unittest.TestCase):
self.assertLessEqual(sys.gettotalrefcount() - before, leeway,
msg='Check for union reference leak.')
+ def test_instantiation(self):
+ with self.assertRaises(TypeError):
+ types.UnionType()
+ self.assertIs(int, types.UnionType[int])
+ self.assertIs(int, types.UnionType[int, int])
+ self.assertEqual(int | str, types.UnionType[int, str])
+ self.assertEqual(int | typing.ForwardRef("str"), types.UnionType[int, "str"])
+
class MappingProxyTests(unittest.TestCase):
mappingproxy = types.MappingProxyType
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 591fb860eee..e88c811bfca 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -502,7 +502,7 @@ class TypeVarTests(BaseTestCase):
def test_bound_errors(self):
with self.assertRaises(TypeError):
- TypeVar('X', bound=Union)
+ TypeVar('X', bound=Optional)
with self.assertRaises(TypeError):
TypeVar('X', str, float, bound=Employee)
with self.assertRaisesRegex(TypeError,
@@ -542,7 +542,7 @@ class TypeVarTests(BaseTestCase):
def test_bad_var_substitution(self):
T = TypeVar('T')
bad_args = (
- (), (int, str), Union,
+ (), (int, str), Optional,
Generic, Generic[T], Protocol, Protocol[T],
Final, Final[int], ClassVar, ClassVar[int],
)
@@ -2044,10 +2044,6 @@ class UnionTests(BaseTestCase):
def test_union_issubclass_type_error(self):
with self.assertRaises(TypeError):
- issubclass(int, Union)
- with self.assertRaises(TypeError):
- issubclass(Union, int)
- with self.assertRaises(TypeError):
issubclass(Union[int, str], int)
with self.assertRaises(TypeError):
issubclass(int, Union[str, list[int]])
@@ -2121,41 +2117,40 @@ class UnionTests(BaseTestCase):
self.assertEqual(Union[A, B].__args__, (A, B))
union1 = Union[A, B]
- with self.assertRaises(TypeError):
+ with self.assertRaisesRegex(TypeError, "unhashable type: 'UnhashableMeta'"):
hash(union1)
union2 = Union[int, B]
- with self.assertRaises(TypeError):
+ with self.assertRaisesRegex(TypeError, "unhashable type: 'UnhashableMeta'"):
hash(union2)
union3 = Union[A, int]
- with self.assertRaises(TypeError):
+ with self.assertRaisesRegex(TypeError, "unhashable type: 'UnhashableMeta'"):
hash(union3)
def test_repr(self):
- self.assertEqual(repr(Union), 'typing.Union')
u = Union[Employee, int]
- self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__)
+ self.assertEqual(repr(u), f'{__name__}.Employee | int')
u = Union[int, Employee]
- self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__)
+ self.assertEqual(repr(u), f'int | {__name__}.Employee')
T = TypeVar('T')
u = Union[T, int][int]
self.assertEqual(repr(u), repr(int))
u = Union[List[int], int]
- self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]')
+ self.assertEqual(repr(u), 'typing.List[int] | int')
u = Union[list[int], dict[str, float]]
- self.assertEqual(repr(u), 'typing.Union[list[int], dict[str, float]]')
+ self.assertEqual(repr(u), 'list[int] | dict[str, float]')
u = Union[int | float]
- self.assertEqual(repr(u), 'typing.Union[int, float]')
+ self.assertEqual(repr(u), 'int | float')
u = Union[None, str]
- self.assertEqual(repr(u), 'typing.Optional[str]')
+ self.assertEqual(repr(u), 'None | str')
u = Union[str, None]
- self.assertEqual(repr(u), 'typing.Optional[str]')
+ self.assertEqual(repr(u), 'str | None')
u = Union[None, str, int]
- self.assertEqual(repr(u), 'typing.Union[NoneType, str, int]')
+ self.assertEqual(repr(u), 'None | str | int')
u = Optional[str]
- self.assertEqual(repr(u), 'typing.Optional[str]')
+ self.assertEqual(repr(u), 'str | None')
def test_dir(self):
dir_items = set(dir(Union[str, int]))
@@ -2167,14 +2162,11 @@ class UnionTests(BaseTestCase):
def test_cannot_subclass(self):
with self.assertRaisesRegex(TypeError,
- r'Cannot subclass typing\.Union'):
+ r"type 'typing\.Union' is not an acceptable base type"):
class C(Union):
pass
- with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE):
- class D(type(Union)):
- pass
with self.assertRaisesRegex(TypeError,
- r'Cannot subclass typing\.Union\[int, str\]'):
+ r'Cannot subclass int \| str'):
class E(Union[int, str]):
pass
@@ -2220,7 +2212,7 @@ class UnionTests(BaseTestCase):
def test_function_repr_union(self):
def fun() -> int: ...
- self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]')
+ self.assertEqual(repr(Union[fun, int]), f'{__name__}.{fun.__qualname__} | int')
def test_union_str_pattern(self):
# Shouldn't crash; see http://bugs.python.org/issue25390
@@ -4895,11 +4887,11 @@ class GenericTests(BaseTestCase):
def test_extended_generic_rules_repr(self):
T = TypeVar('T')
self.assertEqual(repr(Union[Tuple, Callable]).replace('typing.', ''),
- 'Union[Tuple, Callable]')
+ 'Tuple | Callable')
self.assertEqual(repr(Union[Tuple, Tuple[int]]).replace('typing.', ''),
- 'Union[Tuple, Tuple[int]]')
+ 'Tuple | Tuple[int]')
self.assertEqual(repr(Callable[..., Optional[T]][int]).replace('typing.', ''),
- 'Callable[..., Optional[int]]')
+ 'Callable[..., int | None]')
self.assertEqual(repr(Callable[[], List[T]][int]).replace('typing.', ''),
'Callable[[], List[int]]')
@@ -5079,9 +5071,9 @@ class GenericTests(BaseTestCase):
with self.assertRaises(TypeError):
issubclass(Tuple[int, ...], typing.Iterable)
- def test_fail_with_bare_union(self):
+ def test_fail_with_special_forms(self):
with self.assertRaises(TypeError):
- List[Union]
+ List[Final]
with self.assertRaises(TypeError):
Tuple[Optional]
with self.assertRaises(TypeError):
@@ -5623,8 +5615,6 @@ class GenericTests(BaseTestCase):
for obj in (
ClassVar[int],
Final[int],
- Union[int, float],
- Optional[int],
Literal[1, 2],
Concatenate[int, ParamSpec("P")],
TypeGuard[int],
@@ -5656,7 +5646,7 @@ class GenericTests(BaseTestCase):
__parameters__ = (T,)
# Bare classes should be skipped
for a in (List, list):
- for b in (A, int, TypeVar, TypeVarTuple, ParamSpec, types.GenericAlias, types.UnionType):
+ for b in (A, int, TypeVar, TypeVarTuple, ParamSpec, types.GenericAlias, Union):
with self.subTest(generic=a, sub=b):
with self.assertRaisesRegex(TypeError, '.* is not a generic class'):
a[b][str]
@@ -5675,7 +5665,7 @@ class GenericTests(BaseTestCase):
for s in (int, G, A, List, list,
TypeVar, TypeVarTuple, ParamSpec,
- types.GenericAlias, types.UnionType):
+ types.GenericAlias, Union):
for t in Tuple, tuple:
with self.subTest(tuple=t, sub=s):
@@ -7176,7 +7166,7 @@ class GetUtilitiesTestCase(TestCase):
self.assertIs(get_origin(Callable), collections.abc.Callable)
self.assertIs(get_origin(list[int]), list)
self.assertIs(get_origin(list), None)
- self.assertIs(get_origin(list | str), types.UnionType)
+ self.assertIs(get_origin(list | str), Union)
self.assertIs(get_origin(P.args), P)
self.assertIs(get_origin(P.kwargs), P)
self.assertIs(get_origin(Required[int]), Required)
@@ -10434,7 +10424,6 @@ class SpecialAttrsTests(BaseTestCase):
typing.TypeGuard: 'TypeGuard',
typing.TypeIs: 'TypeIs',
typing.TypeVar: 'TypeVar',
- typing.Union: 'Union',
typing.Self: 'Self',
# Subscripted special forms
typing.Annotated[Any, "Annotation"]: 'Annotated',
@@ -10445,7 +10434,7 @@ class SpecialAttrsTests(BaseTestCase):
typing.Literal[Any]: 'Literal',
typing.Literal[1, 2]: 'Literal',
typing.Literal[True, 2]: 'Literal',
- typing.Optional[Any]: 'Optional',
+ typing.Optional[Any]: 'Union',
typing.TypeGuard[Any]: 'TypeGuard',
typing.TypeIs[Any]: 'TypeIs',
typing.Union[Any]: 'Any',
@@ -10464,7 +10453,10 @@ class SpecialAttrsTests(BaseTestCase):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
s = pickle.dumps(cls, proto)
loaded = pickle.loads(s)
- self.assertIs(cls, loaded)
+ if isinstance(cls, Union):
+ self.assertEqual(cls, loaded)
+ else:
+ self.assertIs(cls, loaded)
TypeName = typing.NewType('SpecialAttrsTests.TypeName', Any)
@@ -10739,6 +10731,34 @@ class TypeIterationTests(BaseTestCase):
self.assertNotIsInstance(type_to_test, collections.abc.Iterable)
+class UnionGenericAliasTests(BaseTestCase):
+ def test_constructor(self):
+ # Used e.g. in typer, pydantic
+ with self.assertWarns(DeprecationWarning):
+ inst = typing._UnionGenericAlias(typing.Union, (int, str))
+ self.assertEqual(inst, int | str)
+ with self.assertWarns(DeprecationWarning):
+ # name is accepted but ignored
+ inst = typing._UnionGenericAlias(typing.Union, (int, None), name="Optional")
+ self.assertEqual(inst, int | None)
+
+ def test_isinstance(self):
+ # Used e.g. in pydantic
+ with self.assertWarns(DeprecationWarning):
+ self.assertTrue(isinstance(Union[int, str], typing._UnionGenericAlias))
+ with self.assertWarns(DeprecationWarning):
+ self.assertFalse(isinstance(int, typing._UnionGenericAlias))
+
+ def test_eq(self):
+ # type(t) == _UnionGenericAlias is used in vyos
+ with self.assertWarns(DeprecationWarning):
+ self.assertEqual(Union, typing._UnionGenericAlias)
+ with self.assertWarns(DeprecationWarning):
+ self.assertEqual(typing._UnionGenericAlias, typing._UnionGenericAlias)
+ with self.assertWarns(DeprecationWarning):
+ self.assertNotEqual(int, typing._UnionGenericAlias)
+
+
def load_tests(loader, tests, pattern):
import doctest
tests.addTests(doctest.DocTestSuite(typing))