0
# Import Detection and Analysis
1
2
Functions for detecting and handling Python standard library imports, package names, and import patterns. These utilities ensure safe removal of unused imports while preserving necessary functionality and side effects.
3
4
## Capabilities
5
6
### Standard Library Detection
7
8
Functions for identifying Python standard library modules to enable safe automatic removal.
9
10
```python { .api }
11
def standard_package_names() -> Iterable[str]:
12
"""
13
Yields standard Python module names from the standard library.
14
15
Discovers standard library modules by examining the Python installation
16
paths and filtering out internal/private modules and platform-specific extensions.
17
18
Returns:
19
Iterator of standard library module names safe for automatic removal
20
"""
21
```
22
23
```python { .api }
24
def standard_paths() -> Iterable[str]:
25
"""
26
Yields filesystem paths to standard Python modules.
27
28
Returns paths from the Python installation including stdlib and platstdlib
29
directories, used internally by standard_package_names().
30
31
Returns:
32
Iterator of filesystem paths containing standard library modules
33
"""
34
```
35
36
### Import Statement Analysis
37
38
Functions for parsing and analyzing import statements to understand their structure and content.
39
40
```python { .api }
41
def extract_package_name(line: str) -> str | None:
42
"""
43
Extracts the package name from an import statement line.
44
45
Parses various import statement formats to identify the root package name,
46
handling both 'import' and 'from...import' statements.
47
48
Args:
49
line: Python source line containing an import statement
50
51
Returns:
52
Root package name, or None if line is not a valid import statement
53
"""
54
```
55
56
```python { .api }
57
def multiline_import(line: str, previous_line: str = "") -> bool:
58
"""
59
Returns True if the import statement spans multiple lines.
60
61
Detects multiline import patterns including parenthesized imports and
62
backslash continuations to handle complex import processing.
63
64
Args:
65
line: Current line to analyze
66
previous_line: Previous line for context (default empty string)
67
68
Returns:
69
True if this line is part of a multiline import statement
70
"""
71
```
72
73
```python { .api }
74
def multiline_statement(line: str, previous_line: str = "") -> bool:
75
"""
76
Returns True if this line is part of any multiline statement.
77
78
More general than multiline_import, detects any Python statement that
79
continues across multiple lines using parentheses or backslashes.
80
81
Args:
82
line: Current line to analyze
83
previous_line: Previous line for context (default empty string)
84
85
Returns:
86
True if this line is part of a multiline statement
87
"""
88
```
89
90
### Import Processing and Filtering
91
92
Functions for processing and transforming import statements during cleanup.
93
94
```python { .api }
95
def filter_from_import(line: str, unused_module: Iterable[str]) -> str:
96
"""
97
Removes unused imports from 'from module import ...' statements.
98
99
Parses "from module import a, b, c" statements and removes only the
100
unused imports while preserving the rest, maintaining proper syntax.
101
102
Args:
103
line: Source line containing a 'from...import' statement
104
unused_module: Names of unused imported items to remove
105
106
Returns:
107
Modified import line with unused imports removed, or empty string if all removed
108
"""
109
```
110
111
```python { .api }
112
def break_up_import(line: str) -> str:
113
"""
114
Returns import statement with each import on a separate line.
115
116
Converts "import a, b, c" into separate "import a", "import b", "import c"
117
statements to make individual import removal easier.
118
119
Args:
120
line: Import statement line with multiple imports
121
122
Returns:
123
Multi-line string with each import on its own line
124
"""
125
```
126
127
## Constants and Predefined Sets
128
129
Important constants that control import detection and removal behavior:
130
131
```python { .api }
132
SAFE_IMPORTS: frozenset[str]
133
```
134
Computed set of imports that are safe to remove automatically (combines standard library detection).
135
136
```python { .api }
137
IMPORTS_WITH_SIDE_EFFECTS: set[str]
138
```
139
Set of modules known to have side effects when imported: `{"antigravity", "rlcompleter", "this"}`.
140
141
```python { .api }
142
BINARY_IMPORTS: set[str]
143
```
144
Set of modules that may be built into CPython and don't have separate files.
145
146
## Usage Examples
147
148
### Standard Library Detection
149
150
```python
151
import autoflake
152
153
# Get all standard library module names
154
stdlib_modules = list(autoflake.standard_package_names())
155
print(f"Found {len(stdlib_modules)} standard library modules")
156
157
# Check if a specific module is in the standard library
158
if "os" in stdlib_modules:
159
print("'os' is a standard library module")
160
161
# Safe imports (standard library modules safe for automatic removal)
162
safe_modules = autoflake.SAFE_IMPORTS
163
print(f"Safe to remove: {len(safe_modules)} modules")
164
```
165
166
### Import Statement Analysis
167
168
```python
169
import autoflake
170
171
# Extract package names from various import formats
172
examples = [
173
"import os.path",
174
"from django.conf import settings",
175
"import requests.adapters",
176
"from . import utils"
177
]
178
179
for line in examples:
180
package = autoflake.extract_package_name(line)
181
print(f"'{line}' -> package: '{package}'")
182
```
183
184
### Multiline Import Detection
185
186
```python
187
import autoflake
188
189
# Detect multiline imports
190
lines = [
191
"from django.contrib.auth import (",
192
" User,",
193
" Group,",
194
" Permission",
195
")"
196
]
197
198
for i, line in enumerate(lines):
199
prev_line = lines[i-1] if i > 0 else ""
200
is_multiline = autoflake.multiline_import(line, prev_line)
201
print(f"Line {i}: '{line.strip()}' - multiline: {is_multiline}")
202
```
203
204
### Import Filtering and Processing
205
206
```python
207
import autoflake
208
209
# Filter unused imports from 'from...import' statements
210
line = "from django.contrib.auth import User, Group, Permission"
211
unused = ["Group", "Permission"] # These are unused
212
213
filtered = autoflake.filter_from_import(line, unused)
214
print(f"Original: {line}")
215
print(f"Filtered: {filtered}")
216
# Result: "from django.contrib.auth import User"
217
218
# Break up multiple imports
219
multi_import = "import os, sys, json, unused_module"
220
broken_up = autoflake.break_up_import(multi_import)
221
print("Broken up imports:")
222
print(broken_up)
223
```
224
225
### Side Effect Detection
226
227
```python
228
import autoflake
229
230
# Check for imports with known side effects
231
def is_side_effect_import(module_name):
232
"""Check if a module has known side effects."""
233
return module_name in autoflake.IMPORTS_WITH_SIDE_EFFECTS
234
235
# These imports should not be automatically removed
236
test_modules = ["antigravity", "os", "rlcompleter", "sys"]
237
for module in test_modules:
238
has_side_effects = is_side_effect_import(module)
239
print(f"'{module}' has side effects: {has_side_effects}")
240
```
241
242
### Custom Import Analysis
243
244
```python
245
import autoflake
246
import ast
247
248
def analyze_import_safety(source_code):
249
"""Analyze which imports in source code are safe to remove."""
250
251
# Get unused imports from pyflakes
252
messages = list(autoflake.check(source_code))
253
unused_imports = {}
254
255
for line_num, module_name in autoflake.unused_import_module_name(messages):
256
unused_imports[line_num] = module_name
257
258
# Analyze safety
259
results = {}
260
for line_num, module_name in unused_imports.items():
261
is_stdlib = module_name in autoflake.SAFE_IMPORTS
262
has_side_effects = module_name in autoflake.IMPORTS_WITH_SIDE_EFFECTS
263
264
results[line_num] = {
265
"module": module_name,
266
"is_stdlib": is_stdlib,
267
"has_side_effects": has_side_effects,
268
"safe_to_remove": is_stdlib and not has_side_effects
269
}
270
271
return results
272
273
# Example usage
274
source = '''
275
import os
276
import sys
277
import antigravity
278
import requests # Third-party
279
import unused_local_module
280
'''
281
282
analysis = analyze_import_safety(source)
283
for line_num, info in analysis.items():
284
print(f"Line {line_num}: {info}")
285
```
286
287
### Integration with Code Processing
288
289
```python
290
import autoflake
291
292
def smart_import_removal(source_code, config):
293
"""Remove imports intelligently based on configuration and safety."""
294
295
# Start with conservative settings
296
processing_config = {
297
"remove_all_unused_imports": False, # Only standard library by default
298
"additional_imports": config.get("additional_safe_modules", [])
299
}
300
301
# If user explicitly enables aggressive removal, add checks
302
if config.get("remove_all_unused_imports", False):
303
# Get list of unused modules
304
messages = list(autoflake.check(source_code))
305
unused_modules = [module for _, module in autoflake.unused_import_module_name(messages)]
306
307
# Filter out side-effect modules
308
safe_unused = [
309
module for module in unused_modules
310
if module not in autoflake.IMPORTS_WITH_SIDE_EFFECTS
311
]
312
313
print(f"Would remove {len(safe_unused)} unused imports")
314
print(f"Preserving {len(unused_modules) - len(safe_unused)} imports with side effects")
315
316
processing_config["remove_all_unused_imports"] = True
317
318
return autoflake.fix_code(source_code, **processing_config)
319
```