|
| 1 | +use ruff_python_ast::helpers::map_subscript; |
1 | 2 | use ruff_python_ast::{self as ast, Expr, Stmt};
|
2 | 3 |
|
3 | 4 | use crate::SemanticModel;
|
@@ -36,6 +37,50 @@ pub fn is_sys_path_modification(stmt: &Stmt, semantic: &SemanticModel) -> bool {
|
36 | 37 | })
|
37 | 38 | }
|
38 | 39 |
|
| 40 | +/// Returns `true` if a [`Stmt`] is an `os.environ` modification, as in: |
| 41 | +/// ```python |
| 42 | +/// import os |
| 43 | +/// |
| 44 | +/// os.environ["CUDA_VISIBLE_DEVICES"] = "4" |
| 45 | +/// ``` |
| 46 | +pub fn is_os_environ_modification(stmt: &Stmt, semantic: &SemanticModel) -> bool { |
| 47 | + match stmt { |
| 48 | + Stmt::Expr(ast::StmtExpr { value, .. }) => match value.as_ref() { |
| 49 | + Expr::Call(ast::ExprCall { func, .. }) => semantic |
| 50 | + .resolve_call_path(func.as_ref()) |
| 51 | + .is_some_and(|call_path| { |
| 52 | + matches!( |
| 53 | + call_path.as_slice(), |
| 54 | + ["os", "putenv" | "unsetenv"] |
| 55 | + | [ |
| 56 | + "os", |
| 57 | + "environ", |
| 58 | + "update" | "pop" | "clear" | "setdefault" | "popitem" |
| 59 | + ] |
| 60 | + ) |
| 61 | + }), |
| 62 | + _ => false, |
| 63 | + }, |
| 64 | + Stmt::Delete(ast::StmtDelete { targets, .. }) => targets.iter().any(|target| { |
| 65 | + semantic |
| 66 | + .resolve_call_path(map_subscript(target)) |
| 67 | + .is_some_and(|call_path| matches!(call_path.as_slice(), ["os", "environ"])) |
| 68 | + }), |
| 69 | + Stmt::Assign(ast::StmtAssign { targets, .. }) => targets.iter().any(|target| { |
| 70 | + semantic |
| 71 | + .resolve_call_path(map_subscript(target)) |
| 72 | + .is_some_and(|call_path| matches!(call_path.as_slice(), ["os", "environ"])) |
| 73 | + }), |
| 74 | + Stmt::AnnAssign(ast::StmtAnnAssign { target, .. }) => semantic |
| 75 | + .resolve_call_path(map_subscript(target)) |
| 76 | + .is_some_and(|call_path| matches!(call_path.as_slice(), ["os", "environ"])), |
| 77 | + Stmt::AugAssign(ast::StmtAugAssign { target, .. }) => semantic |
| 78 | + .resolve_call_path(map_subscript(target)) |
| 79 | + .is_some_and(|call_path| matches!(call_path.as_slice(), ["os", "environ"])), |
| 80 | + _ => false, |
| 81 | + } |
| 82 | +} |
| 83 | + |
39 | 84 | /// Returns `true` if a [`Stmt`] is a `matplotlib.use` activation, as in:
|
40 | 85 | /// ```python
|
41 | 86 | /// import matplotlib
|
|
0 commit comments