Skip to content

Commit 4ea3773

Browse files
committed
feat(ruff): add Python 3.15 support and retire RUF017
1 parent d035744 commit 4ea3773

20 files changed

+538
-185
lines changed

crates/ruff_linter/resources/test/fixtures/ruff/RUF017_0.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# target-version: py314
12
x = [1, 2, 3]
23
y = [4, 5, 6]
34

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
# target-version: py314
12
sum((factor.dims for factor in bases), [])
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# target-version: py315
2+
x = [1, 2, 3]
3+
y = [4, 5, 6]
4+
5+
# These should all be OK in 3.15+ because of PEP 798
6+
sum([x, y], start=[])
7+
sum([x, y], [])
8+
sum([[1, 2, 3], [4, 5, 6]], start=[])
9+
sum([[1, 2, 3], [4, 5, 6]], [])
10+
11+
# This should also be ignored (from RUF017_1)
12+
sum((factor.dims for factor in bases), [])

crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP036_0.py.snap

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,48 @@ help: Remove outdated version block
838838
213 | print("py3")
839839
note: This is an unsafe fix and may change runtime behavior
840840

841+
UP036 [*] Version block is outdated for minimum Python version
842+
--> UP036_0.py:213:4
843+
|
844+
211 | print("py3")
845+
212 |
846+
213 | if sys.version_info[:2] > (3,14):
847+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
848+
214 | print("py3")
849+
|
850+
help: Remove outdated version block
851+
210 | if sys.version_info[:3] >= (3,0):
852+
211 | print("py3")
853+
212 |
854+
- if sys.version_info[:2] > (3,14):
855+
- print("py3")
856+
213 + print("py3")
857+
214 |
858+
215 | if sys.version_info[:3] > (3,14):
859+
216 | print("py3")
860+
note: This is an unsafe fix and may change runtime behavior
861+
862+
UP036 [*] Version block is outdated for minimum Python version
863+
--> UP036_0.py:216:4
864+
|
865+
214 | print("py3")
866+
215 |
867+
216 | if sys.version_info[:3] > (3,14):
868+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
869+
217 | print("py3")
870+
|
871+
help: Remove outdated version block
872+
213 | if sys.version_info[:2] > (3,14):
873+
214 | print("py3")
874+
215 |
875+
- if sys.version_info[:3] > (3,14):
876+
- print("py3")
877+
216 + print("py3")
878+
217 |
879+
218 | if sys.version_info > (3,0):
880+
219 | f"this is\
881+
note: This is an unsafe fix and may change runtime behavior
882+
841883
UP036 [*] Version block is outdated for minimum Python version
842884
--> UP036_0.py:219:4
843885
|

crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP036_5.py.snap

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,46 @@ help: Remove outdated version block
219219
68 | print()
220220
note: This is an unsafe fix and may change runtime behavior
221221

222+
UP036 [*] Version block is outdated for minimum Python version
223+
--> UP036_5.py:69:4
224+
|
225+
67 | print()
226+
68 |
227+
69 | if sys.version_info <= (3, 14, 0):
228+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
229+
70 | print()
230+
|
231+
help: Remove outdated version block
232+
66 | if sys.version_info <= (3, 13, 37):
233+
67 | print()
234+
68 |
235+
- if sys.version_info <= (3, 14, 0):
236+
- print()
237+
69 |
238+
70 | if sys.version_info <= (3, 14, 15):
239+
71 | print()
240+
note: This is an unsafe fix and may change runtime behavior
241+
242+
UP036 [*] Version block is outdated for minimum Python version
243+
--> UP036_5.py:72:4
244+
|
245+
70 | print()
246+
71 |
247+
72 | if sys.version_info <= (3, 14, 15):
248+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
249+
73 | print()
250+
|
251+
help: Remove outdated version block
252+
69 | if sys.version_info <= (3, 14, 0):
253+
70 | print()
254+
71 |
255+
- if sys.version_info <= (3, 14, 15):
256+
- print()
257+
72 |
258+
73 | # https://github.com/astral-sh/ruff/issues/18165
259+
74 |
260+
note: This is an unsafe fix and may change runtime behavior
261+
222262
UP036 [*] Version block is outdated for minimum Python version
223263
--> UP036_5.py:77:4
224264
|

crates/ruff_linter/src/rules/ruff/mod.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ mod tests {
5757
Path::new("RUF015.py")
5858
)]
5959
#[test_case(Rule::InvalidIndexType, Path::new("RUF016.py"))]
60-
#[test_case(Rule::QuadraticListSummation, Path::new("RUF017_1.py"))]
61-
#[test_case(Rule::QuadraticListSummation, Path::new("RUF017_0.py"))]
6260
#[test_case(Rule::AssignmentInAssert, Path::new("RUF018.py"))]
6361
#[test_case(Rule::UnnecessaryKeyCheck, Path::new("RUF019.py"))]
6462
#[test_case(Rule::NeverUnion, Path::new("RUF020.py"))]
@@ -740,4 +738,33 @@ mod tests {
740738
);
741739
Ok(())
742740
}
741+
742+
#[test]
743+
fn ruf017_legacy() -> Result<()> {
744+
let diagnostics = test_path(
745+
Path::new("ruff/RUF017_0.py"),
746+
&settings::LinterSettings::for_rule(Rule::QuadraticListSummation)
747+
.with_target_version(PythonVersion::PY314),
748+
)?;
749+
assert_diagnostics!("RUF017_0", diagnostics);
750+
751+
let diagnostics = test_path(
752+
Path::new("ruff/RUF017_1.py"),
753+
&settings::LinterSettings::for_rule(Rule::QuadraticListSummation)
754+
.with_target_version(PythonVersion::PY314),
755+
)?;
756+
assert_diagnostics!("RUF017_1", diagnostics);
757+
Ok(())
758+
}
759+
760+
#[test]
761+
fn ruf017_py315() -> Result<()> {
762+
let diagnostics = test_path(
763+
Path::new("ruff/RUF017_2.py"),
764+
&settings::LinterSettings::for_rule(Rule::QuadraticListSummation)
765+
.with_target_version(PythonVersion::PY315),
766+
)?;
767+
assert_diagnostics!("RUF017_2", diagnostics);
768+
Ok(())
769+
}
743770
}

crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use ruff_text_size::Ranged;
99

1010
use crate::checkers::ast::Checker;
1111
use crate::importer::ImportRequest;
12+
use crate::settings::types::PythonVersion;
1213
use crate::{AlwaysFixableViolation, Edit, Fix};
1314

1415
/// ## What it does
@@ -83,6 +84,10 @@ pub(crate) fn quadratic_list_summation(checker: &Checker, call: &ast::ExprCall)
8384
node_index: _,
8485
} = call;
8586

87+
if checker.target_version() >= PythonVersion::Py315.into() {
88+
return;
89+
}
90+
8691
let Some(iterable) = arguments.args.first() else {
8792
return;
8893
};
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
---
2+
source: crates/ruff_linter/src/rules/ruff/mod.rs
3+
---
4+
RUF017 [*] Avoid quadratic list summation
5+
--> RUF017_0.py:6:1
6+
|
7+
5 | # RUF017
8+
6 | sum([x, y], start=[])
9+
| ^^^^^^^^^^^^^^^^^^^^^
10+
7 | sum([x, y], [])
11+
8 | sum([[1, 2, 3], [4, 5, 6]], start=[])
12+
|
13+
help: Replace with `functools.reduce`
14+
1 | # target-version: py314
15+
2 + import functools
16+
3 + import operator
17+
4 | x = [1, 2, 3]
18+
5 | y = [4, 5, 6]
19+
6 |
20+
7 | # RUF017
21+
- sum([x, y], start=[])
22+
8 + functools.reduce(operator.iadd, [x, y], [])
23+
9 | sum([x, y], [])
24+
10 | sum([[1, 2, 3], [4, 5, 6]], start=[])
25+
11 | sum([[1, 2, 3], [4, 5, 6]], [])
26+
note: This is an unsafe fix and may change runtime behavior
27+
28+
RUF017 [*] Avoid quadratic list summation
29+
--> RUF017_0.py:7:1
30+
|
31+
5 | # RUF017
32+
6 | sum([x, y], start=[])
33+
7 | sum([x, y], [])
34+
| ^^^^^^^^^^^^^^^
35+
8 | sum([[1, 2, 3], [4, 5, 6]], start=[])
36+
9 | sum([[1, 2, 3], [4, 5, 6]], [])
37+
|
38+
help: Replace with `functools.reduce`
39+
1 | # target-version: py314
40+
2 + import functools
41+
3 + import operator
42+
4 | x = [1, 2, 3]
43+
5 | y = [4, 5, 6]
44+
6 |
45+
7 | # RUF017
46+
8 | sum([x, y], start=[])
47+
- sum([x, y], [])
48+
9 + functools.reduce(operator.iadd, [x, y], [])
49+
10 | sum([[1, 2, 3], [4, 5, 6]], start=[])
50+
11 | sum([[1, 2, 3], [4, 5, 6]], [])
51+
12 | sum([[1, 2, 3], [4, 5, 6]],
52+
note: This is an unsafe fix and may change runtime behavior
53+
54+
RUF017 [*] Avoid quadratic list summation
55+
--> RUF017_0.py:8:1
56+
|
57+
6 | sum([x, y], start=[])
58+
7 | sum([x, y], [])
59+
8 | sum([[1, 2, 3], [4, 5, 6]], start=[])
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
61+
9 | sum([[1, 2, 3], [4, 5, 6]], [])
62+
10 | sum([[1, 2, 3], [4, 5, 6]],
63+
|
64+
help: Replace with `functools.reduce`
65+
1 | # target-version: py314
66+
2 + import functools
67+
3 + import operator
68+
4 | x = [1, 2, 3]
69+
5 | y = [4, 5, 6]
70+
6 |
71+
7 | # RUF017
72+
8 | sum([x, y], start=[])
73+
9 | sum([x, y], [])
74+
- sum([[1, 2, 3], [4, 5, 6]], start=[])
75+
10 + functools.reduce(operator.iadd, [[1, 2, 3], [4, 5, 6]], [])
76+
11 | sum([[1, 2, 3], [4, 5, 6]], [])
77+
12 | sum([[1, 2, 3], [4, 5, 6]],
78+
13 | [])
79+
note: This is an unsafe fix and may change runtime behavior
80+
81+
RUF017 [*] Avoid quadratic list summation
82+
--> RUF017_0.py:9:1
83+
|
84+
7 | sum([x, y], [])
85+
8 | sum([[1, 2, 3], [4, 5, 6]], start=[])
86+
9 | sum([[1, 2, 3], [4, 5, 6]], [])
87+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
88+
10 | sum([[1, 2, 3], [4, 5, 6]],
89+
11 | [])
90+
|
91+
help: Replace with `functools.reduce`
92+
1 | # target-version: py314
93+
2 + import functools
94+
3 + import operator
95+
4 | x = [1, 2, 3]
96+
5 | y = [4, 5, 6]
97+
6 |
98+
--------------------------------------------------------------------------------
99+
8 | sum([x, y], start=[])
100+
9 | sum([x, y], [])
101+
10 | sum([[1, 2, 3], [4, 5, 6]], start=[])
102+
- sum([[1, 2, 3], [4, 5, 6]], [])
103+
11 + functools.reduce(operator.iadd, [[1, 2, 3], [4, 5, 6]], [])
104+
12 | sum([[1, 2, 3], [4, 5, 6]],
105+
13 | [])
106+
14 |
107+
note: This is an unsafe fix and may change runtime behavior
108+
109+
RUF017 [*] Avoid quadratic list summation
110+
--> RUF017_0.py:10:1
111+
|
112+
8 | sum([[1, 2, 3], [4, 5, 6]], start=[])
113+
9 | sum([[1, 2, 3], [4, 5, 6]], [])
114+
10 | / sum([[1, 2, 3], [4, 5, 6]],
115+
11 | | [])
116+
| |_______^
117+
12 |
118+
13 | # OK
119+
|
120+
help: Replace with `functools.reduce`
121+
1 | # target-version: py314
122+
2 + import functools
123+
3 + import operator
124+
4 | x = [1, 2, 3]
125+
5 | y = [4, 5, 6]
126+
6 |
127+
--------------------------------------------------------------------------------
128+
9 | sum([x, y], [])
129+
10 | sum([[1, 2, 3], [4, 5, 6]], start=[])
130+
11 | sum([[1, 2, 3], [4, 5, 6]], [])
131+
- sum([[1, 2, 3], [4, 5, 6]],
132+
- [])
133+
12 + functools.reduce(operator.iadd, [[1, 2, 3], [4, 5, 6]], [])
134+
13 |
135+
14 | # OK
136+
15 | sum([x, y])
137+
note: This is an unsafe fix and may change runtime behavior
138+
139+
RUF017 [*] Avoid quadratic list summation
140+
--> RUF017_0.py:22:5
141+
|
142+
20 | import functools, operator
143+
21 |
144+
22 | sum([x, y], [])
145+
| ^^^^^^^^^^^^^^^
146+
|
147+
help: Replace with `functools.reduce`
148+
19 | def func():
149+
20 | import functools, operator
150+
21 |
151+
- sum([x, y], [])
152+
22 + functools.reduce(operator.iadd, [x, y], [])
153+
23 |
154+
24 |
155+
25 | # Regression test for: https://github.com/astral-sh/ruff/issues/7718
156+
note: This is an unsafe fix and may change runtime behavior
157+
158+
RUF017 [*] Avoid quadratic list summation
159+
--> RUF017_0.py:27:5
160+
|
161+
25 | # Regression test for: https://github.com/astral-sh/ruff/issues/7718
162+
26 | def func():
163+
27 | sum((factor.dims for factor in bases), [])
164+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
165+
|
166+
help: Replace with `functools.reduce`
167+
1 | # target-version: py314
168+
2 + import functools
169+
3 + import operator
170+
4 | x = [1, 2, 3]
171+
5 | y = [4, 5, 6]
172+
6 |
173+
--------------------------------------------------------------------------------
174+
26 |
175+
27 | # Regression test for: https://github.com/astral-sh/ruff/issues/7718
176+
28 | def func():
177+
- sum((factor.dims for factor in bases), [])
178+
29 + functools.reduce(operator.iadd, (factor.dims for factor in bases), [])
179+
note: This is an unsafe fix and may change runtime behavior

crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017_1.py.snap renamed to crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_1.snap

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
source: crates/ruff_linter/src/rules/ruff/mod.rs
33
---
44
RUF017 [*] Avoid quadratic list summation
5-
--> RUF017_1.py:1:1
5+
--> RUF017_1.py:2:1
66
|
7-
1 | sum((factor.dims for factor in bases), [])
7+
1 | # target-version: py314
8+
2 | sum((factor.dims for factor in bases), [])
89
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
910
|
1011
help: Replace with `functools.reduce`
12+
1 | # target-version: py314
1113
- sum((factor.dims for factor in bases), [])
12-
1 + import functools
13-
2 + import operator
14-
3 + functools.reduce(operator.iadd, (factor.dims for factor in bases), [])
14+
2 + import functools
15+
3 + import operator
16+
4 + functools.reduce(operator.iadd, (factor.dims for factor in bases), [])
1517
note: This is an unsafe fix and may change runtime behavior
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
source: crates/ruff_linter/src/rules/ruff/mod.rs
3+
---
4+

0 commit comments

Comments
 (0)