mirror of https://github.com/astral-sh/ruff
Use top-level semantic detection for E402 (#6526)
## Summary Noticed in https://github.com/astral-sh/ruff/pull/6378. Given `import h; import i`, we don't consider `import i` to be a "top-level" import for E402 purposes, which is wrong. Similarly, we _do_ consider `import k` to be a "top-level" import in: ```python if __name__ == "__main__": import j; \ import k ``` Using the semantic detection, rather than relying on newline position, fixes both cases. ## Test Plan `cargo test`
This commit is contained in:
parent
c03e2acadb
commit
b49c80f8c8
|
|
@ -30,3 +30,10 @@ def foo() -> None:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import g
|
import g
|
||||||
|
|
||||||
|
import h; import i
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import j; \
|
||||||
|
import k
|
||||||
|
|
|
||||||
|
|
@ -520,11 +520,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
||||||
pycodestyle::rules::multiple_imports_on_one_line(checker, stmt, names);
|
pycodestyle::rules::multiple_imports_on_one_line(checker, stmt, names);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::ModuleImportNotAtTopOfFile) {
|
if checker.enabled(Rule::ModuleImportNotAtTopOfFile) {
|
||||||
pycodestyle::rules::module_import_not_at_top_of_file(
|
pycodestyle::rules::module_import_not_at_top_of_file(checker, stmt);
|
||||||
checker,
|
|
||||||
stmt,
|
|
||||||
checker.locator,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::GlobalStatement) {
|
if checker.enabled(Rule::GlobalStatement) {
|
||||||
for name in names {
|
for name in names {
|
||||||
|
|
@ -689,11 +685,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
||||||
let module = module.as_deref();
|
let module = module.as_deref();
|
||||||
let level = level.map(|level| level.to_u32());
|
let level = level.map(|level| level.to_u32());
|
||||||
if checker.enabled(Rule::ModuleImportNotAtTopOfFile) {
|
if checker.enabled(Rule::ModuleImportNotAtTopOfFile) {
|
||||||
pycodestyle::rules::module_import_not_at_top_of_file(
|
pycodestyle::rules::module_import_not_at_top_of_file(checker, stmt);
|
||||||
checker,
|
|
||||||
stmt,
|
|
||||||
checker.locator,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::GlobalStatement) {
|
if checker.enabled(Rule::GlobalStatement) {
|
||||||
for name in names {
|
for name in names {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
use ruff_python_ast::{Alias, Ranged, Stmt};
|
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_source_file::Locator;
|
use ruff_python_ast::{Alias, Ranged, Stmt};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
|
|
@ -81,12 +79,8 @@ pub(crate) fn multiple_imports_on_one_line(checker: &mut Checker, stmt: &Stmt, n
|
||||||
}
|
}
|
||||||
|
|
||||||
/// E402
|
/// E402
|
||||||
pub(crate) fn module_import_not_at_top_of_file(
|
pub(crate) fn module_import_not_at_top_of_file(checker: &mut Checker, stmt: &Stmt) {
|
||||||
checker: &mut Checker,
|
if checker.semantic().seen_import_boundary() && checker.semantic().at_top_level() {
|
||||||
stmt: &Stmt,
|
|
||||||
locator: &Locator,
|
|
||||||
) {
|
|
||||||
if checker.semantic().seen_import_boundary() && locator.is_at_start_of_line(stmt.start()) {
|
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(ModuleImportNotAtTopOfFile, stmt.range()));
|
.push(Diagnostic::new(ModuleImportNotAtTopOfFile, stmt.range()));
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,20 @@ E402.py:24:1: E402 Module level import not at top of file
|
||||||
| ^^^^^^^^ E402
|
| ^^^^^^^^ E402
|
||||||
|
|
|
|
||||||
|
|
||||||
|
E402.py:34:1: E402 Module level import not at top of file
|
||||||
|
|
|
||||||
|
32 | import g
|
||||||
|
33 |
|
||||||
|
34 | import h; import i
|
||||||
|
| ^^^^^^^^ E402
|
||||||
|
|
|
||||||
|
|
||||||
|
E402.py:34:11: E402 Module level import not at top of file
|
||||||
|
|
|
||||||
|
32 | import g
|
||||||
|
33 |
|
||||||
|
34 | import h; import i
|
||||||
|
| ^^^^^^^^ E402
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue