Skip to content

Commit c594fb8

Browse files
committed
Address code review.
Move the main rule implementation to just below the `BlockingPathMethodInAsyncFunction` implementation.
1 parent c39cc00 commit c594fb8

File tree

1 file changed

+70
-71
lines changed

1 file changed

+70
-71
lines changed

crates/ruff_linter/src/rules/flake8_async/rules/blocking_path_methods.rs

Lines changed: 70 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,76 @@ impl Violation for BlockingPathMethodInAsyncFunction {
6060
}
6161
}
6262

63+
/// ASYNC240
64+
pub(crate) fn blocking_os_path(checker: &Checker, call: &ExprCall) {
65+
let semantic = checker.semantic();
66+
if !semantic.in_async_context() {
67+
return;
68+
}
69+
70+
// Check if an expression is calling I/O related os.path method.
71+
// Just initializing pathlib.Path object is OK, we can return
72+
// early in that scenario.
73+
if let Some(qualified_name) = semantic.resolve_qualified_name(call.func.as_ref()) {
74+
let segments = qualified_name.segments();
75+
if !matches!(segments, ["os", "path", _]) {
76+
return;
77+
}
78+
79+
let Some(os_path_method) = segments.last() else {
80+
return;
81+
};
82+
83+
if maybe_calling_io_operation(os_path_method) {
84+
checker.report_diagnostic(
85+
BlockingPathMethodInAsyncFunction {
86+
path_library: "os.path".to_string(),
87+
},
88+
call.func.range(),
89+
);
90+
}
91+
return;
92+
}
93+
94+
let Some(ast::ExprAttribute { value, attr, .. }) = call.func.as_attribute_expr() else {
95+
return;
96+
};
97+
98+
if !maybe_calling_io_operation(attr.id.as_str()) {
99+
return;
100+
}
101+
102+
// Check if an expression is a pathlib.Path constructor that directly
103+
// calls an I/O method.
104+
if PathlibPathChecker::match_initializer(value, semantic) {
105+
checker.report_diagnostic(
106+
BlockingPathMethodInAsyncFunction {
107+
path_library: "pathlib.Path".to_string(),
108+
},
109+
call.func.range(),
110+
);
111+
return;
112+
}
113+
114+
// Lastly, check if a variable is a pathlib.Path instance and it's
115+
// calling an I/O method.
116+
let Some(name) = value.as_name_expr() else {
117+
return;
118+
};
119+
120+
let Some(binding) = semantic.only_binding(name).map(|id| semantic.binding(id)) else {
121+
return;
122+
};
123+
124+
if check_type::<PathlibPathChecker>(binding, semantic) {
125+
checker.report_diagnostic(
126+
BlockingPathMethodInAsyncFunction {
127+
path_library: "pathlib.Path".to_string(),
128+
},
129+
call.func.range(),
130+
);
131+
}
132+
}
63133
struct PathlibPathChecker;
64134

65135
impl PathlibPathChecker {
@@ -173,74 +243,3 @@ fn maybe_calling_io_operation(attr: &str) -> bool {
173243
| "with_suffix"
174244
)
175245
}
176-
177-
/// ASYNC240
178-
pub(crate) fn blocking_os_path(checker: &Checker, call: &ExprCall) {
179-
let semantic = checker.semantic();
180-
if !semantic.in_async_context() {
181-
return;
182-
}
183-
184-
// Check if an expression is calling I/O related os.path method.
185-
// Just initializing pathlib.Path object is OK, we can return
186-
// early in that scenario.
187-
if let Some(qualified_name) = semantic.resolve_qualified_name(call.func.as_ref()) {
188-
let segments = qualified_name.segments();
189-
if !matches!(segments, ["os", "path", _]) {
190-
return;
191-
}
192-
193-
let Some(os_path_method) = segments.last() else {
194-
return;
195-
};
196-
197-
if maybe_calling_io_operation(os_path_method) {
198-
checker.report_diagnostic(
199-
BlockingPathMethodInAsyncFunction {
200-
path_library: "os.path".to_string(),
201-
},
202-
call.func.range(),
203-
);
204-
}
205-
return;
206-
}
207-
208-
let Some(ast::ExprAttribute { value, attr, .. }) = call.func.as_attribute_expr() else {
209-
return;
210-
};
211-
212-
if !maybe_calling_io_operation(attr.id.as_str()) {
213-
return;
214-
}
215-
216-
// Check if an expression is a pathlib.Path constructor that directly
217-
// calls an I/O method.
218-
if PathlibPathChecker::match_initializer(value, semantic) {
219-
checker.report_diagnostic(
220-
BlockingPathMethodInAsyncFunction {
221-
path_library: "pathlib.Path".to_string(),
222-
},
223-
call.func.range(),
224-
);
225-
return;
226-
}
227-
228-
// Lastly, check if a variable is a pathlib.Path instance and it's
229-
// calling an I/O method.
230-
let Some(name) = value.as_name_expr() else {
231-
return;
232-
};
233-
234-
let Some(binding) = semantic.only_binding(name).map(|id| semantic.binding(id)) else {
235-
return;
236-
};
237-
238-
if check_type::<PathlibPathChecker>(binding, semantic) {
239-
checker.report_diagnostic(
240-
BlockingPathMethodInAsyncFunction {
241-
path_library: "pathlib.Path".to_string(),
242-
},
243-
call.func.range(),
244-
);
245-
}
246-
}

0 commit comments

Comments
 (0)