Allow sys.path modifications between imports (#9047)

## Summary

It's common to interleave a `sys.path` modification between imports at
the top of a file. This is a frequent cause of `# noqa: E402` false
positives, as seen in the ecosystem checks. This PR modifies E402 to
omit such modifications when determining the "import boundary".

(We could consider linting against `sys.path` modifications, but that
should be a separate rule.)

Closes: https://github.com/astral-sh/ruff/issues/5557.
This commit is contained in:
Charlie Marsh 2023-12-07 13:35:55 -05:00 committed by GitHub
parent 96ae9fe685
commit b021ede481
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 110 additions and 22 deletions

View file

@ -0,0 +1,37 @@
use ruff_python_ast::{self as ast, Expr, Stmt};
use crate::SemanticModel;
/// Returns `true` if a [`Stmt`] is a `sys.path` modification, as in:
/// ```python
/// import sys
///
/// sys.path.append("../")
/// ```
pub fn is_sys_path_modification(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(),
[
"sys",
"path",
"append"
| "insert"
| "extend"
| "remove"
| "pop"
| "clear"
| "reverse"
| "sort"
]
)
})
}

View file

@ -1,4 +1,5 @@
pub mod function_type;
pub mod imports;
pub mod logging;
pub mod type_inference;
pub mod typing;