summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorKen Jin <28750310+Fidget-Spinner@users.noreply.github.com>2021-07-24 14:49:25 (GMT)
committerGitHub <noreply@github.com>2021-07-24 14:49:25 (GMT)
commitca5a4cf8266cf789eae379fe224458e94dd41b30 (patch)
treec99a722f3868b74633e93a6074ffa5931b3b8e36 /Lib
parent9356d1e47de583fd794e9d29abc448759f7a4109 (diff)
downloadcpython-ca5a4cf8266cf789eae379fe224458e94dd41b30.zip
cpython-ca5a4cf8266cf789eae379fe224458e94dd41b30.tar.gz
cpython-ca5a4cf8266cf789eae379fe224458e94dd41b30.tar.bz2
bpo-44731: Simplify the union type implementation (GH-27318) (GH-27334)
Remove direct support of typing types in the C code because they are already supported by defining methods __or__ and __ror__ in the Python code. Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_types.py26
-rw-r--r--Lib/typing.py6
2 files changed, 19 insertions, 13 deletions
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index d149e6b..3f491ee 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -776,31 +776,32 @@ class UnionTests(unittest.TestCase):
self.assertEqual((list[T] | list[S])[int, int], list[int])
def test_union_parameter_substitution(self):
- def eq(actual, expected):
+ def eq(actual, expected, typed=True):
self.assertEqual(actual, expected)
- self.assertIs(type(actual), type(expected))
+ if typed:
+ self.assertIs(type(actual), type(expected))
T = typing.TypeVar('T')
S = typing.TypeVar('S')
NT = typing.NewType('NT', str)
x = int | T | bytes
- eq(x[str], int | str | bytes)
- eq(x[list[int]], int | list[int] | bytes)
+ eq(x[str], int | str | bytes, typed=False)
+ eq(x[list[int]], int | list[int] | bytes, typed=False)
eq(x[typing.List], int | typing.List | bytes)
eq(x[typing.List[int]], int | typing.List[int] | bytes)
eq(x[typing.Hashable], int | typing.Hashable | bytes)
eq(x[collections.abc.Hashable],
- int | collections.abc.Hashable | bytes)
+ int | collections.abc.Hashable | bytes, typed=False)
eq(x[typing.Callable[[int], str]],
int | typing.Callable[[int], str] | bytes)
eq(x[collections.abc.Callable[[int], str]],
- int | collections.abc.Callable[[int], str] | bytes)
+ int | collections.abc.Callable[[int], str] | bytes, typed=False)
eq(x[typing.Tuple[int, str]], int | typing.Tuple[int, str] | bytes)
eq(x[typing.Literal['none']], int | typing.Literal['none'] | bytes)
- eq(x[str | list], int | str | list | bytes)
+ eq(x[str | list], int | str | list | bytes, typed=False)
eq(x[typing.Union[str, list]], typing.Union[int, str, list, bytes])
- eq(x[str | int], int | str | bytes)
+ eq(x[str | int], int | str | bytes, typed=False)
eq(x[typing.Union[str, int]], typing.Union[int, str, bytes])
eq(x[NT], int | NT | bytes)
eq(x[S], int | S | bytes)
@@ -829,9 +830,9 @@ class UnionTests(unittest.TestCase):
with self.assertRaisesRegex(ValueError, r"args must be not empty"):
types.Union._from_args(())
- alias = types.Union._from_args((int, str, T))
+ alias = types.Union._from_args((int, list[T], None))
- self.assertEqual(alias.__args__, (int, str, T))
+ self.assertEqual(alias.__args__, (int, list[T], type(None)))
self.assertEqual(alias.__parameters__, (T,))
result = types.Union._from_args((int,))
@@ -894,7 +895,6 @@ class UnionTests(unittest.TestCase):
assert repr(int | None) == "int | None"
assert repr(int | type(None)) == "int | None"
assert repr(int | typing.GenericAlias(list, int)) == "int | list[int]"
- assert repr(int | typing.TypeVar('T')) == "int | ~T"
def test_or_type_operator_with_genericalias(self):
a = list[int]
@@ -939,9 +939,9 @@ class UnionTests(unittest.TestCase):
TypeVar = BadMeta('TypeVar', (), {})
_SpecialForm = BadMeta('_SpecialForm', (), {})
# Crashes in Issue44483
- with self.assertRaises(ZeroDivisionError):
+ with self.assertRaises((TypeError, ZeroDivisionError)):
str | TypeVar()
- with self.assertRaises(ZeroDivisionError):
+ with self.assertRaises((TypeError, ZeroDivisionError)):
str | _SpecialForm()
@cpython_only
diff --git a/Lib/typing.py b/Lib/typing.py
index e2fb7d1..0570b4e 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -375,6 +375,12 @@ class _SpecialForm(_Final, _root=True):
def __call__(self, *args, **kwds):
raise TypeError(f"Cannot instantiate {self!r}")
+ def __or__(self, other):
+ return Union[self, other]
+
+ def __ror__(self, other):
+ return Union[other, self]
+
def __instancecheck__(self, obj):
raise TypeError(f"{self} cannot be used with isinstance()")