mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-17 00:50:16 +00:00
Allow matplotlib.use
calls to intersperse imports (#9094)
This PR allows `matplotlib.use` calls to intersperse imports without triggering `E402`. This is a pragmatic choice as it's common to require `matplotlib.use` calls prior to importing from within `matplotlib` itself. Closes https://github.com/astral-sh/ruff/issues/9091.
This commit is contained in:
parent
07380e0657
commit
f452bf8cad
5 changed files with 77 additions and 32 deletions
|
@ -24,21 +24,27 @@ sys.path.insert(0, "some/path")
|
||||||
|
|
||||||
import f
|
import f
|
||||||
|
|
||||||
__some__magic = 1
|
import matplotlib
|
||||||
|
|
||||||
|
matplotlib.use("Agg")
|
||||||
|
|
||||||
import g
|
import g
|
||||||
|
|
||||||
|
__some__magic = 1
|
||||||
|
|
||||||
def foo() -> None:
|
|
||||||
import h
|
import h
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def foo() -> None:
|
||||||
import i
|
import i
|
||||||
|
|
||||||
import j; import k
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import j
|
||||||
|
|
||||||
|
import k; import l
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import l; \
|
import m; \
|
||||||
import m
|
import n
|
||||||
|
|
|
@ -306,6 +306,7 @@ where
|
||||||
if !(self.semantic.seen_import_boundary()
|
if !(self.semantic.seen_import_boundary()
|
||||||
|| helpers::is_assignment_to_a_dunder(stmt)
|
|| helpers::is_assignment_to_a_dunder(stmt)
|
||||||
|| helpers::in_nested_block(self.semantic.current_statements())
|
|| helpers::in_nested_block(self.semantic.current_statements())
|
||||||
|
|| imports::is_matplotlib_activation(stmt, self.semantic())
|
||||||
|| self.settings.preview.is_enabled()
|
|| self.settings.preview.is_enabled()
|
||||||
&& imports::is_sys_path_modification(stmt, self.semantic()))
|
&& imports::is_sys_path_modification(stmt, self.semantic()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,30 +8,50 @@ E402.py:25:1: E402 Module level import not at top of file
|
||||||
25 | import f
|
25 | import f
|
||||||
| ^^^^^^^^ E402
|
| ^^^^^^^^ E402
|
||||||
26 |
|
26 |
|
||||||
27 | __some__magic = 1
|
27 | import matplotlib
|
||||||
|
|
|
|
||||||
|
|
||||||
E402.py:29:1: E402 Module level import not at top of file
|
E402.py:27:1: E402 Module level import not at top of file
|
||||||
|
|
|
|
||||||
27 | __some__magic = 1
|
25 | import f
|
||||||
|
26 |
|
||||||
|
27 | import matplotlib
|
||||||
|
| ^^^^^^^^^^^^^^^^^ E402
|
||||||
28 |
|
28 |
|
||||||
29 | import g
|
29 | matplotlib.use("Agg")
|
||||||
|
|
|
||||||
|
|
||||||
|
E402.py:31:1: E402 Module level import not at top of file
|
||||||
|
|
|
||||||
|
29 | matplotlib.use("Agg")
|
||||||
|
30 |
|
||||||
|
31 | import g
|
||||||
|
| ^^^^^^^^ E402
|
||||||
|
32 |
|
||||||
|
33 | __some__magic = 1
|
||||||
|
|
|
||||||
|
|
||||||
|
E402.py:35:1: E402 Module level import not at top of file
|
||||||
|
|
|
||||||
|
33 | __some__magic = 1
|
||||||
|
34 |
|
||||||
|
35 | import h
|
||||||
| ^^^^^^^^ E402
|
| ^^^^^^^^ E402
|
||||||
|
|
|
|
||||||
|
|
||||||
E402.py:39:1: E402 Module level import not at top of file
|
E402.py:45:1: E402 Module level import not at top of file
|
||||||
|
|
|
|
||||||
37 | import i
|
43 | import j
|
||||||
38 |
|
44 |
|
||||||
39 | import j; import k
|
45 | import k; import l
|
||||||
| ^^^^^^^^ E402
|
| ^^^^^^^^ E402
|
||||||
|
|
|
|
||||||
|
|
||||||
E402.py:39:11: E402 Module level import not at top of file
|
E402.py:45:11: E402 Module level import not at top of file
|
||||||
|
|
|
|
||||||
37 | import i
|
43 | import j
|
||||||
38 |
|
44 |
|
||||||
39 | import j; import k
|
45 | import k; import l
|
||||||
| ^^^^^^^^ E402
|
| ^^^^^^^^ E402
|
||||||
|
|
|
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
---
|
---
|
||||||
E402.py:29:1: E402 Module level import not at top of file
|
E402.py:35:1: E402 Module level import not at top of file
|
||||||
|
|
|
|
||||||
27 | __some__magic = 1
|
33 | __some__magic = 1
|
||||||
28 |
|
34 |
|
||||||
29 | import g
|
35 | import h
|
||||||
| ^^^^^^^^ E402
|
| ^^^^^^^^ E402
|
||||||
|
|
|
|
||||||
|
|
||||||
E402.py:39:1: E402 Module level import not at top of file
|
E402.py:45:1: E402 Module level import not at top of file
|
||||||
|
|
|
|
||||||
37 | import i
|
43 | import j
|
||||||
38 |
|
44 |
|
||||||
39 | import j; import k
|
45 | import k; import l
|
||||||
| ^^^^^^^^ E402
|
| ^^^^^^^^ E402
|
||||||
|
|
|
|
||||||
|
|
||||||
E402.py:39:11: E402 Module level import not at top of file
|
E402.py:45:11: E402 Module level import not at top of file
|
||||||
|
|
|
|
||||||
37 | import i
|
43 | import j
|
||||||
38 |
|
44 |
|
||||||
39 | import j; import k
|
45 | import k; import l
|
||||||
| ^^^^^^^^ E402
|
| ^^^^^^^^ E402
|
||||||
|
|
|
|
||||||
|
|
||||||
|
|
|
@ -35,3 +35,21 @@ pub fn is_sys_path_modification(stmt: &Stmt, semantic: &SemanticModel) -> bool {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if a [`Stmt`] is a `matplotlib.use` activation, as in:
|
||||||
|
/// ```python
|
||||||
|
/// import matplotlib
|
||||||
|
///
|
||||||
|
/// matplotlib.use("Agg")
|
||||||
|
/// ```
|
||||||
|
pub fn is_matplotlib_activation(stmt: &Stmt, semantic: &SemanticModel) -> bool {
|
||||||
|
let Stmt::Expr(ast::StmtExpr { value, range: _ }) = stmt else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
semantic
|
||||||
|
.resolve_call_path(func.as_ref())
|
||||||
|
.is_some_and(|call_path| matches!(call_path.as_slice(), ["matplotlib", "use"]))
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue