Skip to content

Commit

Permalink
Use position
Browse files Browse the repository at this point in the history
  • Loading branch information
harupy committed Dec 25, 2024
1 parent e4e7107 commit 53bc93f
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 96 deletions.
62 changes: 29 additions & 33 deletions crates/ruff_linter/src/rules/ruff/rules/none_not_at_end_of_union.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use itertools::Itertools;
use itertools::{Itertools, Position};
use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, ViolationMetadata};
use ruff_python_ast::{self as ast, Expr};
Expand Down Expand Up @@ -78,41 +78,37 @@ pub(crate) fn none_not_at_end_of_union<'a>(checker: &mut Checker, union: &'a Exp
return;
}

if let Some(last) = none_exprs.pop() {
let mut elements = non_none_exprs
.iter()
.map(|expr| checker.locator().slice(expr.range()).to_string())
.chain(std::iter::once("None".to_string()));
let fix = if let Expr::Subscript(ast::ExprSubscript { slice, .. }) = union {
let applicability = if checker.comment_ranges().intersects(slice.range()) {
Applicability::Unsafe
for (pos, none_expr) in none_exprs.iter().with_position() {
let mut diagnostic = Diagnostic::new(NoneNotAtEndOfUnion, none_expr.range());
if matches!(pos, Position::Last | Position::Only) {
let mut elements = non_none_exprs
.iter()
.map(|expr| checker.locator().slice(expr.range()).to_string())
.chain(std::iter::once("None".to_string()));
let fix = if let Expr::Subscript(ast::ExprSubscript { slice, .. }) = union {
let applicability = if checker.comment_ranges().intersects(slice.range()) {
Applicability::Unsafe
} else {
Applicability::Safe
};
Fix::applicable_edit(
Edit::range_replacement(elements.join(", "), slice.range()),
applicability,
)
} else {
Applicability::Safe
let applicability = if checker.comment_ranges().intersects(union.range()) {
Applicability::Unsafe
} else {
Applicability::Safe
};
Fix::applicable_edit(
Edit::range_replacement(elements.join(" | "), union.range()),
applicability,
)
};
Fix::applicable_edit(
Edit::range_replacement(elements.join(", "), slice.range()),
applicability,
)
} else {
let applicability = if checker.comment_ranges().intersects(union.range()) {
Applicability::Unsafe
} else {
Applicability::Safe
};
Fix::applicable_edit(
Edit::range_replacement(elements.join(" | "), union.range()),
applicability,
)
};
diagnostic.set_fix(fix);
}

let mut diagnostic = Diagnostic::new(NoneNotAtEndOfUnion, last.range());
diagnostic.set_fix(fix);
checker.diagnostics.push(diagnostic);
}

for none_expr in none_exprs {
checker
.diagnostics
.push(Diagnostic::new(NoneNotAtEndOfUnion, none_expr.range()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,36 +38,36 @@ RUF036.py:8:16: RUF036 [*] `None` not at the end of the type annotation.
10 10 |
11 11 |

RUF036.py:12:16: RUF036 [*] `None` not at the end of the type annotation.
RUF036.py:12:16: RUF036 `None` not at the end of the type annotation.
|
12 | def func2() -> None | int:
12 | def func3(arg: None | None | int):
| ^^^^ RUF036
13 | ...
|
= help: Move `None` to the end of the type annotation

RUF036.py:12:23: RUF036 [*] `None` not at the end of the type annotation.
|
12 | def func3(arg: None | None | int):
| ^^^^ RUF036
13 | ...
|
= help: Move `None` to the end of the type annotation

Safe fix
9 9 | ...
10 10 |
11 11 |
12 |-def func2() -> None | int:
12 |+def func2() -> int | None:
12 |-def func3(arg: None | None | int):
12 |+def func3(arg: int | None):
13 13 | ...
14 14 |
15 15 |

RUF036.py:16:16: RUF036 `None` not at the end of the type annotation.
|
16 | def func3(arg: None | None | int):
| ^^^^ RUF036
17 | ...
RUF036.py:16:18: RUF036 [*] `None` not at the end of the type annotation.
|
= help: Move `None` to the end of the type annotation

RUF036.py:16:23: RUF036 [*] `None` not at the end of the type annotation.
|
16 | def func3(arg: None | None | int):
| ^^^^ RUF036
16 | def func4(arg: U[None, int]):
| ^^^^ RUF036
17 | ...
|
= help: Move `None` to the end of the type annotation
Expand All @@ -76,15 +76,15 @@ RUF036.py:16:23: RUF036 [*] `None` not at the end of the type annotation.
13 13 | ...
14 14 |
15 15 |
16 |-def func3(arg: None | None | int):
16 |+def func3(arg: int | None):
16 |-def func4(arg: U[None, int]):
16 |+def func4(arg: U[int, None]):
17 17 | ...
18 18 |
19 19 |

RUF036.py:20:18: RUF036 [*] `None` not at the end of the type annotation.
|
20 | def func4(arg: U[None, int]):
20 | def func5() -> U[None, int]:
| ^^^^ RUF036
21 | ...
|
Expand All @@ -94,74 +94,56 @@ RUF036.py:20:18: RUF036 [*] `None` not at the end of the type annotation.
17 17 | ...
18 18 |
19 19 |
20 |-def func4(arg: U[None, int]):
20 |+def func4(arg: U[int, None]):
20 |-def func5() -> U[None, int]:
20 |+def func5() -> U[int, None]:
21 21 | ...
22 22 |
23 23 |

RUF036.py:24:18: RUF036 [*] `None` not at the end of the type annotation.
RUF036.py:24:18: RUF036 `None` not at the end of the type annotation.
|
24 | def func5() -> U[None, int]:
24 | def func6(arg: U[None, None, int]):
| ^^^^ RUF036
25 | ...
|
= help: Move `None` to the end of the type annotation

Safe fix
21 21 | ...
22 22 |
23 23 |
24 |-def func5() -> U[None, int]:
24 |+def func5() -> U[int, None]:
25 25 | ...
26 26 |
27 27 |

RUF036.py:28:18: RUF036 `None` not at the end of the type annotation.
|
28 | def func6(arg: U[None, None, int]):
| ^^^^ RUF036
29 | ...
|
= help: Move `None` to the end of the type annotation

RUF036.py:28:24: RUF036 [*] `None` not at the end of the type annotation.
RUF036.py:24:24: RUF036 [*] `None` not at the end of the type annotation.
|
28 | def func6(arg: U[None, None, int]):
24 | def func6(arg: U[None, None, int]):
| ^^^^ RUF036
29 | ...
25 | ...
|
= help: Move `None` to the end of the type annotation

Safe fix
21 21 | ...
22 22 |
23 23 |
24 |-def func6(arg: U[None, None, int]):
24 |+def func6(arg: U[int, None]):
25 25 | ...
26 26 |
27 27 |
28 |-def func6(arg: U[None, None, int]):
28 |+def func6(arg: U[int, None]):
29 29 | ...
30 30 |
31 31 |

RUF036.py:33:5: RUF036 [*] `None` not at the end of the type annotation.
RUF036.py:29:5: RUF036 [*] `None` not at the end of the type annotation.
|
32 | def func7() -> U[
33 | None,
28 | def func7() -> U[
29 | None,
| ^^^^ RUF036
34 | # comment
35 | int
30 | # comment
31 | int
|
= help: Move `None` to the end of the type annotation

Unsafe fix
30 30 |
31 31 |
32 32 | def func7() -> U[
33 |- None,
34 |- # comment
35 |- int
33 |+ int, None
36 34 | ]:
37 35 | ...
38 36 |
26 26 |
27 27 |
28 28 | def func7() -> U[
29 |- None,
30 |- # comment
31 |- int
29 |+ int, None
32 30 | ]:
33 31 | ...
34 32 |

0 comments on commit 53bc93f

Please sign in to comment.