/
unnecessary_builtin_import.rs
107 lines (101 loc) · 2.69 KB
/
unnecessary_builtin_import.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use itertools::Itertools;
use log::error;
use rustpython_ast::{Alias, AliasData, Located};
use rustpython_parser::ast::Stmt;
use crate::ast::types::Range;
use crate::autofix;
use crate::checkers::ast::Checker;
use crate::registry::{Check, CheckKind};
const BUILTINS: &[&str] = &[
"*",
"ascii",
"bytes",
"chr",
"dict",
"filter",
"hex",
"input",
"int",
"isinstance",
"list",
"map",
"max",
"min",
"next",
"object",
"oct",
"open",
"pow",
"range",
"round",
"str",
"super",
"zip",
];
const IO: &[&str] = &["open"];
const SIX_MOVES_BUILTINS: &[&str] = BUILTINS;
const SIX: &[&str] = &["callable", "next"];
const SIX_MOVES: &[&str] = &["filter", "input", "map", "range", "zip"];
/// UP029
pub fn unnecessary_builtin_import(
checker: &mut Checker,
stmt: &Stmt,
module: &str,
names: &[Located<AliasData>],
) {
let deprecated_names = match module {
"builtins" => BUILTINS,
"io" => IO,
"six" => SIX,
"six.moves" => SIX_MOVES,
"six.moves.builtins" => SIX_MOVES_BUILTINS,
_ => return,
};
let mut unused_imports: Vec<&Alias> = vec![];
for alias in names {
if alias.node.asname.is_some() {
continue;
}
if deprecated_names.contains(&alias.node.name.as_str()) {
unused_imports.push(alias);
}
}
if unused_imports.is_empty() {
return;
}
let mut check = Check::new(
CheckKind::UnnecessaryBuiltinImport(
unused_imports
.iter()
.map(|alias| alias.node.name.to_string())
.sorted()
.collect(),
),
Range::from_located(stmt),
);
if checker.patch(check.kind.code()) {
let deleted: Vec<&Stmt> = checker.deletions.iter().map(|node| node.0).collect();
let defined_by = checker.current_stmt();
let defined_in = checker.current_stmt_parent();
let unused_imports: Vec<String> = unused_imports
.iter()
.map(|alias| format!("{module}.{}", alias.node.name))
.collect();
match autofix::helpers::remove_unused_imports(
unused_imports.iter().map(String::as_str),
defined_by.0,
defined_in.map(|node| node.0),
&deleted,
checker.locator,
) {
Ok(fix) => {
if fix.content.is_empty() || fix.content == "pass" {
checker.deletions.insert(defined_by.clone());
}
check.amend(fix);
}
Err(e) => error!("Failed to remove builtin import: {e}"),
}
}
checker.add_check(check);
}