mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +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