[ty] Subscript assignment diagnostics follow-up (#21452)
## Summary Follow up from https://github.com/astral-sh/ruff/pull/21411. Again, there are more things that could be improved here (like the diagnostics for `lists`, or extending what we have for `dict` to `OrderedDict` etc), but that will have to be postponed.
This commit is contained in:
@@ -313,7 +313,7 @@ def f(c: C, s: str):
|
||||
reveal_type(c.x) # revealed: int | None
|
||||
s = c.x # error: [invalid-assignment]
|
||||
|
||||
# error: [invalid-assignment] "Method `__setitem__` of type `Overload[(key: SupportsIndex, value: int, /) -> None, (key: slice[Any, Any, Any], value: Iterable[int], /) -> None]` cannot be called with a key of type `Literal[0]` and a value of type `str` on object of type `list[int]`"
|
||||
# error: [invalid-assignment] "Invalid subscript assignment with key of type `Literal[0]` and value of type `str` on object of type `list[int]`"
|
||||
c.l[0] = s
|
||||
reveal_type(c.l[0]) # revealed: int
|
||||
```
|
||||
|
||||
@@ -3,7 +3,7 @@ source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: assignment_diagnostics.md - Subscript assignment diagnostics - Invalid key type
|
||||
mdtest name: assignment_diagnostics.md - Subscript assignment diagnostics - Invalid key type - For a `dict`
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/subscript/assignment_diagnostics.md
|
||||
---
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: assignment_diagnostics.md - Subscript assignment diagnostics - Invalid key type - For a `list`
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/subscript/assignment_diagnostics.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | numbers: list[int] = []
|
||||
2 | numbers["zero"] = 3 # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error[invalid-assignment]: Invalid subscript assignment with key of type `Literal["zero"]` and value of type `Literal[3]` on object of type `list[int]`
|
||||
--> src/mdtest_snippet.py:2:1
|
||||
|
|
||||
1 | numbers: list[int] = []
|
||||
2 | numbers["zero"] = 3 # error: [invalid-assignment]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
info: rule `invalid-assignment` is enabled by default
|
||||
|
||||
```
|
||||
@@ -3,7 +3,7 @@ source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: assignment_diagnostics.md - Subscript assignment diagnostics - Invalid value type
|
||||
mdtest name: assignment_diagnostics.md - Subscript assignment diagnostics - Invalid value type - For a `dict`
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/subscript/assignment_diagnostics.md
|
||||
---
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: assignment_diagnostics.md - Subscript assignment diagnostics - Invalid value type - For a `list`
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/subscript/assignment_diagnostics.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | numbers: list[int] = []
|
||||
2 | numbers[0] = "three" # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error[invalid-assignment]: Invalid subscript assignment with key of type `Literal[0]` and value of type `Literal["three"]` on object of type `list[int]`
|
||||
--> src/mdtest_snippet.py:2:1
|
||||
|
|
||||
1 | numbers: list[int] = []
|
||||
2 | numbers[0] = "three" # error: [invalid-assignment]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
info: rule `invalid-assignment` is enabled by default
|
||||
|
||||
```
|
||||
@@ -89,7 +89,7 @@ info: rule `invalid-key` is enabled by default
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-key]: TypedDict `Person` can only be subscripted with string literal keys, got key of type `str`
|
||||
error[invalid-key]: TypedDict `Person` can only be subscripted with a string literal key, got key of type `str`
|
||||
--> src/mdtest_snippet.py:16:12
|
||||
|
|
||||
15 | def access_with_str_key(person: Person, str_key: str):
|
||||
|
||||
@@ -4,6 +4,15 @@
|
||||
|
||||
## Invalid value type
|
||||
|
||||
### For a `list`
|
||||
|
||||
```py
|
||||
numbers: list[int] = []
|
||||
numbers[0] = "three" # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
### For a `dict`
|
||||
|
||||
```py
|
||||
config: dict[str, int] = {}
|
||||
config["retries"] = "three" # error: [invalid-assignment]
|
||||
@@ -11,6 +20,15 @@ config["retries"] = "three" # error: [invalid-assignment]
|
||||
|
||||
## Invalid key type
|
||||
|
||||
### For a `list`
|
||||
|
||||
```py
|
||||
numbers: list[int] = []
|
||||
numbers["zero"] = 3 # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
### For a `dict`
|
||||
|
||||
```py
|
||||
config: dict[str, int] = {}
|
||||
config[0] = 3 # error: [invalid-assignment]
|
||||
|
||||
@@ -110,6 +110,6 @@ class Identity:
|
||||
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`"
|
||||
# error: [invalid-assignment] "Invalid subscript assignment with key of type `Literal["a"]` and value of type `Literal[0]` on object of type `Identity`"
|
||||
a["a"] = 0
|
||||
```
|
||||
|
||||
@@ -69,7 +69,7 @@ def name_or_age() -> Literal["name", "age"]:
|
||||
carol: Person = {NAME: "Carol", AGE: 20}
|
||||
|
||||
reveal_type(carol[NAME]) # revealed: str
|
||||
# error: [invalid-key] "TypedDict `Person` can only be subscripted with string literal keys, got key of type `str`"
|
||||
# error: [invalid-key] "TypedDict `Person` can only be subscripted with a string literal key, got key of type `str`"
|
||||
reveal_type(carol[non_literal()]) # revealed: Unknown
|
||||
reveal_type(carol[name_or_age()]) # revealed: str | int | None
|
||||
|
||||
@@ -553,7 +553,7 @@ def _(
|
||||
# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "non_existing""
|
||||
reveal_type(person["non_existing"]) # revealed: Unknown
|
||||
|
||||
# error: [invalid-key] "TypedDict `Person` can only be subscripted with string literal keys, got key of type `str`"
|
||||
# error: [invalid-key] "TypedDict `Person` can only be subscripted with a string literal key, got key of type `str`"
|
||||
reveal_type(person[str_key]) # revealed: Unknown
|
||||
|
||||
# No error here:
|
||||
|
||||
Reference in New Issue
Block a user