mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-19 20:24:27 +00:00
## Summary Currently our diagnostic only covers the range of the thing being subscripted: <img width="1702" height="312" alt="image" src="https://github.com/user-attachments/assets/7e630431-e846-46ca-93c1-139f11aaba11" /> But it should probably cover the _whole_ subscript expression (arguably the more "incorrect" bit is the `["foo"]` part of this expression, not the `x` part of this expression!) ## Test Plan Added a snapshot Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
2.6 KiB
2.6 KiB
Instance subscript
__getitem__ unbound
class NotSubscriptable: ...
a = NotSubscriptable()[0] # error: [non-subscriptable]
__getitem__ not callable
class NotSubscriptable:
__getitem__ = None
# TODO: this would be more user-friendly if the `call-non-callable` diagnostic was
# transformed into a `not-subscriptable` diagnostic with a subdiagnostic explaining
# that this was because `__getitem__` was possibly not callable
#
# error: [call-non-callable] "Method `__getitem__` of type `Unknown | None` may not be callable on object of type `NotSubscriptable`"
a = NotSubscriptable()[0]
Valid __getitem__
class Identity:
def __getitem__(self, index: int) -> int:
return index
reveal_type(Identity()[0]) # revealed: int
__getitem__ union
def _(flag: bool):
class Identity:
if flag:
def __getitem__(self, index: int) -> int:
return index
else:
def __getitem__(self, index: int) -> str:
return str(index)
reveal_type(Identity()[0]) # revealed: int | str
__getitem__ with invalid index argument
class Identity:
def __getitem__(self, index: int) -> int:
return index
a = Identity()
# error: [invalid-argument-type] "Method `__getitem__` of type `bound method Identity.__getitem__(index: int) -> int` cannot be called with key of type `Literal["a"]` on object of type `Identity`"
a["a"]
__setitem__ with no __getitem__
class NoGetitem:
def __setitem__(self, index: int, value: int) -> None:
pass
a = NoGetitem()
a[0] = 0
Subscript store with no __setitem__
class NoSetitem: ...
a = NoSetitem()
a[0] = 0 # error: "Cannot assign to a subscript on an object of type `NoSetitem`"
__setitem__ not callable
class NoSetitem:
__setitem__ = None
a = NoSetitem()
a[0] = 0 # error: "Method `__setitem__` of type `Unknown | None` may not be callable on object of type `NoSetitem`"
Valid __setitem__ method
class Identity:
def __setitem__(self, index: int, value: int) -> None:
pass
a = Identity()
a[0] = 0
__setitem__ with invalid index argument
class Identity:
def __setitem__(self, index: int, value: int) -> None:
pass
a = Identity()
# error: [invalid-assignment] "Method `__setitem__` of type `bound method Identity.__setitem__(index: int, value: int) -> None` cannot be called with a key of type `Literal["a"]` and a value of type `Literal[0]` on object of type `Identity`"
a["a"] = 0