From 7e2eb591bc717b70475c3c7e6eedbd1b0d0aa654 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Tue, 8 Apr 2025 15:01:19 -0400 Subject: [PATCH] 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. --- .../resources/mdtest/annotations/new_types.md | 2 +- .../resources/mdtest/call/annotation.md | 4 +- .../mdtest/call/callable_instance.md | 4 +- .../resources/mdtest/call/constructor.md | 4 +- .../resources/mdtest/call/function.md | 16 ++--- .../resources/mdtest/call/getattr_static.md | 2 +- .../resources/mdtest/call/invalid_syntax.md | 4 +- .../resources/mdtest/call/methods.md | 2 +- .../resources/mdtest/call/subclass_of.md | 2 +- .../resources/mdtest/call/union.md | 2 +- .../resources/mdtest/decorators.md | 2 +- .../doc/public_type_undeclared_symbols.md | 2 +- .../resources/mdtest/generics/classes.md | 6 +- .../resources/mdtest/generics/scoping.md | 2 +- .../resources/mdtest/properties.md | 4 +- ...lid_argument_type_diagnostics_-_Basic.snap | 10 +-- ...t_type_diagnostics_-_Calls_to_methods.snap | 10 +-- ...nt_type_diagnostics_-_Different_files.snap | 10 +-- ..._diagnostics_-_Different_source_order.snap | 10 +-- ...nt_type_diagnostics_-_Many_parameters.snap | 10 +-- ...Many_parameters_across_multiple_lines.snap | 11 ++-- ...eters_with_multiple_invalid_arguments.snap | 30 ++++----- ...hose_type_is_vendored_from_`typeshed`.snap | 12 ++-- ...gument_types_-_Keyword_only_arguments.snap | 10 +-- ..._of_argument_types_-_Mix_of_arguments.snap | 10 +-- ...argument_types_-_One_keyword_argument.snap | 10 +-- ...y_of_argument_types_-_Only_positional.snap | 10 +-- ..._argument_types_-_Synthetic_arguments.snap | 10 +-- ...f_argument_types_-_Variadic_arguments.snap | 10 +-- ...nt_types_-_Variadic_keyword_arguments.snap | 10 +-- .../src/types/call/bind.rs | 62 ++++++++++--------- 31 files changed, 151 insertions(+), 142 deletions(-) diff --git a/crates/red_knot_python_semantic/resources/mdtest/annotations/new_types.md b/crates/red_knot_python_semantic/resources/mdtest/annotations/new_types.md index 825ca9b27d..0c5142ef70 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/annotations/new_types.md +++ b/crates/red_knot_python_semantic/resources/mdtest/annotations/new_types.md @@ -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 _( diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/annotation.md b/crates/red_knot_python_semantic/resources/mdtest/call/annotation.md index 1899baafe6..709ad8e1a6 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/annotation.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/annotation.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md b/crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md index 4a6b2b1ad1..9f43e7b621 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md b/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md index 763b6bd30b..56a49fc13f 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/function.md b/crates/red_knot_python_semantic/resources/mdtest/call/function.md index b4ff45cc61..10db8aaa80 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/function.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/function.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/getattr_static.md b/crates/red_knot_python_semantic/resources/mdtest/call/getattr_static.md index 390fb565f8..2bf7a52d4e 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/getattr_static.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/getattr_static.md @@ -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" diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/invalid_syntax.md b/crates/red_knot_python_semantic/resources/mdtest/call/invalid_syntax.md index e919d26adf..81b933d7f5 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/invalid_syntax.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/invalid_syntax.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/methods.md b/crates/red_knot_python_semantic/resources/mdtest/call/methods.md index 5aa3f0e3d2..c09e749388 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/methods.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/methods.md @@ -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() ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/subclass_of.md b/crates/red_knot_python_semantic/resources/mdtest/call/subclass_of.md index 747367b03f..9fe47b9b6c 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/subclass_of.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/subclass_of.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/union.md b/crates/red_knot_python_semantic/resources/mdtest/call/union.md index 15ef569ca2..d76fc2ed2b 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/union.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/union.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/decorators.md b/crates/red_knot_python_semantic/resources/mdtest/decorators.md index c13002fcc5..0d957b2dc7 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/decorators.md +++ b/crates/red_knot_python_semantic/resources/mdtest/decorators.md @@ -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): ... diff --git a/crates/red_knot_python_semantic/resources/mdtest/doc/public_type_undeclared_symbols.md b/crates/red_knot_python_semantic/resources/mdtest/doc/public_type_undeclared_symbols.md index 20216871fe..72676dfbeb 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/doc/public_type_undeclared_symbols.md +++ b/crates/red_knot_python_semantic/resources/mdtest/doc/public_type_undeclared_symbols.md @@ -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) ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md b/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md index 8630731764..ee767056e8 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md +++ b/crates/red_knot_python_semantic/resources/mdtest/generics/classes.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/generics/scoping.md b/crates/red_knot_python_semantic/resources/mdtest/generics/scoping.md index 2a8d75b16e..f38070751a 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/generics/scoping.md +++ b/crates/red_knot_python_semantic/resources/mdtest/generics/scoping.md @@ -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") ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/properties.md b/crates/red_knot_python_semantic/resources/mdtest/properties.md index de16979c66..df35515d5a 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/properties.md +++ b/crates/red_knot_python_semantic/resources/mdtest/properties.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Basic.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Basic.snap index b4b36a97c1..a95ae257f4 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Basic.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Basic.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Calls_to_methods.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Calls_to_methods.snap index 5e0c69ff53..b6ef280203 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Calls_to_methods.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Calls_to_methods.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Different_files.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Different_files.snap index ad36916718..25d65a1940 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Different_files.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Different_files.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Different_source_order.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Different_source_order.snap index 5ba67561db..8910a6e1bf 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Different_source_order.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Different_source_order.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters.snap index 72e8308e75..b23b61c9ba 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters_across_multiple_lines.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters_across_multiple_lines.snap index 8aa83c7731..8d08b8b9de 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters_across_multiple_lines.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters_across_multiple_lines.snap @@ -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: | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters_with_multiple_invalid_arguments.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters_with_multiple_invalid_arguments.snap index 49ca11e364..c4b5dd3677 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters_with_multiple_invalid_arguments.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Many_parameters_with_multiple_invalid_arguments.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Test_calling_a_function_whose_type_is_vendored_from_`typeshed`.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Test_calling_a_function_whose_type_is_vendored_from_`typeshed`.snap index e3005a3fd2..8ff31730b7 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Test_calling_a_function_whose_type_is_vendored_from_`typeshed`.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Test_calling_a_function_whose_type_is_vendored_from_`typeshed`.snap @@ -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, | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Keyword_only_arguments.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Keyword_only_arguments.snap index b0a18cb859..6bb4b90f22 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Keyword_only_arguments.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Keyword_only_arguments.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Mix_of_arguments.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Mix_of_arguments.snap index c00be2519d..e9fc47e2bc 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Mix_of_arguments.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Mix_of_arguments.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_One_keyword_argument.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_One_keyword_argument.snap index 59cd8a5765..6add6e72c6 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_One_keyword_argument.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_One_keyword_argument.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Only_positional.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Only_positional.snap index 6a1d45927b..7834637de1 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Only_positional.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Only_positional.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Synthetic_arguments.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Synthetic_arguments.snap index 4d2c7acaa1..6dfa130e9b 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Synthetic_arguments.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Synthetic_arguments.snap @@ -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 | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Variadic_arguments.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Variadic_arguments.snap index 5e497d60a0..b9ef2e2e33 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Variadic_arguments.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Variadic_arguments.snap @@ -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) | diff --git a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Variadic_keyword_arguments.snap b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Variadic_keyword_arguments.snap index e3f03dc8ba..d61b550349 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Variadic_keyword_arguments.snap +++ b/crates/red_knot_python_semantic/resources/mdtest/snapshots/invalid_argument_type.md_-_Invalid_argument_type_diagnostics_-_Tests_for_a_variety_of_argument_types_-_Variadic_keyword_arguments.snap @@ -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) | diff --git a/crates/red_knot_python_semantic/src/types/call/bind.rs b/crates/red_knot_python_semantic/src/types/call/bind.rs index 3bafa82cd1..d4f811b0aa 100644 --- a/crates/red_knot_python_semantic/src/types/call/bind.rs +++ b/crates/red_knot_python_semantic/src/types/call/bind.rs @@ -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 { + ) -> 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 {