From cbb91e60b2217639f51f4ea35ae13ff8f80f7deb Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Sun, 17 Nov 2024 18:58:26 -0500 Subject: [PATCH 1/2] Infer generic type arguments for slice expressions --- mypy/checkexpr.py | 6 +++++- test-data/unit/check-expressions.test | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 577576a4e5f8..d23382c4cdd0 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -5616,7 +5616,11 @@ def visit_slice_expr(self, e: SliceExpr) -> Type: if index: t = self.accept(index) self.chk.check_subtype(t, expected, index, message_registry.INVALID_SLICE_INDEX) - return self.named_type("builtins.slice") + type_args = [ + NoneType() if arg is None else self.accept(arg) + for arg in [e.begin_index, e.end_index, e.stride] + ] + return self.chk.named_generic_type("builtins.slice", type_args) def visit_list_comprehension(self, e: ListComprehension) -> Type: return self.check_generator_or_comprehension( diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index d5ddc910bcd6..cd26c9bb408a 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -1178,8 +1178,8 @@ class B: pass [case testSlicingWithInvalidBase] a: A -a[1:2] # E: Invalid index type "slice" for "A"; expected type "int" -a[:] # E: Invalid index type "slice" for "A"; expected type "int" +a[1:2] # E: Invalid index type "slice[int, int, None]" for "A"; expected type "int" +a[:] # E: Invalid index type "slice[None, None, None]" for "A"; expected type "int" class A: def __getitem__(self, n: int) -> 'A': pass [builtins fixtures/slice.pyi] From 510455ac289cadbe1926a1fbceea83dd23560a46 Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Mon, 18 Nov 2024 08:15:15 -0500 Subject: [PATCH 2/2] Visit index expressions only once --- mypy/checkexpr.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index d23382c4cdd0..11a9cffe18c3 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -5612,14 +5612,14 @@ def visit_slice_expr(self, e: SliceExpr) -> Type: except KeyError: supports_index = self.chk.named_type("builtins.int") # thanks, fixture life expected = make_optional_type(supports_index) + type_args = [] for index in [e.begin_index, e.end_index, e.stride]: if index: t = self.accept(index) self.chk.check_subtype(t, expected, index, message_registry.INVALID_SLICE_INDEX) - type_args = [ - NoneType() if arg is None else self.accept(arg) - for arg in [e.begin_index, e.end_index, e.stride] - ] + type_args.append(t) + else: + type_args.append(NoneType()) return self.chk.named_generic_type("builtins.slice", type_args) def visit_list_comprehension(self, e: ListComprehension) -> Type: