mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 04:19:18 +00:00
ty_python_semantic: add snapshot tests for existing union function type diagnostics
This is just capturing the status quo so that we can better see the changes. I took these tests from the (now defunct) PR #17959.
This commit is contained in:
parent
e9da1750a1
commit
90272ad85a
5 changed files with 345 additions and 0 deletions
|
@ -0,0 +1,121 @@
|
|||
# Calling a union of function types
|
||||
|
||||
<!-- snapshot-diagnostics -->
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.12"
|
||||
```
|
||||
|
||||
## A smaller scale example
|
||||
|
||||
```py
|
||||
def f1() -> int:
|
||||
return 0
|
||||
|
||||
def f2(name: str) -> int:
|
||||
return 0
|
||||
|
||||
def _(flag: bool):
|
||||
if flag:
|
||||
f = f1
|
||||
else:
|
||||
f = f2
|
||||
# error: [too-many-positional-arguments]
|
||||
x = f(3)
|
||||
```
|
||||
|
||||
## Multiple variants but only one is invalid
|
||||
|
||||
This test in particular demonstrates some of the smarts of this diagnostic. Namely, since only one
|
||||
variant is invalid, additional context specific to that variant is added to the diagnostic output.
|
||||
(If more than one variant is invalid, then this additional context is elided to avoid overwhelming
|
||||
the end user.)
|
||||
|
||||
```py
|
||||
def f1(a: int) -> int:
|
||||
return 0
|
||||
|
||||
def f2(name: str) -> int:
|
||||
return 0
|
||||
|
||||
def _(flag: bool):
|
||||
if flag:
|
||||
f = f1
|
||||
else:
|
||||
f = f2
|
||||
# error: [invalid-argument-type]
|
||||
x = f(3)
|
||||
```
|
||||
|
||||
## Try to cover all possible reasons
|
||||
|
||||
These tests is likely to become stale over time, but this was added when the union-specific
|
||||
diagnostic was initially created. In each test, we try to cover as much as we can. This is mostly
|
||||
just ensuring that we get test coverage for each of the possible diagnostic messages.
|
||||
|
||||
### Cover non-keyword related reasons
|
||||
|
||||
```py
|
||||
from inspect import getattr_static
|
||||
|
||||
def f1() -> int:
|
||||
return 0
|
||||
|
||||
def f2(name: str) -> int:
|
||||
return 0
|
||||
|
||||
def f3(a: int, b: int) -> int:
|
||||
return 0
|
||||
|
||||
def f4[T: str](x: T) -> int:
|
||||
return 0
|
||||
|
||||
class OverloadExample:
|
||||
def f(self, x: str) -> int:
|
||||
return 0
|
||||
|
||||
f5 = getattr_static(OverloadExample, "f").__get__
|
||||
|
||||
def _(n: int):
|
||||
class PossiblyNotCallable:
|
||||
if n == 0:
|
||||
def __call__(self) -> int:
|
||||
return 0
|
||||
|
||||
if n == 0:
|
||||
f = f1
|
||||
elif n == 1:
|
||||
f = f2
|
||||
elif n == 2:
|
||||
f = f3
|
||||
elif n == 3:
|
||||
f = f4
|
||||
elif n == 4:
|
||||
f = 5
|
||||
elif n == 5:
|
||||
f = f5
|
||||
else:
|
||||
f = PossiblyNotCallable()
|
||||
# error: [too-many-positional-arguments]
|
||||
x = f(3)
|
||||
```
|
||||
|
||||
### Cover keyword argument related reasons
|
||||
|
||||
```py
|
||||
def any(*args, **kwargs) -> int:
|
||||
return 0
|
||||
|
||||
def f1(name: str) -> int:
|
||||
return 0
|
||||
|
||||
def _(n: int):
|
||||
if n == 0:
|
||||
f = f1
|
||||
else:
|
||||
f = any
|
||||
# error: [parameter-already-assigned]
|
||||
# error: [unknown-argument]
|
||||
y = f("foo", name="bar", unknown="quux")
|
||||
```
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: union_call.md - Calling a union of function types - A smaller scale example
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/union_call.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | def f1() -> int:
|
||||
2 | return 0
|
||||
3 |
|
||||
4 | def f2(name: str) -> int:
|
||||
5 | return 0
|
||||
6 |
|
||||
7 | def _(flag: bool):
|
||||
8 | if flag:
|
||||
9 | f = f1
|
||||
10 | else:
|
||||
11 | f = f2
|
||||
12 | # error: [too-many-positional-arguments]
|
||||
13 | x = f(3)
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:too-many-positional-arguments: Too many positional arguments to function `f1`: expected 0, got 1
|
||||
--> src/mdtest_snippet.py:13:11
|
||||
|
|
||||
11 | f = f2
|
||||
12 | # error: [too-many-positional-arguments]
|
||||
13 | x = f(3)
|
||||
| ^
|
||||
|
|
||||
info: `lint:too-many-positional-arguments` is enabled by default
|
||||
|
||||
```
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: union_call.md - Calling a union of function types - Multiple variants but only one is invalid
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/union_call.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | def f1(a: int) -> int:
|
||||
2 | return 0
|
||||
3 |
|
||||
4 | def f2(name: str) -> int:
|
||||
5 | return 0
|
||||
6 |
|
||||
7 | def _(flag: bool):
|
||||
8 | if flag:
|
||||
9 | f = f1
|
||||
10 | else:
|
||||
11 | f = f2
|
||||
12 | # error: [invalid-argument-type]
|
||||
13 | x = f(3)
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> src/mdtest_snippet.py:13:11
|
||||
|
|
||||
11 | f = f2
|
||||
12 | # error: [invalid-argument-type]
|
||||
13 | x = f(3)
|
||||
| ^ Expected `str`, found `Literal[3]`
|
||||
|
|
||||
info: Function defined here
|
||||
--> src/mdtest_snippet.py:4:5
|
||||
|
|
||||
2 | return 0
|
||||
3 |
|
||||
4 | def f2(name: str) -> int:
|
||||
| ^^ --------- Parameter declared here
|
||||
5 | return 0
|
||||
|
|
||||
info: `lint:invalid-argument-type` is enabled by default
|
||||
|
||||
```
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: union_call.md - Calling a union of function types - Try to cover all possible reasons - Cover keyword argument related reasons
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/union_call.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | def any(*args, **kwargs) -> int:
|
||||
2 | return 0
|
||||
3 |
|
||||
4 | def f1(name: str) -> int:
|
||||
5 | return 0
|
||||
6 |
|
||||
7 | def _(n: int):
|
||||
8 | if n == 0:
|
||||
9 | f = f1
|
||||
10 | else:
|
||||
11 | f = any
|
||||
12 | # error: [parameter-already-assigned]
|
||||
13 | # error: [unknown-argument]
|
||||
14 | y = f("foo", name="bar", unknown="quux")
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:parameter-already-assigned: Multiple values provided for parameter `name` of function `f1`
|
||||
--> src/mdtest_snippet.py:14:18
|
||||
|
|
||||
12 | # error: [parameter-already-assigned]
|
||||
13 | # error: [unknown-argument]
|
||||
14 | y = f("foo", name="bar", unknown="quux")
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
info: `lint:parameter-already-assigned` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error: lint:unknown-argument: Argument `unknown` does not match any known parameter of function `f1`
|
||||
--> src/mdtest_snippet.py:14:30
|
||||
|
|
||||
12 | # error: [parameter-already-assigned]
|
||||
13 | # error: [unknown-argument]
|
||||
14 | y = f("foo", name="bar", unknown="quux")
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
info: `lint:unknown-argument` is enabled by default
|
||||
|
||||
```
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
source: crates/ty_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: union_call.md - Calling a union of function types - Try to cover all possible reasons - Cover non-keyword related reasons
|
||||
mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/union_call.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | from inspect import getattr_static
|
||||
2 |
|
||||
3 | def f1() -> int:
|
||||
4 | return 0
|
||||
5 |
|
||||
6 | def f2(name: str) -> int:
|
||||
7 | return 0
|
||||
8 |
|
||||
9 | def f3(a: int, b: int) -> int:
|
||||
10 | return 0
|
||||
11 |
|
||||
12 | def f4[T: str](x: T) -> int:
|
||||
13 | return 0
|
||||
14 |
|
||||
15 | class OverloadExample:
|
||||
16 | def f(self, x: str) -> int:
|
||||
17 | return 0
|
||||
18 |
|
||||
19 | f5 = getattr_static(OverloadExample, "f").__get__
|
||||
20 |
|
||||
21 | def _(n: int):
|
||||
22 | class PossiblyNotCallable:
|
||||
23 | if n == 0:
|
||||
24 | def __call__(self) -> int:
|
||||
25 | return 0
|
||||
26 |
|
||||
27 | if n == 0:
|
||||
28 | f = f1
|
||||
29 | elif n == 1:
|
||||
30 | f = f2
|
||||
31 | elif n == 2:
|
||||
32 | f = f3
|
||||
33 | elif n == 3:
|
||||
34 | f = f4
|
||||
35 | elif n == 4:
|
||||
36 | f = 5
|
||||
37 | elif n == 5:
|
||||
38 | f = f5
|
||||
39 | else:
|
||||
40 | f = PossiblyNotCallable()
|
||||
41 | # error: [too-many-positional-arguments]
|
||||
42 | x = f(3)
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:too-many-positional-arguments: Too many positional arguments to function `f1`: expected 0, got 1
|
||||
--> src/mdtest_snippet.py:42:11
|
||||
|
|
||||
40 | f = PossiblyNotCallable()
|
||||
41 | # error: [too-many-positional-arguments]
|
||||
42 | x = f(3)
|
||||
| ^
|
||||
|
|
||||
info: `lint:too-many-positional-arguments` is enabled by default
|
||||
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue