Skip to content

Commit 5018701

Browse files
authored
[refurb] Avoid false positives for math-constant (FURB152) (#9290)
Fixes #9281
1 parent 2951339 commit 5018701

File tree

3 files changed

+311
-11
lines changed

3 files changed

+311
-11
lines changed

crates/ruff_linter/resources/test/fixtures/refurb/FURB152.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,36 @@
1010

1111
r = 3.141 # FURB152
1212

13+
r = 3.142 # FURB152
14+
1315
r = 3.1415 # FURB152
1416

17+
r = 3.1416 # FURB152
18+
19+
r = 3.141592 # FURB152
20+
21+
r = 3.141593 # FURB152
22+
23+
r = 3.14159265 # FURB152
24+
25+
r = 3.141592653589793238462643383279 # FURB152
26+
27+
r = 3.14159266 # OK
28+
1529
e = 2.7 # OK
30+
31+
e = 2.718 # FURB152
32+
33+
e = 2.7182 # FURB152
34+
35+
e = 2.7183 # FURB152
36+
37+
e = 2.719 # OK
38+
39+
e = 2.71824 # OK
40+
41+
e = 2.71820001 # OK
42+
43+
e = 2.718200000000001 # OK
44+
45+
e = 2.7182000000000001 # FURB152

crates/ruff_linter/src/rules/refurb/rules/math_constant.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ fn convert_to_constant(
8383
))
8484
}
8585

86+
fn matches_constant(constant: f64, value: f64) -> bool {
87+
for point in 2..=15 {
88+
let rounded = (constant * 10_f64.powi(point)).round() / 10_f64.powi(point);
89+
if (rounded - value).abs() < f64::EPSILON {
90+
return true;
91+
}
92+
let rounded = (constant * 10_f64.powi(point)).floor() / 10_f64.powi(point);
93+
if (rounded - value).abs() < f64::EPSILON {
94+
return true;
95+
}
96+
}
97+
false
98+
}
99+
86100
#[derive(Debug, Clone, Copy)]
87101
enum Constant {
88102
Pi,
@@ -94,11 +108,11 @@ impl Constant {
94108
#[allow(clippy::approx_constant)]
95109
fn from_value(value: f64) -> Option<Self> {
96110
if (3.14..3.15).contains(&value) {
97-
Some(Self::Pi)
111+
matches_constant(std::f64::consts::PI, value).then_some(Self::Pi)
98112
} else if (2.71..2.72).contains(&value) {
99-
Some(Self::E)
113+
matches_constant(std::f64::consts::E, value).then_some(Self::E)
100114
} else if (6.28..6.29).contains(&value) {
101-
Some(Self::Tau)
115+
matches_constant(std::f64::consts::TAU, value).then_some(Self::Tau)
102116
} else {
103117
None
104118
}

crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB152_FURB152.py.snap

Lines changed: 264 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ FURB152.py:11:5: FURB152 [*] Replace `3.141` with `math.pi`
7777
11 | r = 3.141 # FURB152
7878
| ^^^^^ FURB152
7979
12 |
80-
13 | r = 3.1415 # FURB152
80+
13 | r = 3.142 # FURB152
8181
|
8282
= help: Use `math.pi`
8383

@@ -93,17 +93,17 @@ FURB152.py:11:5: FURB152 [*] Replace `3.141` with `math.pi`
9393
11 |-r = 3.141 # FURB152
9494
12 |+r = math.pi # FURB152
9595
12 13 |
96-
13 14 | r = 3.1415 # FURB152
96+
13 14 | r = 3.142 # FURB152
9797
14 15 |
9898

99-
FURB152.py:13:5: FURB152 [*] Replace `3.1415` with `math.pi`
99+
FURB152.py:13:5: FURB152 [*] Replace `3.142` with `math.pi`
100100
|
101101
11 | r = 3.141 # FURB152
102102
12 |
103-
13 | r = 3.1415 # FURB152
104-
| ^^^^^^ FURB152
103+
13 | r = 3.142 # FURB152
104+
| ^^^^^ FURB152
105105
14 |
106-
15 | e = 2.7 # OK
106+
15 | r = 3.1415 # FURB152
107107
|
108108
= help: Use `math.pi`
109109

@@ -116,9 +116,265 @@ FURB152.py:13:5: FURB152 [*] Replace `3.1415` with `math.pi`
116116
10 11 |
117117
11 12 | r = 3.141 # FURB152
118118
12 13 |
119-
13 |-r = 3.1415 # FURB152
119+
13 |-r = 3.142 # FURB152
120120
14 |+r = math.pi # FURB152
121121
14 15 |
122-
15 16 | e = 2.7 # OK
122+
15 16 | r = 3.1415 # FURB152
123+
16 17 |
124+
125+
FURB152.py:15:5: FURB152 [*] Replace `3.1415` with `math.pi`
126+
|
127+
13 | r = 3.142 # FURB152
128+
14 |
129+
15 | r = 3.1415 # FURB152
130+
| ^^^^^^ FURB152
131+
16 |
132+
17 | r = 3.1416 # FURB152
133+
|
134+
= help: Use `math.pi`
135+
136+
Safe fix
137+
1 |+import math
138+
1 2 | r = 3.1 # OK
139+
2 3 |
140+
3 4 | A = 3.14 * r ** 2 # FURB152
141+
--------------------------------------------------------------------------------
142+
12 13 |
143+
13 14 | r = 3.142 # FURB152
144+
14 15 |
145+
15 |-r = 3.1415 # FURB152
146+
16 |+r = math.pi # FURB152
147+
16 17 |
148+
17 18 | r = 3.1416 # FURB152
149+
18 19 |
150+
151+
FURB152.py:17:5: FURB152 [*] Replace `3.1416` with `math.pi`
152+
|
153+
15 | r = 3.1415 # FURB152
154+
16 |
155+
17 | r = 3.1416 # FURB152
156+
| ^^^^^^ FURB152
157+
18 |
158+
19 | r = 3.141592 # FURB152
159+
|
160+
= help: Use `math.pi`
161+
162+
Safe fix
163+
1 |+import math
164+
1 2 | r = 3.1 # OK
165+
2 3 |
166+
3 4 | A = 3.14 * r ** 2 # FURB152
167+
--------------------------------------------------------------------------------
168+
14 15 |
169+
15 16 | r = 3.1415 # FURB152
170+
16 17 |
171+
17 |-r = 3.1416 # FURB152
172+
18 |+r = math.pi # FURB152
173+
18 19 |
174+
19 20 | r = 3.141592 # FURB152
175+
20 21 |
176+
177+
FURB152.py:19:5: FURB152 [*] Replace `3.141592` with `math.pi`
178+
|
179+
17 | r = 3.1416 # FURB152
180+
18 |
181+
19 | r = 3.141592 # FURB152
182+
| ^^^^^^^^ FURB152
183+
20 |
184+
21 | r = 3.141593 # FURB152
185+
|
186+
= help: Use `math.pi`
187+
188+
Safe fix
189+
1 |+import math
190+
1 2 | r = 3.1 # OK
191+
2 3 |
192+
3 4 | A = 3.14 * r ** 2 # FURB152
193+
--------------------------------------------------------------------------------
194+
16 17 |
195+
17 18 | r = 3.1416 # FURB152
196+
18 19 |
197+
19 |-r = 3.141592 # FURB152
198+
20 |+r = math.pi # FURB152
199+
20 21 |
200+
21 22 | r = 3.141593 # FURB152
201+
22 23 |
202+
203+
FURB152.py:21:5: FURB152 [*] Replace `3.141593` with `math.pi`
204+
|
205+
19 | r = 3.141592 # FURB152
206+
20 |
207+
21 | r = 3.141593 # FURB152
208+
| ^^^^^^^^ FURB152
209+
22 |
210+
23 | r = 3.14159265 # FURB152
211+
|
212+
= help: Use `math.pi`
213+
214+
Safe fix
215+
1 |+import math
216+
1 2 | r = 3.1 # OK
217+
2 3 |
218+
3 4 | A = 3.14 * r ** 2 # FURB152
219+
--------------------------------------------------------------------------------
220+
18 19 |
221+
19 20 | r = 3.141592 # FURB152
222+
20 21 |
223+
21 |-r = 3.141593 # FURB152
224+
22 |+r = math.pi # FURB152
225+
22 23 |
226+
23 24 | r = 3.14159265 # FURB152
227+
24 25 |
228+
229+
FURB152.py:23:5: FURB152 [*] Replace `3.14159265` with `math.pi`
230+
|
231+
21 | r = 3.141593 # FURB152
232+
22 |
233+
23 | r = 3.14159265 # FURB152
234+
| ^^^^^^^^^^ FURB152
235+
24 |
236+
25 | r = 3.141592653589793238462643383279 # FURB152
237+
|
238+
= help: Use `math.pi`
239+
240+
Safe fix
241+
1 |+import math
242+
1 2 | r = 3.1 # OK
243+
2 3 |
244+
3 4 | A = 3.14 * r ** 2 # FURB152
245+
--------------------------------------------------------------------------------
246+
20 21 |
247+
21 22 | r = 3.141593 # FURB152
248+
22 23 |
249+
23 |-r = 3.14159265 # FURB152
250+
24 |+r = math.pi # FURB152
251+
24 25 |
252+
25 26 | r = 3.141592653589793238462643383279 # FURB152
253+
26 27 |
254+
255+
FURB152.py:25:5: FURB152 [*] Replace `3.141592653589793238462643383279` with `math.pi`
256+
|
257+
23 | r = 3.14159265 # FURB152
258+
24 |
259+
25 | r = 3.141592653589793238462643383279 # FURB152
260+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB152
261+
26 |
262+
27 | r = 3.14159266 # OK
263+
|
264+
= help: Use `math.pi`
265+
266+
Safe fix
267+
1 |+import math
268+
1 2 | r = 3.1 # OK
269+
2 3 |
270+
3 4 | A = 3.14 * r ** 2 # FURB152
271+
--------------------------------------------------------------------------------
272+
22 23 |
273+
23 24 | r = 3.14159265 # FURB152
274+
24 25 |
275+
25 |-r = 3.141592653589793238462643383279 # FURB152
276+
26 |+r = math.pi # FURB152
277+
26 27 |
278+
27 28 | r = 3.14159266 # OK
279+
28 29 |
280+
281+
FURB152.py:31:5: FURB152 [*] Replace `2.718` with `math.e`
282+
|
283+
29 | e = 2.7 # OK
284+
30 |
285+
31 | e = 2.718 # FURB152
286+
| ^^^^^ FURB152
287+
32 |
288+
33 | e = 2.7182 # FURB152
289+
|
290+
= help: Use `math.e`
291+
292+
Safe fix
293+
1 |+import math
294+
1 2 | r = 3.1 # OK
295+
2 3 |
296+
3 4 | A = 3.14 * r ** 2 # FURB152
297+
--------------------------------------------------------------------------------
298+
28 29 |
299+
29 30 | e = 2.7 # OK
300+
30 31 |
301+
31 |-e = 2.718 # FURB152
302+
32 |+e = math.e # FURB152
303+
32 33 |
304+
33 34 | e = 2.7182 # FURB152
305+
34 35 |
306+
307+
FURB152.py:33:5: FURB152 [*] Replace `2.7182` with `math.e`
308+
|
309+
31 | e = 2.718 # FURB152
310+
32 |
311+
33 | e = 2.7182 # FURB152
312+
| ^^^^^^ FURB152
313+
34 |
314+
35 | e = 2.7183 # FURB152
315+
|
316+
= help: Use `math.e`
317+
318+
Safe fix
319+
1 |+import math
320+
1 2 | r = 3.1 # OK
321+
2 3 |
322+
3 4 | A = 3.14 * r ** 2 # FURB152
323+
--------------------------------------------------------------------------------
324+
30 31 |
325+
31 32 | e = 2.718 # FURB152
326+
32 33 |
327+
33 |-e = 2.7182 # FURB152
328+
34 |+e = math.e # FURB152
329+
34 35 |
330+
35 36 | e = 2.7183 # FURB152
331+
36 37 |
332+
333+
FURB152.py:35:5: FURB152 [*] Replace `2.7183` with `math.e`
334+
|
335+
33 | e = 2.7182 # FURB152
336+
34 |
337+
35 | e = 2.7183 # FURB152
338+
| ^^^^^^ FURB152
339+
36 |
340+
37 | e = 2.719 # OK
341+
|
342+
= help: Use `math.e`
343+
344+
Safe fix
345+
1 |+import math
346+
1 2 | r = 3.1 # OK
347+
2 3 |
348+
3 4 | A = 3.14 * r ** 2 # FURB152
349+
--------------------------------------------------------------------------------
350+
32 33 |
351+
33 34 | e = 2.7182 # FURB152
352+
34 35 |
353+
35 |-e = 2.7183 # FURB152
354+
36 |+e = math.e # FURB152
355+
36 37 |
356+
37 38 | e = 2.719 # OK
357+
38 39 |
358+
359+
FURB152.py:45:5: FURB152 [*] Replace `2.7182000000000001` with `math.e`
360+
|
361+
43 | e = 2.718200000000001 # OK
362+
44 |
363+
45 | e = 2.7182000000000001 # FURB152
364+
| ^^^^^^^^^^^^^^^^^^ FURB152
365+
|
366+
= help: Use `math.e`
367+
368+
Safe fix
369+
1 |+import math
370+
1 2 | r = 3.1 # OK
371+
2 3 |
372+
3 4 | A = 3.14 * r ** 2 # FURB152
373+
--------------------------------------------------------------------------------
374+
42 43 |
375+
43 44 | e = 2.718200000000001 # OK
376+
44 45 |
377+
45 |-e = 2.7182000000000001 # FURB152
378+
46 |+e = math.e # FURB152
123379

124380

0 commit comments

Comments
 (0)