Skip to content

Commit 1fcccf8

Browse files
Avoid syntax error via importing trio.lowlevel (#8730)
We ended up with a syntax error here via `from trio import lowlevel.checkpoint`. The new solution avoids that error, but does miss cases like: ```py from trio.lowlevel import Timer ``` Where it could insert `from trio.lowlevel import Timer, checkpoint`. Instead, it'll add `from trio import lowlevel`. See: #8402 (comment)
1 parent 14e65af commit 1fcccf8

File tree

3 files changed

+77
-86
lines changed

3 files changed

+77
-86
lines changed

crates/ruff_linter/resources/test/fixtures/flake8_trio/TRIO115.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import trio
2-
from trio import sleep
3-
4-
51
async def func():
2+
import trio
3+
from trio import sleep
4+
65
await trio.sleep(0) # TRIO115
76
await trio.sleep(1) # OK
87
await trio.sleep(0, 1) # OK
@@ -21,8 +20,11 @@ async def func():
2120
trio.sleep(bar)
2221

2322

24-
trio.sleep(0) # TRIO115
23+
def func():
24+
trio.run(trio.sleep(0)) # TRIO115
25+
2526

27+
from trio import Event, sleep
2628

2729
def func():
28-
trio.run(trio.sleep(0)) # TRIO115
30+
sleep(0) # TRIO115

crates/ruff_linter/src/rules/flake8_trio/rules/zero_sleep_call.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,12 @@ pub(crate) fn zero_sleep_call(checker: &mut Checker, call: &ExprCall) {
9797
let mut diagnostic = Diagnostic::new(TrioZeroSleepCall, call.range());
9898
diagnostic.try_set_fix(|| {
9999
let (import_edit, binding) = checker.importer().get_or_import_symbol(
100-
&ImportRequest::import("trio", "lowlevel.checkpoint"),
100+
&ImportRequest::import_from("trio", "lowlevel"),
101101
call.func.start(),
102102
checker.semantic(),
103103
)?;
104-
let reference_edit = Edit::range_replacement(binding, call.func.range());
104+
let reference_edit =
105+
Edit::range_replacement(format!("{binding}.checkpoint"), call.func.range());
105106
let arg_edit = Edit::range_deletion(call.arguments.range);
106107
Ok(Fix::safe_edits(import_edit, [reference_edit, arg_edit]))
107108
});
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,107 @@
11
---
22
source: crates/ruff_linter/src/rules/flake8_trio/mod.rs
33
---
4-
TRIO115.py:6:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
4+
TRIO115.py:5:11: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
55
|
6-
5 | async def func():
7-
6 | await trio.sleep(0) # TRIO115
6+
3 | from trio import sleep
7+
4 |
8+
5 | await trio.sleep(0) # TRIO115
89
| ^^^^^^^^^^^^^ TRIO115
9-
7 | await trio.sleep(1) # OK
10-
8 | await trio.sleep(0, 1) # OK
10+
6 | await trio.sleep(1) # OK
11+
7 | await trio.sleep(0, 1) # OK
1112
|
1213
= help: Replace with `trio.lowlevel.checkpoint()`
1314

1415
Safe fix
15-
3 3 |
16+
2 2 | import trio
17+
3 3 | from trio import sleep
1618
4 4 |
17-
5 5 | async def func():
18-
6 |- await trio.sleep(0) # TRIO115
19-
6 |+ await trio.lowlevel.checkpoint # TRIO115
20-
7 7 | await trio.sleep(1) # OK
21-
8 8 | await trio.sleep(0, 1) # OK
22-
9 9 | await trio.sleep(...) # OK
19+
5 |- await trio.sleep(0) # TRIO115
20+
5 |+ await trio.lowlevel.checkpoint # TRIO115
21+
6 6 | await trio.sleep(1) # OK
22+
7 7 | await trio.sleep(0, 1) # OK
23+
8 8 | await trio.sleep(...) # OK
2324

24-
TRIO115.py:12:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
25+
TRIO115.py:11:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
2526
|
26-
10 | await trio.sleep() # OK
27-
11 |
28-
12 | trio.sleep(0) # TRIO115
27+
9 | await trio.sleep() # OK
28+
10 |
29+
11 | trio.sleep(0) # TRIO115
2930
| ^^^^^^^^^^^^^ TRIO115
30-
13 | foo = 0
31-
14 | trio.sleep(foo) # TRIO115
31+
12 | foo = 0
32+
13 | trio.sleep(foo) # TRIO115
3233
|
3334
= help: Replace with `trio.lowlevel.checkpoint()`
3435

3536
Safe fix
36-
9 9 | await trio.sleep(...) # OK
37-
10 10 | await trio.sleep() # OK
38-
11 11 |
39-
12 |- trio.sleep(0) # TRIO115
40-
12 |+ trio.lowlevel.checkpoint # TRIO115
41-
13 13 | foo = 0
42-
14 14 | trio.sleep(foo) # TRIO115
43-
15 15 | trio.sleep(1) # OK
37+
8 8 | await trio.sleep(...) # OK
38+
9 9 | await trio.sleep() # OK
39+
10 10 |
40+
11 |- trio.sleep(0) # TRIO115
41+
11 |+ trio.lowlevel.checkpoint # TRIO115
42+
12 12 | foo = 0
43+
13 13 | trio.sleep(foo) # TRIO115
44+
14 14 | trio.sleep(1) # OK
4445

45-
TRIO115.py:14:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
46+
TRIO115.py:13:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
4647
|
47-
12 | trio.sleep(0) # TRIO115
48-
13 | foo = 0
49-
14 | trio.sleep(foo) # TRIO115
48+
11 | trio.sleep(0) # TRIO115
49+
12 | foo = 0
50+
13 | trio.sleep(foo) # TRIO115
5051
| ^^^^^^^^^^^^^^^ TRIO115
51-
15 | trio.sleep(1) # OK
52-
16 | time.sleep(0) # OK
52+
14 | trio.sleep(1) # OK
53+
15 | time.sleep(0) # OK
5354
|
5455
= help: Replace with `trio.lowlevel.checkpoint()`
5556

5657
Safe fix
57-
11 11 |
58-
12 12 | trio.sleep(0) # TRIO115
59-
13 13 | foo = 0
60-
14 |- trio.sleep(foo) # TRIO115
61-
14 |+ trio.lowlevel.checkpoint # TRIO115
62-
15 15 | trio.sleep(1) # OK
63-
16 16 | time.sleep(0) # OK
64-
17 17 |
58+
10 10 |
59+
11 11 | trio.sleep(0) # TRIO115
60+
12 12 | foo = 0
61+
13 |- trio.sleep(foo) # TRIO115
62+
13 |+ trio.lowlevel.checkpoint # TRIO115
63+
14 14 | trio.sleep(1) # OK
64+
15 15 | time.sleep(0) # OK
65+
16 16 |
6566

66-
TRIO115.py:18:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
67+
TRIO115.py:17:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
6768
|
68-
16 | time.sleep(0) # OK
69-
17 |
70-
18 | sleep(0) # TRIO115
69+
15 | time.sleep(0) # OK
70+
16 |
71+
17 | sleep(0) # TRIO115
7172
| ^^^^^^^^ TRIO115
72-
19 |
73-
20 | bar = "bar"
73+
18 |
74+
19 | bar = "bar"
7475
|
7576
= help: Replace with `trio.lowlevel.checkpoint()`
7677

7778
Safe fix
78-
15 15 | trio.sleep(1) # OK
79-
16 16 | time.sleep(0) # OK
80-
17 17 |
81-
18 |- sleep(0) # TRIO115
82-
18 |+ trio.lowlevel.checkpoint # TRIO115
83-
19 19 |
84-
20 20 | bar = "bar"
85-
21 21 | trio.sleep(bar)
79+
14 14 | trio.sleep(1) # OK
80+
15 15 | time.sleep(0) # OK
81+
16 16 |
82+
17 |- sleep(0) # TRIO115
83+
17 |+ trio.lowlevel.checkpoint # TRIO115
84+
18 18 |
85+
19 19 | bar = "bar"
86+
20 20 | trio.sleep(bar)
8687

87-
TRIO115.py:24:1: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
88+
TRIO115.py:30:5: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
8889
|
89-
24 | trio.sleep(0) # TRIO115
90-
| ^^^^^^^^^^^^^ TRIO115
91-
|
92-
= help: Replace with `trio.lowlevel.checkpoint()`
93-
94-
Safe fix
95-
21 21 | trio.sleep(bar)
96-
22 22 |
97-
23 23 |
98-
24 |-trio.sleep(0) # TRIO115
99-
24 |+trio.lowlevel.checkpoint # TRIO115
100-
25 25 |
101-
26 26 |
102-
27 27 | def func():
103-
104-
TRIO115.py:28:14: TRIO115 [*] Use `trio.lowlevel.checkpoint()` instead of `trio.sleep(0)`
105-
|
106-
27 | def func():
107-
28 | trio.run(trio.sleep(0)) # TRIO115
108-
| ^^^^^^^^^^^^^ TRIO115
90+
29 | def func():
91+
30 | sleep(0) # TRIO115
92+
| ^^^^^^^^ TRIO115
10993
|
11094
= help: Replace with `trio.lowlevel.checkpoint()`
11195

11296
Safe fix
97+
24 24 | trio.run(trio.sleep(0)) # TRIO115
11398
25 25 |
11499
26 26 |
115-
27 27 | def func():
116-
28 |- trio.run(trio.sleep(0)) # TRIO115
117-
28 |+ trio.run(trio.lowlevel.checkpoint) # TRIO115
100+
27 |-from trio import Event, sleep
101+
27 |+from trio import Event, sleep, lowlevel
102+
28 28 |
103+
29 29 | def func():
104+
30 |- sleep(0) # TRIO115
105+
30 |+ lowlevel.checkpoint # TRIO115
118106

119107

0 commit comments

Comments
 (0)