From 7bb0cdc2510e9b973ff418d84f4dce7f225b8308 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 24 Nov 2022 13:59:56 +0000 Subject: [PATCH 1/7] Add test cases from #12134 by @sobolevn --- test-data/unit/check-type-aliases.test | 25 +++++++++++++++++++++++++ test-data/unit/pythoneval.test | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index e9b5e3e4d966..e7e41fa1eca7 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -993,3 +993,28 @@ x_bad: A[bytes] # E: Value of type variable "S" of "A" cannot be "bytes" B = List[C[U]] y: B[int] y_bad: B[str] # E: Type argument "str" of "B" must be a subtype of "int" + +[case testTupleWithDifferentArgsPy38] +# flags: --python-version 3.8 +NotYet1 = tuple[float] # E: "tuple" is not subscriptable +NotYet2 = tuple[float, float] # E: "tuple" is not subscriptable +[builtins fixtures/tuple.pyi] + +[case testTupleWithDifferentArgsStub] +# https://github.com/python/mypy/issues/11098 +import tup + +[file tup.pyi] +Correct1 = str | tuple[float, float, str] +Correct2 = tuple[float] | str +Correct3 = tuple[float, ...] | str + +RHSAlias1: type = tuple[int, int] +RHSAlias2: type = tuple[int] +RHSAlias3: type = tuple[int, ...] + +# Wrong: + +WrongTypeElement = str | tuple[float, 1] # E: Invalid type: try using Literal[1] instead? +WrongEllipsis = str | tuple[float, float, ...] # E: Unexpected "..." +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index acaaf5f21cf0..9330e9f2447f 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1816,3 +1816,21 @@ def foo(k: str) -> TD: return x.get(k, {}) [out] _testTypedDictUnionGetFull.py:11: note: Revealed type is "TypedDict('_testTypedDictUnionGetFull.TD', {'x'?: builtins.int, 'y'?: builtins.int})" + +[case testTupleWithDifferentArgsPy310] +# https://github.com/python/mypy/issues/11098 +# flags: --python-version 3.10 +Correct1 = str | tuple[float, float, str] +Correct2 = tuple[float] | str +Correct3 = tuple[float, ...] | str + +RHSAlias1: type = tuple[int, int] +RHSAlias2: type = tuple[int] +RHSAlias3: type = tuple[int, ...] + +# Wrong: +WrongTypeElement = str | tuple[float, 1] +WrongEllipsis = tuple[float, float, ...] | str +[out] +_testTupleWithDifferentArgsPy310.py:12: error: Invalid type: try using Literal[1] instead? +_testTupleWithDifferentArgsPy310.py:13: error: Unexpected "..." From 2a1ab2d16d207987b7a6bd4bde64b7a3a112582f Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 24 Nov 2022 14:07:57 +0000 Subject: [PATCH 2/7] Extract fix from #14181 --- mypy/checkexpr.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index ad0f42f1e32a..a1b671333788 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -3968,6 +3968,8 @@ def apply_type_arguments_to_callable( tp = get_proper_type(tp) if isinstance(tp, CallableType): + if tp.is_type_obj() and tp.type_object().fullname == "builtins.tuple": + return tp if len(tp.variables) != len(args): self.msg.incompatible_type_application(len(tp.variables), len(args), ctx) return AnyType(TypeOfAny.from_error) From 68719a5e3a839dd003236c01333f751a220d96c3 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 24 Nov 2022 14:14:33 +0000 Subject: [PATCH 3/7] Update test cases --- test-data/unit/check-type-aliases.test | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index e7e41fa1eca7..e5d9bf94873a 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -998,6 +998,10 @@ y_bad: B[str] # E: Type argument "str" of "B" must be a subtype of "int" # flags: --python-version 3.8 NotYet1 = tuple[float] # E: "tuple" is not subscriptable NotYet2 = tuple[float, float] # E: "tuple" is not subscriptable +NotYet3 = tuple[float, ...] # E: Unexpected "..." \ + # E: "tuple" is not subscriptable +NotYet4 = tuple[float, float, ...] # E: Unexpected "..." \ + # E: "tuple" is not subscriptable [builtins fixtures/tuple.pyi] [case testTupleWithDifferentArgsStub] @@ -1008,6 +1012,9 @@ import tup Correct1 = str | tuple[float, float, str] Correct2 = tuple[float] | str Correct3 = tuple[float, ...] | str +Correct4 = tuple[float, str] | str +Correct5 = tuple[int, str] +Correct6 = tuple[int, ...] RHSAlias1: type = tuple[int, int] RHSAlias2: type = tuple[int] From bdc6cf1223774572374545a03eb831b6e8f34e21 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 24 Nov 2022 14:17:40 +0000 Subject: [PATCH 4/7] Update test case --- test-data/unit/pythoneval.test | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 9330e9f2447f..250ec377cf14 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1823,6 +1823,18 @@ _testTypedDictUnionGetFull.py:11: note: Revealed type is "TypedDict('_testTypedD Correct1 = str | tuple[float, float, str] Correct2 = tuple[float] | str Correct3 = tuple[float, ...] | str +Correct4 = tuple[float, str] +Correct5 = tuple[float, ...] +c1: Correct1 +c2: Correct2 +c3: Correct3 +c4: Correct4 +c5: Correct5 +reveal_type(c1) +reveal_type(c2) +reveal_type(c3) +reveal_type(c4) +reveal_type(c5) RHSAlias1: type = tuple[int, int] RHSAlias2: type = tuple[int] @@ -1832,5 +1844,10 @@ RHSAlias3: type = tuple[int, ...] WrongTypeElement = str | tuple[float, 1] WrongEllipsis = tuple[float, float, ...] | str [out] -_testTupleWithDifferentArgsPy310.py:12: error: Invalid type: try using Literal[1] instead? -_testTupleWithDifferentArgsPy310.py:13: error: Unexpected "..." +_testTupleWithDifferentArgsPy310.py:13: note: Revealed type is "Union[builtins.str, Tuple[builtins.float, builtins.float, builtins.str]]" +_testTupleWithDifferentArgsPy310.py:14: note: Revealed type is "Union[Tuple[builtins.float], builtins.str]" +_testTupleWithDifferentArgsPy310.py:15: note: Revealed type is "Union[builtins.tuple[builtins.float, ...], builtins.str]" +_testTupleWithDifferentArgsPy310.py:16: note: Revealed type is "Tuple[builtins.float, builtins.str]" +_testTupleWithDifferentArgsPy310.py:17: note: Revealed type is "builtins.tuple[builtins.float, ...]" +_testTupleWithDifferentArgsPy310.py:24: error: Invalid type: try using Literal[1] instead? +_testTupleWithDifferentArgsPy310.py:25: error: Unexpected "..." From a66c057ae050dd71ba46ec85f4baa7cf6421bf1c Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 24 Nov 2022 14:21:10 +0000 Subject: [PATCH 5/7] Add TODOs about using type application to create a tuple --- mypy/checkexpr.py | 1 + test-data/unit/pythoneval.test | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index a1b671333788..9d9a0aaa9800 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -3969,6 +3969,7 @@ def apply_type_arguments_to_callable( if isinstance(tp, CallableType): if tp.is_type_obj() and tp.type_object().fullname == "builtins.tuple": + # TODO: Specialize the callable for the type arguments return tp if len(tp.variables) != len(args): self.msg.incompatible_type_application(len(tp.variables), len(args), ctx) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 250ec377cf14..94b2d71ab062 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1840,14 +1840,17 @@ RHSAlias1: type = tuple[int, int] RHSAlias2: type = tuple[int] RHSAlias3: type = tuple[int, ...] -# Wrong: -WrongTypeElement = str | tuple[float, 1] -WrongEllipsis = tuple[float, float, ...] | str +WrongTypeElement = str | tuple[float, 1] # Error +WrongEllipsis = tuple[float, float, ...] | str # Error + +# TODO: This should produce a fixed-length tuple +reveal_type(tuple[int, str]((1, "x"))) [out] _testTupleWithDifferentArgsPy310.py:13: note: Revealed type is "Union[builtins.str, Tuple[builtins.float, builtins.float, builtins.str]]" _testTupleWithDifferentArgsPy310.py:14: note: Revealed type is "Union[Tuple[builtins.float], builtins.str]" _testTupleWithDifferentArgsPy310.py:15: note: Revealed type is "Union[builtins.tuple[builtins.float, ...], builtins.str]" _testTupleWithDifferentArgsPy310.py:16: note: Revealed type is "Tuple[builtins.float, builtins.str]" _testTupleWithDifferentArgsPy310.py:17: note: Revealed type is "builtins.tuple[builtins.float, ...]" -_testTupleWithDifferentArgsPy310.py:24: error: Invalid type: try using Literal[1] instead? -_testTupleWithDifferentArgsPy310.py:25: error: Unexpected "..." +_testTupleWithDifferentArgsPy310.py:23: error: Invalid type: try using Literal[1] instead? +_testTupleWithDifferentArgsPy310.py:24: error: Unexpected "..." +_testTupleWithDifferentArgsPy310.py:27: note: Revealed type is "builtins.tuple[builtins.object, ...]" From 68b369ec607b82955d0ea8c8c36abaa71e5b79e6 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 24 Nov 2022 14:33:39 +0000 Subject: [PATCH 6/7] Fix test case --- mypy/checkexpr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 9d9a0aaa9800..eb585aba42df 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -3968,10 +3968,10 @@ def apply_type_arguments_to_callable( tp = get_proper_type(tp) if isinstance(tp, CallableType): - if tp.is_type_obj() and tp.type_object().fullname == "builtins.tuple": - # TODO: Specialize the callable for the type arguments - return tp if len(tp.variables) != len(args): + if tp.is_type_obj() and tp.type_object().fullname == "builtins.tuple": + # TODO: Specialize the callable for the type arguments + return tp self.msg.incompatible_type_application(len(tp.variables), len(args), ctx) return AnyType(TypeOfAny.from_error) return self.apply_generic_arguments(tp, args, ctx) From 3ee919357e7cae3b85d747ab26190fc97d516186 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Fri, 25 Nov 2022 10:12:49 +0000 Subject: [PATCH 7/7] Update test case --- test-data/unit/pythoneval.test | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 94b2d71ab062..3520b5874018 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1825,16 +1825,19 @@ Correct2 = tuple[float] | str Correct3 = tuple[float, ...] | str Correct4 = tuple[float, str] Correct5 = tuple[float, ...] +Correct6 = list[tuple[int, str]] c1: Correct1 c2: Correct2 c3: Correct3 c4: Correct4 c5: Correct5 +c6: Correct6 reveal_type(c1) reveal_type(c2) reveal_type(c3) reveal_type(c4) reveal_type(c5) +reveal_type(c6) RHSAlias1: type = tuple[int, int] RHSAlias2: type = tuple[int] @@ -1846,11 +1849,12 @@ WrongEllipsis = tuple[float, float, ...] | str # Error # TODO: This should produce a fixed-length tuple reveal_type(tuple[int, str]((1, "x"))) [out] -_testTupleWithDifferentArgsPy310.py:13: note: Revealed type is "Union[builtins.str, Tuple[builtins.float, builtins.float, builtins.str]]" -_testTupleWithDifferentArgsPy310.py:14: note: Revealed type is "Union[Tuple[builtins.float], builtins.str]" -_testTupleWithDifferentArgsPy310.py:15: note: Revealed type is "Union[builtins.tuple[builtins.float, ...], builtins.str]" -_testTupleWithDifferentArgsPy310.py:16: note: Revealed type is "Tuple[builtins.float, builtins.str]" -_testTupleWithDifferentArgsPy310.py:17: note: Revealed type is "builtins.tuple[builtins.float, ...]" -_testTupleWithDifferentArgsPy310.py:23: error: Invalid type: try using Literal[1] instead? -_testTupleWithDifferentArgsPy310.py:24: error: Unexpected "..." -_testTupleWithDifferentArgsPy310.py:27: note: Revealed type is "builtins.tuple[builtins.object, ...]" +_testTupleWithDifferentArgsPy310.py:15: note: Revealed type is "Union[builtins.str, Tuple[builtins.float, builtins.float, builtins.str]]" +_testTupleWithDifferentArgsPy310.py:16: note: Revealed type is "Union[Tuple[builtins.float], builtins.str]" +_testTupleWithDifferentArgsPy310.py:17: note: Revealed type is "Union[builtins.tuple[builtins.float, ...], builtins.str]" +_testTupleWithDifferentArgsPy310.py:18: note: Revealed type is "Tuple[builtins.float, builtins.str]" +_testTupleWithDifferentArgsPy310.py:19: note: Revealed type is "builtins.tuple[builtins.float, ...]" +_testTupleWithDifferentArgsPy310.py:20: note: Revealed type is "builtins.list[Tuple[builtins.int, builtins.str]]" +_testTupleWithDifferentArgsPy310.py:26: error: Invalid type: try using Literal[1] instead? +_testTupleWithDifferentArgsPy310.py:27: error: Unexpected "..." +_testTupleWithDifferentArgsPy310.py:30: note: Revealed type is "builtins.tuple[builtins.object, ...]"