From a2b86c27f6f4a1d959a3175cfccdf8510f237530 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 16 Jan 2022 11:46:17 +0300 Subject: [PATCH 1/4] bpo-46396: test invalid `Concatenate` usages in `test_typing` --- Lib/test/test_typing.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index cf719df6da1d7a0..d4d7836785dff8f 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4868,6 +4868,28 @@ def test_valid_uses(self): self.assertEqual(C4.__args__, (Concatenate[int, T, P], T)) self.assertEqual(C4.__parameters__, (T, P)) + def test_invalud_uses(self): + P = ParamSpec('P') + T = TypeVar('T') + + with self.assertRaisesRegex( + TypeError, + 'Cannot take a Concatenate of no types', + ): + Concatenate[()] + + with self.assertRaisesRegex( + TypeError, + 'The last parameter to Concatenate should be a ParamSpec variable', + ): + Concatenate[P, T] + + with self.assertRaisesRegex( + TypeError, + 'each arg must be a type', + ): + Concatenate[1, P] + class TypeGuardTests(BaseTestCase): def test_basics(self): From 3b175c104a2ac9f331fb383e64489d034d3239c6 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 16 Jan 2022 11:47:16 +0300 Subject: [PATCH 2/4] Typo --- Lib/test/test_typing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index d4d7836785dff8f..f561199735aa38d 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4868,7 +4868,7 @@ def test_valid_uses(self): self.assertEqual(C4.__args__, (Concatenate[int, T, P], T)) self.assertEqual(C4.__parameters__, (T, P)) - def test_invalud_uses(self): + def test_invalid_uses(self): P = ParamSpec('P') T = TypeVar('T') From cf5ee38ad4bce12ea7787cee30bb371291af1411 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 24 Jan 2022 16:18:39 +0300 Subject: [PATCH 3/4] Refactor `Concatenate` not to raise semantic errors --- Lib/test/test_typing.py | 24 +++++++----------------- Lib/typing.py | 5 ----- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index f561199735aa38d..64551e667fc920d 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4868,27 +4868,17 @@ def test_valid_uses(self): self.assertEqual(C4.__args__, (Concatenate[int, T, P], T)) self.assertEqual(C4.__parameters__, (T, P)) - def test_invalid_uses(self): + def test_semantically_invalid_uses_have_no_errors(self): P = ParamSpec('P') T = TypeVar('T') - with self.assertRaisesRegex( - TypeError, - 'Cannot take a Concatenate of no types', - ): - Concatenate[()] + self.assertEqual(Concatenate[()].__args__, ()) + self.assertEqual(Concatenate[int].__args__, (int,)) + self.assertEqual(Concatenate[P, T].__args__, (P, T)) - with self.assertRaisesRegex( - TypeError, - 'The last parameter to Concatenate should be a ParamSpec variable', - ): - Concatenate[P, T] - - with self.assertRaisesRegex( - TypeError, - 'each arg must be a type', - ): - Concatenate[1, P] + def test_invalid_uses_that_generate_errors(self): + with self.assertRaises(TypeError): + Concatenate[1, 2] class TypeGuardTests(BaseTestCase): diff --git a/Lib/typing.py b/Lib/typing.py index 972b8ba24b27e83..250dc7959fae343 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -598,13 +598,8 @@ def Concatenate(self, parameters): See PEP 612 for detailed information. """ - if parameters == (): - raise TypeError("Cannot take a Concatenate of no types.") if not isinstance(parameters, tuple): parameters = (parameters,) - if not isinstance(parameters[-1], ParamSpec): - raise TypeError("The last parameter to Concatenate should be a " - "ParamSpec variable.") msg = "Concatenate[arg, ...]: each arg must be a type." parameters = tuple(_type_check(p, msg) for p in parameters) return _ConcatenateGenericAlias(self, parameters) From fa5bc9a794c5b49ac32151a819b14429a25e6299 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 24 Jan 2022 16:20:10 +0300 Subject: [PATCH 4/4] Add `NEWS` --- .../next/Library/2022-01-24-16-19-54.bpo-46396.qQYnUk.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-01-24-16-19-54.bpo-46396.qQYnUk.rst diff --git a/Misc/NEWS.d/next/Library/2022-01-24-16-19-54.bpo-46396.qQYnUk.rst b/Misc/NEWS.d/next/Library/2022-01-24-16-19-54.bpo-46396.qQYnUk.rst new file mode 100644 index 000000000000000..b5a5ebf02e74422 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-24-16-19-54.bpo-46396.qQYnUk.rst @@ -0,0 +1,3 @@ +:class:`typing.Concatenate` does not raise semantic errors anymore. + +We leave type validation to type-checkers.