Skip to content

Commit

Permalink
Infer generic type arguments for slice expressions (#18160)
Browse files Browse the repository at this point in the history
Fixes  #18149

Slices were made generic in
python/typeshed#11637. Currently, all slice
expressions are inferred to have type `slice[Any, Any, Any]`. This PR
fills in the generic type arguments more appropriately using
start/stop/stride expression types.

Given
```python
class Foo:
    def __getitem__[T](self, item: T) -> T: return item

x = Foo()
reveal_type(x[1:])
```
Before:
```none
main.py:5: note: Revealed type is "builtins.slice[Any, Any, Any]"
```
After:
```none
main.py:5: note: Revealed type is "builtins.slice[builtins.int, None, None]"
```
  • Loading branch information
brianschubert authored Nov 19, 2024
1 parent 8ef2197 commit 6759dbd
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 3 deletions.
6 changes: 5 additions & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -5612,11 +5612,15 @@ 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)
return self.named_type("builtins.slice")
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:
return self.check_generator_or_comprehension(
Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-expressions.test
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit 6759dbd

Please sign in to comment.