mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
[ty] Improve diagnostics for assert_type
and assert_never
(#18050)
This commit is contained in:
parent
00f672a83b
commit
5913997c72
6 changed files with 278 additions and 21 deletions
|
@ -2,6 +2,8 @@
|
|||
|
||||
## Basic functionality
|
||||
|
||||
<!-- snapshot-diagnostics -->
|
||||
|
||||
`assert_never` makes sure that the type of the argument is `Never`. If it is not, a
|
||||
`type-assertion-failure` diagnostic is emitted.
|
||||
|
||||
|
@ -58,7 +60,7 @@ def if_else_isinstance_error(obj: A | B):
|
|||
elif isinstance(obj, C):
|
||||
pass
|
||||
else:
|
||||
# error: [type-assertion-failure] "Expected type `Never`, got `B & ~A & ~C` instead"
|
||||
# error: [type-assertion-failure] "Argument does not have asserted type `Never`"
|
||||
assert_never(obj)
|
||||
|
||||
def if_else_singletons_success(obj: Literal[1, "a"] | None):
|
||||
|
@ -79,7 +81,7 @@ def if_else_singletons_error(obj: Literal[1, "a"] | None):
|
|||
elif obj is None:
|
||||
pass
|
||||
else:
|
||||
# error: [type-assertion-failure] "Expected type `Never`, got `Literal["a"]` instead"
|
||||
# error: [type-assertion-failure] "Argument does not have asserted type `Never`"
|
||||
assert_never(obj)
|
||||
|
||||
def match_singletons_success(obj: Literal[1, "a"] | None):
|
||||
|
@ -92,7 +94,7 @@ def match_singletons_success(obj: Literal[1, "a"] | None):
|
|||
pass
|
||||
case _ as obj:
|
||||
# TODO: Ideally, we would not emit an error here
|
||||
# error: [type-assertion-failure] "Expected type `Never`, got `@Todo"
|
||||
# error: [type-assertion-failure] "Argument does not have asserted type `Never`"
|
||||
assert_never(obj)
|
||||
|
||||
def match_singletons_error(obj: Literal[1, "a"] | None):
|
||||
|
@ -106,6 +108,6 @@ def match_singletons_error(obj: Literal[1, "a"] | None):
|
|||
case _ as obj:
|
||||
# TODO: We should emit an error here, but the message should
|
||||
# show the type `Literal["a"]` instead of `@Todo(…)`.
|
||||
# error: [type-assertion-failure] "Expected type `Never`, got `@Todo"
|
||||
# error: [type-assertion-failure] "Argument does not have asserted type `Never`"
|
||||
assert_never(obj)
|
||||
```
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
## Basic
|
||||
|
||||
<!-- snapshot-diagnostics -->
|
||||
|
||||
```py
|
||||
from typing_extensions import assert_type
|
||||
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: assert_never.md - `assert_never` - Basic functionality
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/directives/assert_never.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | from typing_extensions import assert_never, Never, Any
|
||||
2 | from ty_extensions import Unknown
|
||||
3 |
|
||||
4 | def _(never: Never, any_: Any, unknown: Unknown, flag: bool):
|
||||
5 | assert_never(never) # fine
|
||||
6 |
|
||||
7 | assert_never(0) # error: [type-assertion-failure]
|
||||
8 | assert_never("") # error: [type-assertion-failure]
|
||||
9 | assert_never(None) # error: [type-assertion-failure]
|
||||
10 | assert_never([]) # error: [type-assertion-failure]
|
||||
11 | assert_never({}) # error: [type-assertion-failure]
|
||||
12 | assert_never(()) # error: [type-assertion-failure]
|
||||
13 | assert_never(1 if flag else never) # error: [type-assertion-failure]
|
||||
14 |
|
||||
15 | assert_never(any_) # error: [type-assertion-failure]
|
||||
16 | assert_never(unknown) # error: [type-assertion-failure]
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:7:5
|
||||
|
|
||||
5 | assert_never(never) # fine
|
||||
6 |
|
||||
7 | assert_never(0) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^-^
|
||||
| |
|
||||
| Inferred type of argument is `Literal[0]`
|
||||
8 | assert_never("") # error: [type-assertion-failure]
|
||||
9 | assert_never(None) # error: [type-assertion-failure]
|
||||
|
|
||||
info: `Never` and `Literal[0]` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:8:5
|
||||
|
|
||||
7 | assert_never(0) # error: [type-assertion-failure]
|
||||
8 | assert_never("") # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^--^
|
||||
| |
|
||||
| Inferred type of argument is `Literal[""]`
|
||||
9 | assert_never(None) # error: [type-assertion-failure]
|
||||
10 | assert_never([]) # error: [type-assertion-failure]
|
||||
|
|
||||
info: `Never` and `Literal[""]` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:9:5
|
||||
|
|
||||
7 | assert_never(0) # error: [type-assertion-failure]
|
||||
8 | assert_never("") # error: [type-assertion-failure]
|
||||
9 | assert_never(None) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^----^
|
||||
| |
|
||||
| Inferred type of argument is `None`
|
||||
10 | assert_never([]) # error: [type-assertion-failure]
|
||||
11 | assert_never({}) # error: [type-assertion-failure]
|
||||
|
|
||||
info: `Never` and `None` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:10:5
|
||||
|
|
||||
8 | assert_never("") # error: [type-assertion-failure]
|
||||
9 | assert_never(None) # error: [type-assertion-failure]
|
||||
10 | assert_never([]) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^--^
|
||||
| |
|
||||
| Inferred type of argument is `list[Unknown]`
|
||||
11 | assert_never({}) # error: [type-assertion-failure]
|
||||
12 | assert_never(()) # error: [type-assertion-failure]
|
||||
|
|
||||
info: `Never` and `list[Unknown]` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:11:5
|
||||
|
|
||||
9 | assert_never(None) # error: [type-assertion-failure]
|
||||
10 | assert_never([]) # error: [type-assertion-failure]
|
||||
11 | assert_never({}) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^--^
|
||||
| |
|
||||
| Inferred type of argument is `dict[Unknown, Unknown]`
|
||||
12 | assert_never(()) # error: [type-assertion-failure]
|
||||
13 | assert_never(1 if flag else never) # error: [type-assertion-failure]
|
||||
|
|
||||
info: `Never` and `dict[Unknown, Unknown]` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:12:5
|
||||
|
|
||||
10 | assert_never([]) # error: [type-assertion-failure]
|
||||
11 | assert_never({}) # error: [type-assertion-failure]
|
||||
12 | assert_never(()) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^--^
|
||||
| |
|
||||
| Inferred type of argument is `tuple[()]`
|
||||
13 | assert_never(1 if flag else never) # error: [type-assertion-failure]
|
||||
|
|
||||
info: `Never` and `tuple[()]` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:13:5
|
||||
|
|
||||
11 | assert_never({}) # error: [type-assertion-failure]
|
||||
12 | assert_never(()) # error: [type-assertion-failure]
|
||||
13 | assert_never(1 if flag else never) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^--------------------^
|
||||
| |
|
||||
| Inferred type of argument is `Literal[1]`
|
||||
14 |
|
||||
15 | assert_never(any_) # error: [type-assertion-failure]
|
||||
|
|
||||
info: `Never` and `Literal[1]` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:15:5
|
||||
|
|
||||
13 | assert_never(1 if flag else never) # error: [type-assertion-failure]
|
||||
14 |
|
||||
15 | assert_never(any_) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^----^
|
||||
| |
|
||||
| Inferred type of argument is `Any`
|
||||
16 | assert_never(unknown) # error: [type-assertion-failure]
|
||||
|
|
||||
info: `Never` and `Any` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `Never`
|
||||
--> src/mdtest_snippet.py:16:5
|
||||
|
|
||||
15 | assert_never(any_) # error: [type-assertion-failure]
|
||||
16 | assert_never(unknown) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^^-------^
|
||||
| |
|
||||
| Inferred type of argument is `Unknown`
|
||||
|
|
||||
info: `Never` and `Unknown` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: assert_type.md - `assert_type` - Basic
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/directives/assert_type.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | from typing_extensions import assert_type
|
||||
2 |
|
||||
3 | def _(x: int):
|
||||
4 | assert_type(x, int) # fine
|
||||
5 | assert_type(x, str) # error: [type-assertion-failure]
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error[type-assertion-failure]: Argument does not have asserted type `str`
|
||||
--> src/mdtest_snippet.py:5:5
|
||||
|
|
||||
3 | def _(x: int):
|
||||
4 | assert_type(x, int) # fine
|
||||
5 | assert_type(x, str) # error: [type-assertion-failure]
|
||||
| ^^^^^^^^^^^^-^^^^^^
|
||||
| |
|
||||
| Inferred type of argument is `int`
|
||||
|
|
||||
info: `str` and `int` are not equivalent types
|
||||
info: rule `type-assertion-failure` is enabled by default
|
||||
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue