mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
[ty] Add hints to invalid-type-form
for common mistakes (#18543)
Co-authored-by: Ben Bar-Or <ben.baror@ridewithvia.com> Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
This commit is contained in:
parent
301b9f4135
commit
1dc8f8f903
7 changed files with 462 additions and 74 deletions
|
@ -47,7 +47,7 @@ def _(flag: bool):
|
|||
def _(x: Annotated | bool):
|
||||
reveal_type(x) # revealed: Unknown | bool
|
||||
|
||||
# error: [invalid-type-form]
|
||||
# error: [invalid-type-form] "Special form `typing.Annotated` expected at least 2 arguments (one type and at least one metadata element)"
|
||||
def _(x: Annotated[()]):
|
||||
reveal_type(x) # revealed: Unknown
|
||||
|
||||
|
|
|
@ -116,6 +116,21 @@ def _(c: Callable[
|
|||
reveal_type(c) # revealed: (...) -> Unknown
|
||||
```
|
||||
|
||||
### Tuple as the second argument
|
||||
|
||||
```py
|
||||
from typing import Callable
|
||||
|
||||
# fmt: off
|
||||
|
||||
def _(c: Callable[
|
||||
int, # error: [invalid-type-form] "The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`"
|
||||
(str, ) # error: [invalid-type-form] "Tuple literals are not allowed in this context in a type expression"
|
||||
]
|
||||
):
|
||||
reveal_type(c) # revealed: (...) -> Unknown
|
||||
```
|
||||
|
||||
### List as both arguments
|
||||
|
||||
```py
|
||||
|
|
|
@ -95,6 +95,11 @@ async def outer(): # avoid unrelated syntax errors on yield, yield from, and aw
|
|||
|
||||
## Invalid Collection based AST nodes
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.12"
|
||||
```
|
||||
|
||||
```py
|
||||
def _(
|
||||
a: {1: 2}, # error: [invalid-type-form] "Dict literals are not allowed in type expressions"
|
||||
|
@ -103,7 +108,11 @@ def _(
|
|||
d: [k for k in [1, 2]], # error: [invalid-type-form] "List comprehensions are not allowed in type expressions"
|
||||
e: {k for k in [1, 2]}, # error: [invalid-type-form] "Set comprehensions are not allowed in type expressions"
|
||||
f: (k for k in [1, 2]), # error: [invalid-type-form] "Generator expressions are not allowed in type expressions"
|
||||
g: [int, str], # error: [invalid-type-form] "List literals are not allowed in this context in a type expression"
|
||||
# error: [invalid-type-form] "List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?"
|
||||
g: [int, str],
|
||||
# error: [invalid-type-form] "Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?"
|
||||
h: (int, str),
|
||||
i: (), # error: [invalid-type-form] "Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[()]`?"
|
||||
):
|
||||
reveal_type(a) # revealed: Unknown
|
||||
reveal_type(b) # revealed: Unknown
|
||||
|
@ -112,6 +121,17 @@ def _(
|
|||
reveal_type(e) # revealed: Unknown
|
||||
reveal_type(f) # revealed: Unknown
|
||||
reveal_type(g) # revealed: Unknown
|
||||
reveal_type(h) # revealed: Unknown
|
||||
reveal_type(i) # revealed: Unknown
|
||||
|
||||
# error: [invalid-type-form] "List literals are not allowed in this context in a type expression: Did you mean `list[int]`?"
|
||||
class name_0[name_2: [int]]:
|
||||
pass
|
||||
|
||||
# error: [invalid-type-form] "List literals are not allowed in this context in a type expression"
|
||||
# error: [invalid-type-form] "Dict literals are not allowed in type expressions"
|
||||
class name_4[name_1: [{}]]:
|
||||
pass
|
||||
```
|
||||
|
||||
## Diagnostics for common errors
|
||||
|
@ -145,3 +165,42 @@ from PIL import Image
|
|||
|
||||
def g(x: Image): ... # error: [invalid-type-form]
|
||||
```
|
||||
|
||||
### List-literal used when you meant to use a list or tuple
|
||||
|
||||
```py
|
||||
def _(
|
||||
x: [int], # error: [invalid-type-form]
|
||||
) -> [int]: # error: [invalid-type-form]
|
||||
return x
|
||||
```
|
||||
|
||||
```py
|
||||
def _(
|
||||
x: [int, str], # error: [invalid-type-form]
|
||||
) -> [int, str]: # error: [invalid-type-form]
|
||||
return x
|
||||
```
|
||||
|
||||
### Tuple-literal used when you meant to use a tuple
|
||||
|
||||
```py
|
||||
def _(
|
||||
x: (), # error: [invalid-type-form]
|
||||
) -> (): # error: [invalid-type-form]
|
||||
return x
|
||||
```
|
||||
|
||||
```py
|
||||
def _(
|
||||
x: (int,), # error: [invalid-type-form]
|
||||
) -> (int,): # error: [invalid-type-form]
|
||||
return x
|
||||
```
|
||||
|
||||
```py
|
||||
def _(
|
||||
x: (int, str), # error: [invalid-type-form]
|
||||
) -> (int, str): # error: [invalid-type-form]
|
||||
return x
|
||||
```
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: invalid.md - Tests for invalid types in type expressions - Diagnostics for common errors - List-literal used when you meant to use a list or tuple
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/annotations/invalid.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | def _(
|
||||
2 | x: [int], # error: [invalid-type-form]
|
||||
3 | ) -> [int]: # error: [invalid-type-form]
|
||||
4 | return x
|
||||
5 | def _(
|
||||
6 | x: [int, str], # error: [invalid-type-form]
|
||||
7 | ) -> [int, str]: # error: [invalid-type-form]
|
||||
8 | return x
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error[invalid-type-form]: List literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:2:8
|
||||
|
|
||||
1 | def _(
|
||||
2 | x: [int], # error: [invalid-type-form]
|
||||
| ^^^^^ Did you mean `list[int]`?
|
||||
3 | ) -> [int]: # error: [invalid-type-form]
|
||||
4 | return x
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-form]: List literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:3:6
|
||||
|
|
||||
1 | def _(
|
||||
2 | x: [int], # error: [invalid-type-form]
|
||||
3 | ) -> [int]: # error: [invalid-type-form]
|
||||
| ^^^^^ Did you mean `list[int]`?
|
||||
4 | return x
|
||||
5 | def _(
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-form]: List literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:6:8
|
||||
|
|
||||
4 | return x
|
||||
5 | def _(
|
||||
6 | x: [int, str], # error: [invalid-type-form]
|
||||
| ^^^^^^^^^^ Did you mean `tuple[int, str]`?
|
||||
7 | ) -> [int, str]: # error: [invalid-type-form]
|
||||
8 | return x
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-form]: List literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:7:6
|
||||
|
|
||||
5 | def _(
|
||||
6 | x: [int, str], # error: [invalid-type-form]
|
||||
7 | ) -> [int, str]: # error: [invalid-type-form]
|
||||
| ^^^^^^^^^^ Did you mean `tuple[int, str]`?
|
||||
8 | return x
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
|
@ -0,0 +1,129 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: invalid.md - Tests for invalid types in type expressions - Diagnostics for common errors - Tuple-literal used when you meant to use a tuple
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/annotations/invalid.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | def _(
|
||||
2 | x: (), # error: [invalid-type-form]
|
||||
3 | ) -> (): # error: [invalid-type-form]
|
||||
4 | return x
|
||||
5 | def _(
|
||||
6 | x: (int,), # error: [invalid-type-form]
|
||||
7 | ) -> (int,): # error: [invalid-type-form]
|
||||
8 | return x
|
||||
9 | def _(
|
||||
10 | x: (int, str), # error: [invalid-type-form]
|
||||
11 | ) -> (int, str): # error: [invalid-type-form]
|
||||
12 | return x
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error[invalid-type-form]: Tuple literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:2:8
|
||||
|
|
||||
1 | def _(
|
||||
2 | x: (), # error: [invalid-type-form]
|
||||
| ^^ Did you mean `tuple[()]`?
|
||||
3 | ) -> (): # error: [invalid-type-form]
|
||||
4 | return x
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-form]: Tuple literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:3:6
|
||||
|
|
||||
1 | def _(
|
||||
2 | x: (), # error: [invalid-type-form]
|
||||
3 | ) -> (): # error: [invalid-type-form]
|
||||
| ^^ Did you mean `tuple[()]`?
|
||||
4 | return x
|
||||
5 | def _(
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-form]: Tuple literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:6:8
|
||||
|
|
||||
4 | return x
|
||||
5 | def _(
|
||||
6 | x: (int,), # error: [invalid-type-form]
|
||||
| ^^^^^^ Did you mean `tuple[int]`?
|
||||
7 | ) -> (int,): # error: [invalid-type-form]
|
||||
8 | return x
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-form]: Tuple literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:7:6
|
||||
|
|
||||
5 | def _(
|
||||
6 | x: (int,), # error: [invalid-type-form]
|
||||
7 | ) -> (int,): # error: [invalid-type-form]
|
||||
| ^^^^^^ Did you mean `tuple[int]`?
|
||||
8 | return x
|
||||
9 | def _(
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-form]: Tuple literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:10:8
|
||||
|
|
||||
8 | return x
|
||||
9 | def _(
|
||||
10 | x: (int, str), # error: [invalid-type-form]
|
||||
| ^^^^^^^^^^ Did you mean `tuple[int, str]`?
|
||||
11 | ) -> (int, str): # error: [invalid-type-form]
|
||||
12 | return x
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-form]: Tuple literals are not allowed in this context in a type expression
|
||||
--> src/mdtest_snippet.py:11:6
|
||||
|
|
||||
9 | def _(
|
||||
10 | x: (int, str), # error: [invalid-type-form]
|
||||
11 | ) -> (int, str): # error: [invalid-type-form]
|
||||
| ^^^^^^^^^^ Did you mean `tuple[int, str]`?
|
||||
12 | return x
|
||||
|
|
||||
info: See the following page for a reference on valid type expressions:
|
||||
info: https://typing.python.org/en/latest/spec/annotations.html#type-and-annotation-expressions
|
||||
info: rule `invalid-type-form` is enabled by default
|
||||
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue