mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
red_knot_python_semantic: replace one use of "old" secondary diagnostic messages
This is the first use of the new `lint()` reporter. I somewhat skipped a step here and also modified the actual diagnostic message itself. The snapshots should tell the story. We couldn't do this before because we had no way of differentiating between "message for the diagnostic as a whole" and "message for a specific code annotation." Now we can, so we can write more precise messages based on the assumption that users are also seeing the code snippet. The downside here is that the actual message text can become quite vague in the absence of the code snippet. This occurs, for example, with concise diagnostic formatting. It's unclear if we should do anything about it. I don't really see a way to make it better that doesn't involve creating diagnostics with messages for each mode, which I think would be a major PITA. The upside is that this code gets a bit simpler, and we very specifically avoid doing extra work if this specific lint is disabled.
This commit is contained in:
parent
ba408f4231
commit
7e2eb591bc
31 changed files with 151 additions and 142 deletions
|
@ -12,7 +12,7 @@ X = GenericAlias(type, ())
|
|||
A = NewType("A", int)
|
||||
# TODO: typeshed for `typing.GenericAlias` uses `type` for the first argument. `NewType` should be special-cased
|
||||
# to be compatible with `type`
|
||||
# error: [invalid-argument-type] "Object of type `NewType` cannot be assigned to parameter 2 (`origin`) of function `__new__`; expected type `type`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `type`, found `NewType`"
|
||||
B = GenericAlias(A, ())
|
||||
|
||||
def _(
|
||||
|
|
|
@ -9,8 +9,8 @@ def _(c: Callable[[], int]):
|
|||
def _(c: Callable[[int, str], int]):
|
||||
reveal_type(c(1, "a")) # revealed: int
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `Literal["a"]` cannot be assigned to parameter 1; expected type `int`"
|
||||
# error: [invalid-argument-type] "Object of type `Literal[1]` cannot be assigned to parameter 2; expected type `str`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["a"]`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `str`, found `Literal[1]`"
|
||||
reveal_type(c("a", 1)) # revealed: int
|
||||
```
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ class C:
|
|||
|
||||
c = C()
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal["foo"]` cannot be assigned to parameter 2 (`x`) of bound method `__call__`; expected type `int`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["foo"]`"
|
||||
reveal_type(c("foo")) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -99,7 +99,7 @@ class C:
|
|||
|
||||
c = C()
|
||||
|
||||
# error: 13 [invalid-argument-type] "Object of type `C` cannot be assigned to parameter 1 (`self`) of bound method `__call__`; expected type `int`"
|
||||
# error: 13 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `C`"
|
||||
reveal_type(c()) # revealed: int
|
||||
```
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ def _(flag: bool) -> None:
|
|||
def __new__(cls, x: int, y: int = 1): ...
|
||||
|
||||
reveal_type(Foo(1)) # revealed: Foo
|
||||
# error: [invalid-argument-type] "Object of type `Literal["1"]` cannot be assigned to parameter 2 (`x`) of function `__new__`; expected type `int`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["1"]`"
|
||||
reveal_type(Foo("1")) # revealed: Foo
|
||||
# error: [missing-argument] "No argument provided for required parameter `x` of function `__new__`"
|
||||
reveal_type(Foo()) # revealed: Foo
|
||||
|
@ -210,7 +210,7 @@ def _(flag: bool) -> None:
|
|||
def __init__(self, x: int, y: int = 1): ...
|
||||
|
||||
reveal_type(Foo(1)) # revealed: Foo
|
||||
# error: [invalid-argument-type] "Object of type `Literal["1"]` cannot be assigned to parameter 2 (`x`) of bound method `__init__`; expected type `int`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["1"]`"
|
||||
reveal_type(Foo("1")) # revealed: Foo
|
||||
# error: [missing-argument] "No argument provided for required parameter `x` of bound method `__init__`"
|
||||
reveal_type(Foo()) # revealed: Foo
|
||||
|
|
|
@ -72,7 +72,7 @@ def _(flag: bool):
|
|||
def f(x: int) -> int:
|
||||
return 1
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal["foo"]` cannot be assigned to parameter 1 (`x`) of function `f`; expected type `int`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["foo"]`"
|
||||
reveal_type(f("foo")) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -82,7 +82,7 @@ reveal_type(f("foo")) # revealed: int
|
|||
def f(x: int, /) -> int:
|
||||
return 1
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal["foo"]` cannot be assigned to parameter 1 (`x`) of function `f`; expected type `int`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["foo"]`"
|
||||
reveal_type(f("foo")) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -92,7 +92,7 @@ reveal_type(f("foo")) # revealed: int
|
|||
def f(*args: int) -> int:
|
||||
return 1
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal["foo"]` cannot be assigned to parameter `*args` of function `f`; expected type `int`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["foo"]`"
|
||||
reveal_type(f("foo")) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -102,7 +102,7 @@ reveal_type(f("foo")) # revealed: int
|
|||
def f(x: int) -> int:
|
||||
return 1
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal["foo"]` cannot be assigned to parameter `x` of function `f`; expected type `int`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["foo"]`"
|
||||
reveal_type(f(x="foo")) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -112,7 +112,7 @@ reveal_type(f(x="foo")) # revealed: int
|
|||
def f(*, x: int) -> int:
|
||||
return 1
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal["foo"]` cannot be assigned to parameter `x` of function `f`; expected type `int`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["foo"]`"
|
||||
reveal_type(f(x="foo")) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -122,7 +122,7 @@ reveal_type(f(x="foo")) # revealed: int
|
|||
def f(**kwargs: int) -> int:
|
||||
return 1
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal["foo"]` cannot be assigned to parameter `**kwargs` of function `f`; expected type `int`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["foo"]`"
|
||||
reveal_type(f(x="foo")) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -132,8 +132,8 @@ reveal_type(f(x="foo")) # revealed: int
|
|||
def f(x: int = 1, y: str = "foo") -> int:
|
||||
return 1
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal[2]` cannot be assigned to parameter `y` of function `f`; expected type `str`"
|
||||
# error: 20 [invalid-argument-type] "Object of type `Literal["bar"]` cannot be assigned to parameter `x` of function `f`; expected type `int`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `str`, found `Literal[2]`"
|
||||
# error: 20 [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["bar"]`"
|
||||
reveal_type(f(y=2, x="bar")) # revealed: int
|
||||
```
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ inspect.getattr_static()
|
|||
# error: [missing-argument] "No argument provided for required parameter `attr`"
|
||||
inspect.getattr_static(C())
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `Literal[1]` cannot be assigned to parameter 2 (`attr`) of function `getattr_static`; expected type `str`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `str`, found `Literal[1]`"
|
||||
inspect.getattr_static(C(), 1)
|
||||
|
||||
# error: [too-many-positional-arguments] "Too many positional arguments to function `getattr_static`: expected 3, got 4"
|
||||
|
|
|
@ -24,7 +24,7 @@ to the valid order:
|
|||
def f(**kw: int, x: str) -> int:
|
||||
return 1
|
||||
|
||||
# error: 15 [invalid-argument-type] "Object of type `Literal[1]` cannot be assigned to parameter 1 (`x`) of function `f`; expected type `str`"
|
||||
# error: 15 [invalid-argument-type] "Argument to this function is incorrect: Expected `str`, found `Literal[1]`"
|
||||
reveal_type(f(1)) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -38,7 +38,7 @@ def f(x: int = 1, y: str) -> int:
|
|||
return 1
|
||||
|
||||
reveal_type(f(y="foo")) # revealed: int
|
||||
# error: [invalid-argument-type] "Object of type `Literal["foo"]` cannot be assigned to parameter 1 (`x`) of function `f`; expected type `int`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["foo"]`"
|
||||
# error: [missing-argument] "No argument provided for required parameter `y` of function `f`"
|
||||
reveal_type(f("foo")) # revealed: int
|
||||
```
|
||||
|
|
|
@ -350,7 +350,7 @@ class D:
|
|||
# This function is wrongly annotated, it should be `type[D]` instead of `D`
|
||||
pass
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `Literal[D]` cannot be assigned to parameter 1 (`cls`) of bound method `f`; expected type `D`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `D`, found `Literal[D]`"
|
||||
D.f()
|
||||
```
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class C:
|
|||
def _(subclass_of_c: type[C]):
|
||||
reveal_type(subclass_of_c(1)) # revealed: C
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `Literal["a"]` cannot be assigned to parameter 2 (`x`) of bound method `__init__`; expected type `int`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["a"]`"
|
||||
reveal_type(subclass_of_c("a")) # revealed: C
|
||||
# error: [missing-argument] "No argument provided for required parameter `x` of bound method `__init__`"
|
||||
reveal_type(subclass_of_c()) # revealed: C
|
||||
|
|
|
@ -94,7 +94,7 @@ def _(flag: bool):
|
|||
else:
|
||||
f = f2
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `Literal[3]` cannot be assigned to parameter 1 (`a`) of function `f2`; expected type `str`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `str`, found `Literal[3]`"
|
||||
x = f(3)
|
||||
reveal_type(x) # revealed: int | str
|
||||
```
|
||||
|
|
|
@ -207,7 +207,7 @@ first argument:
|
|||
def wrong_signature(f: int) -> str:
|
||||
return "a"
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `Literal[f]` cannot be assigned to parameter 1 (`f`) of function `wrong_signature`; expected type `int`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal[f]`"
|
||||
@wrong_signature
|
||||
def f(x): ...
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ def f(w: Wrapper) -> None:
|
|||
v: int | None = w.value
|
||||
|
||||
# This function call is incorrect, because `w.value` could be `None`. We therefore emit the following
|
||||
# error: "`Unknown | None` cannot be assigned to parameter 1 (`i`) of function `accepts_int`; expected type `int`"
|
||||
# error: "Argument to this function is incorrect: Expected `int`, found `Unknown | None`"
|
||||
c = accepts_int(w.value)
|
||||
```
|
||||
|
||||
|
|
|
@ -81,10 +81,10 @@ class IntSubclass(int): ...
|
|||
reveal_type(Bounded[int]()) # revealed: Bounded[int]
|
||||
reveal_type(Bounded[IntSubclass]()) # revealed: Bounded[IntSubclass]
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `str` cannot be assigned to parameter 1 (`T`) of class `Bounded`; expected type `int`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `str`"
|
||||
reveal_type(Bounded[str]()) # revealed: Unknown
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `int | str` cannot be assigned to parameter 1 (`T`) of class `Bounded`; expected type `int`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `int | str`"
|
||||
reveal_type(Bounded[int | str]()) # revealed: Unknown
|
||||
|
||||
reveal_type(BoundedByUnion[int]()) # revealed: BoundedByUnion[int]
|
||||
|
@ -110,7 +110,7 @@ reveal_type(Constrained[str]()) # revealed: Constrained[str]
|
|||
# TODO: revealed: Unknown
|
||||
reveal_type(Constrained[int | str]()) # revealed: Constrained[int | str]
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `object` cannot be assigned to parameter 1 (`T`) of class `Constrained`; expected type `int | str`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int | str`, found `object`"
|
||||
reveal_type(Constrained[object]()) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ class C[T]:
|
|||
c: C[int] = C[int]()
|
||||
c.m1(1)
|
||||
c.m2(1)
|
||||
# error: [invalid-argument-type] "Object of type `Literal["string"]` cannot be assigned to parameter 2 (`x`) of bound method `m2`; expected type `int`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal["string"]`"
|
||||
c.m2("string")
|
||||
```
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ class C:
|
|||
@property
|
||||
def attr(self) -> int:
|
||||
return 1
|
||||
# error: [invalid-argument-type] "Object of type `Literal[attr]` cannot be assigned to parameter 2 (`fset`) of bound method `setter`; expected type `(Any, Any, /) -> None`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `(Any, Any, /) -> None`, found `Literal[attr]`"
|
||||
@attr.setter
|
||||
def attr(self) -> None:
|
||||
pass
|
||||
|
@ -156,7 +156,7 @@ class C:
|
|||
|
||||
```py
|
||||
class C:
|
||||
# error: [invalid-argument-type] "Object of type `Literal[attr]` cannot be assigned to parameter 1 (`fget`) of class `property`; expected type `((Any, /) -> Any) | None`"
|
||||
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `((Any, /) -> Any) | None`, found `Literal[attr]`"
|
||||
@property
|
||||
def attr(self, x: int) -> int:
|
||||
return 1
|
||||
|
|
|
@ -21,19 +21,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:4:5
|
||||
|
|
||||
2 | return x * x
|
||||
3 |
|
||||
4 | foo("hello") # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter 1 (`x`) of function `foo`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:9
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^ ------ Parameter declared here
|
||||
2 | return x * x
|
||||
|
|
||||
|
||||
|
|
|
@ -23,19 +23,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:6:10
|
||||
|
|
||||
5 | c = C()
|
||||
6 | c.square("hello") # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter 2 (`x`) of bound method `square`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:2:22
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:2:9
|
||||
|
|
||||
1 | class C:
|
||||
2 | def square(self, x: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^^^^ ------ Parameter declared here
|
||||
3 | return x * x
|
||||
|
|
||||
|
||||
|
|
|
@ -27,19 +27,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:3:13
|
||||
|
|
||||
1 | import package
|
||||
2 |
|
||||
3 | package.foo("hello") # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter 1 (`x`) of function `foo`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/package.py:1:9
|
||||
info: Function defined here
|
||||
--> /src/package.py:1:5
|
||||
|
|
||||
1 | def foo(x: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^ ------ Parameter declared here
|
||||
2 | return x * x
|
||||
|
|
||||
|
||||
|
|
|
@ -22,22 +22,22 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:2:9
|
||||
|
|
||||
1 | def bar():
|
||||
2 | foo("hello") # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter 1 (`x`) of function `foo`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
3 |
|
||||
4 | def foo(x: int) -> int:
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:4:9
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:4:5
|
||||
|
|
||||
2 | foo("hello") # error: [invalid-argument-type]
|
||||
3 |
|
||||
4 | def foo(x: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^ ------ Parameter declared here
|
||||
5 | return x * x
|
||||
|
|
||||
|
||||
|
|
|
@ -21,19 +21,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:4:8
|
||||
|
|
||||
2 | return x * y * z
|
||||
3 |
|
||||
4 | foo(1, "hello", 3) # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter 2 (`y`) of function `foo`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:17
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int, y: int, z: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^ ------ Parameter declared here
|
||||
2 | return x * y * z
|
||||
|
|
||||
|
||||
|
|
|
@ -25,21 +25,22 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:8:8
|
||||
|
|
||||
6 | return x * y * z
|
||||
7 |
|
||||
8 | foo(1, "hello", 3) # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter 2 (`y`) of function `foo`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:3:5
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(
|
||||
| ^^^
|
||||
2 | x: int,
|
||||
3 | y: int,
|
||||
| ------ parameter declared in function definition here
|
||||
| ------ Parameter declared here
|
||||
4 | z: int,
|
||||
5 | ) -> int:
|
||||
|
|
||||
|
|
|
@ -24,57 +24,57 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:7:5
|
||||
|
|
||||
5 | # error: [invalid-argument-type]
|
||||
6 | # error: [invalid-argument-type]
|
||||
7 | foo("a", "b", "c")
|
||||
| ^^^ Object of type `Literal["a"]` cannot be assigned to parameter 1 (`x`) of function `foo`; expected type `int`
|
||||
| ^^^ Expected `int`, found `Literal["a"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:9
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int, y: int, z: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^ ------ Parameter declared here
|
||||
2 | return x * y * z
|
||||
|
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:7:10
|
||||
|
|
||||
5 | # error: [invalid-argument-type]
|
||||
6 | # error: [invalid-argument-type]
|
||||
7 | foo("a", "b", "c")
|
||||
| ^^^ Object of type `Literal["b"]` cannot be assigned to parameter 2 (`y`) of function `foo`; expected type `int`
|
||||
| ^^^ Expected `int`, found `Literal["b"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:17
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int, y: int, z: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^ ------ Parameter declared here
|
||||
2 | return x * y * z
|
||||
|
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:7:15
|
||||
|
|
||||
5 | # error: [invalid-argument-type]
|
||||
6 | # error: [invalid-argument-type]
|
||||
7 | foo("a", "b", "c")
|
||||
| ^^^ Object of type `Literal["c"]` cannot be assigned to parameter 3 (`z`) of function `foo`; expected type `int`
|
||||
| ^^^ Expected `int`, found `Literal["c"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:25
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int, y: int, z: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^ ------ Parameter declared here
|
||||
2 | return x * y * z
|
||||
|
|
||||
|
||||
|
|
|
@ -20,21 +20,23 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:3:12
|
||||
|
|
||||
1 | import json
|
||||
2 |
|
||||
3 | json.loads(5) # error: [invalid-argument-type]
|
||||
| ^ Object of type `Literal[5]` cannot be assigned to parameter 1 (`s`) of function `loads`; expected type `str | bytes | bytearray`
|
||||
| ^ Expected `str | bytes | bytearray`, found `Literal[5]`
|
||||
|
|
||||
info
|
||||
--> stdlib/json/__init__.pyi:40:5
|
||||
info: Function defined here
|
||||
--> stdlib/json/__init__.pyi:39:5
|
||||
|
|
||||
37 | **kwds: Any,
|
||||
38 | ) -> None: ...
|
||||
39 | def loads(
|
||||
| ^^^^^
|
||||
40 | s: str | bytes | bytearray,
|
||||
| -------------------------- parameter declared in function definition here
|
||||
| -------------------------- Parameter declared here
|
||||
41 | *,
|
||||
42 | cls: type[JSONDecoder] | None = None,
|
||||
|
|
||||
|
|
|
@ -21,19 +21,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:4:11
|
||||
|
|
||||
2 | return x * y * z
|
||||
3 |
|
||||
4 | foo(1, 2, z="hello") # error: [invalid-argument-type]
|
||||
| ^^^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter `z` of function `foo`; expected type `int`
|
||||
| ^^^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:28
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int, y: int, *, z: int = 0) -> int:
|
||||
| ---------- parameter declared in function definition here
|
||||
| ^^^ ---------- Parameter declared here
|
||||
2 | return x * y * z
|
||||
|
|
||||
|
||||
|
|
|
@ -21,19 +21,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:4:11
|
||||
|
|
||||
2 | return x * y * z
|
||||
3 |
|
||||
4 | foo(1, 2, z="hello") # error: [invalid-argument-type]
|
||||
| ^^^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter `z` of function `foo`; expected type `int`
|
||||
| ^^^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:31
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int, /, y: int, *, z: int = 0) -> int:
|
||||
| ---------- parameter declared in function definition here
|
||||
| ^^^ ---------- Parameter declared here
|
||||
2 | return x * y * z
|
||||
|
|
||||
|
||||
|
|
|
@ -21,19 +21,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:4:11
|
||||
|
|
||||
2 | return x * y * z
|
||||
3 |
|
||||
4 | foo(1, 2, "hello") # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter 3 (`z`) of function `foo`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:25
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int, y: int, z: int = 0) -> int:
|
||||
| ---------- parameter declared in function definition here
|
||||
| ^^^ ---------- Parameter declared here
|
||||
2 | return x * y * z
|
||||
|
|
||||
|
||||
|
|
|
@ -21,19 +21,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:4:8
|
||||
|
|
||||
2 | return x * y * z
|
||||
3 |
|
||||
4 | foo(1, "hello", 3) # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter 2 (`y`) of function `foo`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:17
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(x: int, y: int, z: int, /) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^ ------ Parameter declared here
|
||||
2 | return x * y * z
|
||||
|
|
||||
|
||||
|
|
|
@ -23,19 +23,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:6:3
|
||||
|
|
||||
5 | c = C()
|
||||
6 | c("wrong") # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["wrong"]` cannot be assigned to parameter 2 (`x`) of bound method `__call__`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["wrong"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:2:24
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:2:9
|
||||
|
|
||||
1 | class C:
|
||||
2 | def __call__(self, x: int) -> int:
|
||||
| ------ parameter declared in function definition here
|
||||
| ^^^^^^^^ ------ Parameter declared here
|
||||
3 | return 1
|
||||
|
|
||||
|
||||
|
|
|
@ -21,19 +21,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:4:14
|
||||
|
|
||||
2 | return len(numbers)
|
||||
3 |
|
||||
4 | foo(1, 2, 3, "hello", 5) # error: [invalid-argument-type]
|
||||
| ^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter `*numbers` of function `foo`; expected type `int`
|
||||
| ^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:9
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(*numbers: int) -> int:
|
||||
| ------------- parameter declared in function definition here
|
||||
| ^^^ ------------- Parameter declared here
|
||||
2 | return len(numbers)
|
||||
|
|
||||
|
||||
|
|
|
@ -21,19 +21,19 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/invali
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-argument-type
|
||||
error: lint:invalid-argument-type: Argument to this function is incorrect
|
||||
--> /src/mdtest_snippet.py:4:20
|
||||
|
|
||||
2 | return len(numbers)
|
||||
3 |
|
||||
4 | foo(a=1, b=2, c=3, d="hello", e=5) # error: [invalid-argument-type]
|
||||
| ^^^^^^^^^ Object of type `Literal["hello"]` cannot be assigned to parameter `**numbers` of function `foo`; expected type `int`
|
||||
| ^^^^^^^^^ Expected `int`, found `Literal["hello"]`
|
||||
|
|
||||
info
|
||||
--> /src/mdtest_snippet.py:1:9
|
||||
info: Function defined here
|
||||
--> /src/mdtest_snippet.py:1:5
|
||||
|
|
||||
1 | def foo(**numbers: int) -> int:
|
||||
| -------------- parameter declared in function definition here
|
||||
| ^^^ -------------- Parameter declared here
|
||||
2 | return len(numbers)
|
||||
|
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::types::{
|
|||
todo_type, BoundMethodType, FunctionDecorators, KnownClass, KnownFunction, KnownInstanceType,
|
||||
MethodWrapperKind, PropertyInstanceType, UnionType, WrapperDescriptorKind,
|
||||
};
|
||||
use ruff_db::diagnostic::{OldSecondaryDiagnosticMessage, Span};
|
||||
use ruff_db::diagnostic::{Annotation, Severity, Span, SubDiagnostic};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -1183,15 +1183,23 @@ pub(crate) enum BindingError<'db> {
|
|||
}
|
||||
|
||||
impl<'db> BindingError<'db> {
|
||||
/// Returns a tuple of two spans. The first is
|
||||
/// the span for the identifier of the function
|
||||
/// definition for `callable_ty`. The second is
|
||||
/// the span for the parameter in the function
|
||||
/// definition for `callable_ty`.
|
||||
///
|
||||
/// If there are no meaningful spans, then this
|
||||
/// returns `None`.
|
||||
fn parameter_span_from_index(
|
||||
db: &'db dyn Db,
|
||||
callable_ty: Type<'db>,
|
||||
parameter_index: usize,
|
||||
) -> Option<Span> {
|
||||
) -> Option<(Span, Span)> {
|
||||
match callable_ty {
|
||||
Type::FunctionLiteral(function) => {
|
||||
let function_scope = function.body_scope(db);
|
||||
let mut span = Span::from(function_scope.file(db));
|
||||
let span = Span::from(function_scope.file(db));
|
||||
let node = function_scope.node(db);
|
||||
if let Some(func_def) = node.as_function() {
|
||||
let range = func_def
|
||||
|
@ -1200,8 +1208,9 @@ impl<'db> BindingError<'db> {
|
|||
.nth(parameter_index)
|
||||
.map(|param| param.range())
|
||||
.unwrap_or(func_def.parameters.range);
|
||||
span = span.with_range(range);
|
||||
Some(span)
|
||||
let name_span = span.clone().with_range(func_def.name.range);
|
||||
let parameter_span = span.with_range(range);
|
||||
Some((name_span, parameter_span))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1229,32 +1238,29 @@ impl<'db> BindingError<'db> {
|
|||
expected_ty,
|
||||
provided_ty,
|
||||
} => {
|
||||
let mut messages = vec![];
|
||||
if let Some(span) =
|
||||
Self::parameter_span_from_index(context.db(), callable_ty, parameter.index)
|
||||
{
|
||||
messages.push(OldSecondaryDiagnosticMessage::new(
|
||||
span,
|
||||
"parameter declared in function definition here",
|
||||
));
|
||||
}
|
||||
let Some(builder) = context.lint(&INVALID_ARGUMENT_TYPE) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let provided_ty_display = provided_ty.display(context.db());
|
||||
let expected_ty_display = expected_ty.display(context.db());
|
||||
context.report_lint_with_secondary_messages(
|
||||
&INVALID_ARGUMENT_TYPE,
|
||||
Self::get_node(node, *argument_index),
|
||||
format_args!(
|
||||
"Object of type `{provided_ty_display}` cannot be assigned to \
|
||||
parameter {parameter}{}; expected type `{expected_ty_display}`",
|
||||
if let Some(CallableDescription { kind, name }) = callable_description {
|
||||
format!(" of {kind} `{name}`")
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
),
|
||||
&messages,
|
||||
);
|
||||
let mut reporter = builder.build("Argument to this function is incorrect");
|
||||
|
||||
let diag = reporter.diagnostic();
|
||||
let span = context.span(Self::get_node(node, *argument_index));
|
||||
diag.annotate(Annotation::primary(span).message(format_args!(
|
||||
"Expected `{expected_ty_display}`, found `{provided_ty_display}`"
|
||||
)));
|
||||
if let Some((name_span, parameter_span)) =
|
||||
Self::parameter_span_from_index(context.db(), callable_ty, parameter.index)
|
||||
{
|
||||
let mut sub = SubDiagnostic::new(Severity::Info, "Function defined here");
|
||||
sub.annotate(Annotation::primary(name_span));
|
||||
sub.annotate(
|
||||
Annotation::secondary(parameter_span).message("Parameter declared here"),
|
||||
);
|
||||
diag.sub(sub);
|
||||
}
|
||||
}
|
||||
|
||||
Self::TooManyPositionalArguments {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue