mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
red_knot_python_semantic: migrate INVALID_ASSIGNMENT for shadowing
We mostly keep things the same here, but the message has been moved from the annotation to the diagnostic's top-line message. I think this is perhaps a little worse, but some bigger improvements could be made here. Indeed, we could perhaps even add a "fix" here.
This commit is contained in:
parent
890ba725d9
commit
6dc2d29966
9 changed files with 109 additions and 17 deletions
|
@ -0,0 +1,19 @@
|
|||
# Shadowing
|
||||
|
||||
<!-- snapshot-diagnostics -->
|
||||
|
||||
## Implicit class shadowing
|
||||
|
||||
```py
|
||||
class C: ...
|
||||
|
||||
C = 1 # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
## Implicit function shadowing
|
||||
|
||||
```py
|
||||
def f(): ...
|
||||
|
||||
f = 1 # error: [invalid-assignment]
|
||||
```
|
|
@ -5,7 +5,7 @@
|
|||
```py
|
||||
class C: ...
|
||||
|
||||
C = 1 # error: "Implicit shadowing of class `C`; annotate to make it explicit if this is intentional"
|
||||
C = 1 # error: "Implicit shadowing of class `C`"
|
||||
```
|
||||
|
||||
## Explicit
|
||||
|
|
|
@ -15,7 +15,7 @@ def f(x: str):
|
|||
```py
|
||||
def f(): ...
|
||||
|
||||
f = 1 # error: "Implicit shadowing of function `f`; annotate to make it explicit if this is intentional"
|
||||
f = 1 # error: "Implicit shadowing of function `f`"
|
||||
```
|
||||
|
||||
## Explicit shadowing
|
||||
|
|
|
@ -26,13 +26,13 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/attrib
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-assignment
|
||||
error: lint:invalid-assignment: Object of type `Literal["wrong"]` is not assignable to attribute `attr` of type `int`
|
||||
--> /src/mdtest_snippet.py:6:1
|
||||
|
|
||||
4 | instance = C()
|
||||
5 | instance.attr = 1 # fine
|
||||
6 | instance.attr = "wrong" # error: [invalid-assignment]
|
||||
| ^^^^^^^^^^^^^ Object of type `Literal["wrong"]` is not assignable to attribute `attr` of type `int`
|
||||
| ^^^^^^^^^^^^^
|
||||
7 |
|
||||
8 | C.attr = 1 # fine
|
||||
|
|
||||
|
@ -40,12 +40,12 @@ error: lint:invalid-assignment
|
|||
```
|
||||
|
||||
```
|
||||
error: lint:invalid-assignment
|
||||
error: lint:invalid-assignment: Object of type `Literal["wrong"]` is not assignable to attribute `attr` of type `int`
|
||||
--> /src/mdtest_snippet.py:9:1
|
||||
|
|
||||
8 | C.attr = 1 # fine
|
||||
9 | C.attr = "wrong" # error: [invalid-assignment]
|
||||
| ^^^^^^ Object of type `Literal["wrong"]` is not assignable to attribute `attr` of type `int`
|
||||
| ^^^^^^
|
||||
|
|
||||
|
||||
```
|
||||
|
|
|
@ -26,13 +26,13 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/attrib
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-assignment
|
||||
error: lint:invalid-assignment: Object of type `Literal["wrong"]` is not assignable to attribute `attr` of type `int`
|
||||
--> /src/mdtest_snippet.py:7:1
|
||||
|
|
||||
5 | instance = C()
|
||||
6 | instance.attr = 1 # fine
|
||||
7 | instance.attr = "wrong" # error: [invalid-assignment]
|
||||
| ^^^^^^^^^^^^^ Object of type `Literal["wrong"]` is not assignable to attribute `attr` of type `int`
|
||||
| ^^^^^^^^^^^^^
|
||||
8 |
|
||||
9 | C.attr = 1 # error: [invalid-attribute-access]
|
||||
|
|
||||
|
|
|
@ -27,12 +27,12 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/attrib
|
|||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-assignment
|
||||
error: lint:invalid-assignment: Object of type `Literal["wrong"]` is not assignable to attribute `attr` of type `int`
|
||||
--> /src/mdtest_snippet.py:7:1
|
||||
|
|
||||
6 | C.attr = 1 # fine
|
||||
7 | C.attr = "wrong" # error: [invalid-assignment]
|
||||
| ^^^^^^ Object of type `Literal["wrong"]` is not assignable to attribute `attr` of type `int`
|
||||
| ^^^^^^
|
||||
8 |
|
||||
9 | instance = C()
|
||||
|
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
source: crates/red_knot_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: shadowing.md - Shadowing - Implicit class shadowing
|
||||
mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/shadowing.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | class C: ...
|
||||
2 |
|
||||
3 | C = 1 # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-assignment: Implicit shadowing of class `C`
|
||||
--> /src/mdtest_snippet.py:3:1
|
||||
|
|
||||
1 | class C: ...
|
||||
2 |
|
||||
3 | C = 1 # error: [invalid-assignment]
|
||||
| ^
|
||||
|
|
||||
info: Annotate to make it explicit if this is intentional
|
||||
|
||||
```
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
source: crates/red_knot_test/src/lib.rs
|
||||
expression: snapshot
|
||||
---
|
||||
---
|
||||
mdtest name: shadowing.md - Shadowing - Implicit function shadowing
|
||||
mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/shadowing.md
|
||||
---
|
||||
|
||||
# Python source files
|
||||
|
||||
## mdtest_snippet.py
|
||||
|
||||
```
|
||||
1 | def f(): ...
|
||||
2 |
|
||||
3 | f = 1 # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error: lint:invalid-assignment: Implicit shadowing of function `f`
|
||||
--> /src/mdtest_snippet.py:3:1
|
||||
|
|
||||
1 | def f(): ...
|
||||
2 |
|
||||
3 | f = 1 # error: [invalid-assignment]
|
||||
| ^
|
||||
|
|
||||
info: Annotate to make it explicit if this is intentional
|
||||
|
||||
```
|
|
@ -1116,19 +1116,26 @@ fn report_invalid_assignment_with_message(
|
|||
target_ty: Type,
|
||||
message: std::fmt::Arguments,
|
||||
) {
|
||||
let Some(builder) = context.report_lint(&INVALID_ASSIGNMENT, node) else {
|
||||
return;
|
||||
};
|
||||
match target_ty {
|
||||
Type::ClassLiteral(class) => {
|
||||
context.report_lint_old(&INVALID_ASSIGNMENT, node, format_args!(
|
||||
"Implicit shadowing of class `{}`; annotate to make it explicit if this is intentional",
|
||||
class.name(context.db())));
|
||||
let mut diag = builder.into_diagnostic(format_args!(
|
||||
"Implicit shadowing of class `{}`",
|
||||
class.name(context.db()),
|
||||
));
|
||||
diag.info("Annotate to make it explicit if this is intentional");
|
||||
}
|
||||
Type::FunctionLiteral(function) => {
|
||||
context.report_lint_old(&INVALID_ASSIGNMENT, node, format_args!(
|
||||
"Implicit shadowing of function `{}`; annotate to make it explicit if this is intentional",
|
||||
function.name(context.db())));
|
||||
let mut diag = builder.into_diagnostic(format_args!(
|
||||
"Implicit shadowing of function `{}`",
|
||||
function.name(context.db()),
|
||||
));
|
||||
diag.info("Annotate to make it explicit if this is intentional");
|
||||
}
|
||||
_ => {
|
||||
context.report_lint_old(&INVALID_ASSIGNMENT, node, message);
|
||||
builder.into_diagnostic(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue