diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2021-07-24 13:34:48 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-24 13:34:48 (GMT) |
commit | 08284231275ac9cc60ae27eab2338805919d8881 (patch) | |
tree | 4d61a5ef20902208d8615ac052e39d070e85c73d /Lib | |
parent | 3eae8f20d7b6f88d3618b0afc94893165a914022 (diff) | |
download | cpython-08284231275ac9cc60ae27eab2338805919d8881.zip cpython-08284231275ac9cc60ae27eab2338805919d8881.tar.gz cpython-08284231275ac9cc60ae27eab2338805919d8881.tar.bz2 |
bpo-44731: Simplify the union type implementation (GH-27318)
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.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_types.py | 26 | ||||
-rw-r--r-- | Lib/typing.py | 6 |
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 198837c..3403f55 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -383,6 +383,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()") |