0
# Reorder Python Imports
1
2
A command-line tool and Python library for automatically reordering Python imports using static analysis. Unlike similar tools like `isort`, it emphasizes static analysis over configuration, organizing imports into three distinct sections (standard library, third-party, first-party) while enforcing consistent ordering and splitting multi-import statements to reduce merge conflicts.
3
4
## Package Information
5
6
- **Package Name**: reorder-python-imports
7
- **Package Type**: pypi
8
- **Language**: Python
9
- **Installation**: `pip install reorder-python-imports`
10
- **Requirements**: Python 3.9+
11
12
## Core Imports
13
14
```python
15
from reorder_python_imports import fix_file_contents, main
16
```
17
18
For advanced usage with replacement and removal rules:
19
20
```python
21
from reorder_python_imports import (
22
fix_file_contents,
23
Replacements,
24
parse_imports,
25
apply_import_sorting,
26
partition_source
27
)
28
```
29
30
## Basic Usage
31
32
### Command Line Usage
33
34
```bash
35
# Reorder imports in specific files
36
reorder-python-imports file1.py file2.py
37
38
# Add an import to all processed files
39
reorder-python-imports --add-import 'from __future__ import annotations' *.py
40
41
# Remove obsolete imports for Python 3.9+
42
reorder-python-imports --py39-plus *.py
43
44
# Replace deprecated imports
45
reorder-python-imports --replace-import 'old.module::new.module' *.py
46
```
47
48
### Library Usage
49
50
```python
51
from reorder_python_imports import fix_file_contents
52
53
# Read a Python file
54
with open('example.py', 'r') as f:
55
original_contents = f.read()
56
57
# Reorder imports
58
reordered_contents = fix_file_contents(original_contents)
59
60
# Write back if changed
61
if reordered_contents != original_contents:
62
with open('example.py', 'w') as f:
63
f.write(reordered_contents)
64
```
65
66
## Capabilities
67
68
### File Content Processing
69
70
Core functionality for processing Python file contents and reordering imports.
71
72
```python { .api }
73
def fix_file_contents(
74
contents: str,
75
*,
76
to_add: tuple[str, ...] = (),
77
to_remove: set[tuple[str, ...]],
78
to_replace: Replacements,
79
settings: Settings = Settings()
80
) -> str:
81
"""
82
Reorder imports in Python file contents.
83
84
Args:
85
contents: Python source code as string
86
to_add: Tuple of import strings to add
87
to_remove: Set of import tuples to remove (required)
88
to_replace: Replacements object for import substitutions (required)
89
settings: classify-imports Settings object for sorting behavior
90
91
Returns:
92
Modified source code with reordered imports
93
"""
94
```
95
96
### Source Code Parsing
97
98
Functions for parsing and analyzing Python source code structure.
99
100
```python { .api }
101
def partition_source(src: str) -> tuple[str, list[str], str, str]:
102
"""
103
Split Python source into pre-import, import, post-import sections.
104
105
Args:
106
src: Python source code string
107
108
Returns:
109
Tuple of (pre_import_code, import_lines, post_import_code, newline_char)
110
"""
111
112
def parse_imports(
113
imports: list[str],
114
*,
115
to_add: tuple[str, ...] = ()
116
) -> list[tuple[str, Import | ImportFrom]]:
117
"""
118
Parse import strings into Import/ImportFrom objects.
119
120
Args:
121
imports: List of import statement strings
122
to_add: Additional imports to include in parsing
123
124
Returns:
125
List of (import_string, import_object) tuples
126
"""
127
```
128
129
### Import Processing
130
131
Functions for manipulating and processing parsed imports.
132
133
```python { .api }
134
def replace_imports(
135
imports: list[tuple[str, Import | ImportFrom]],
136
to_replace: Replacements
137
) -> list[tuple[str, Import | ImportFrom]]:
138
"""
139
Apply replacement rules to parsed imports.
140
141
Args:
142
imports: List of (import_string, import_object) tuples
143
to_replace: Replacements object containing substitution rules
144
145
Returns:
146
Modified import list with replacements applied
147
"""
148
149
def remove_duplicated_imports(
150
imports: list[tuple[str, Import | ImportFrom]],
151
*,
152
to_remove: set[tuple[str, ...]]
153
) -> list[tuple[str, Import | ImportFrom]]:
154
"""
155
Remove duplicate and specified imports.
156
157
Args:
158
imports: List of (import_string, import_object) tuples
159
to_remove: Set of import tuples to remove
160
161
Returns:
162
Deduplicated import list
163
"""
164
165
def apply_import_sorting(
166
imports: list[tuple[str, Import | ImportFrom]],
167
settings: Settings = Settings()
168
) -> list[str]:
169
"""
170
Sort imports according to classification settings.
171
172
Args:
173
imports: List of (import_string, import_object) tuples
174
settings: classify-imports Settings for sorting behavior
175
176
Returns:
177
List of sorted import strings
178
"""
179
```
180
181
### Command Line Interface
182
183
Entry point for command-line usage with argument processing.
184
185
```python { .api }
186
def main(argv: Sequence[str] | None = None) -> int:
187
"""
188
Command-line entry point for the reorder tool.
189
190
Args:
191
argv: Command line arguments (uses sys.argv if None)
192
193
Returns:
194
Exit code: 0 for success, non-zero for changes made or errors
195
"""
196
```
197
198
### Import Replacement Rules
199
200
Configuration classes and constants for import modernization.
201
202
```python { .api }
203
class Replacements:
204
"""Container for import replacement mappings."""
205
exact: dict[tuple[str, str], str] # Maps (module, attribute) to new_module
206
mods: dict[str, str] # Maps old_module to new_module
207
208
@classmethod
209
def make(cls, args: list[tuple[str, str, str]]) -> Replacements:
210
"""
211
Create Replacements from argument list.
212
213
Args:
214
args: List of (old_module, attribute, new_module) tuples
215
216
Returns:
217
Replacements object
218
"""
219
220
# Version-specific import modernization rules
221
REMOVALS: dict[tuple[int, ...], set[str]]
222
REPLACES: dict[tuple[int, ...], set[str]]
223
```
224
225
### Token Processing
226
227
Enums and constants for low-level source code analysis.
228
229
```python { .api }
230
class CodeType(enum.Enum):
231
"""Code section type classifier."""
232
PRE_IMPORT_CODE = "PRE_IMPORT_CODE"
233
IMPORT = "IMPORT"
234
NON_CODE = "NON_CODE"
235
CODE = "CODE"
236
237
class Tok(enum.Enum):
238
"""Token types for import parsing."""
239
IMPORT = "IMPORT"
240
STRING = "STRING"
241
NEWLINE = "NEWLINE"
242
ERROR = "ERROR"
243
244
# Token patterns for parsing Python source
245
TOKENIZE: tuple[tuple[Tok, re.Pattern[str]], ...]
246
```
247
248
## Common Usage Patterns
249
250
### Adding Imports
251
252
```python
253
from reorder_python_imports import fix_file_contents
254
255
# Add future imports to modernize code
256
contents = fix_file_contents(
257
source_code,
258
to_add=('from __future__ import annotations',)
259
)
260
```
261
262
### Import Replacement
263
264
```python
265
from reorder_python_imports import fix_file_contents, Replacements
266
267
# Replace deprecated imports
268
replacements = Replacements.make([
269
('collections', 'Mapping', 'collections.abc'),
270
('typing', 'Dict', 'builtins') # Use dict instead of typing.Dict
271
])
272
273
contents = fix_file_contents(
274
source_code,
275
to_replace=replacements
276
)
277
```
278
279
### Advanced Processing Pipeline
280
281
```python
282
from reorder_python_imports import (
283
partition_source,
284
parse_imports,
285
remove_duplicated_imports,
286
apply_import_sorting
287
)
288
289
# Manual processing pipeline
290
pre_import, imports, post_import, nl = partition_source(source_code)
291
parsed_imports = parse_imports(imports)
292
deduplicated = remove_duplicated_imports(parsed_imports, to_remove=set())
293
sorted_imports = apply_import_sorting(deduplicated)
294
295
# Reconstruct file
296
reordered = pre_import + ''.join(sorted_imports) + post_import
297
```
298
299
## Import Style Rules
300
301
The tool enforces these specific formatting rules to minimize merge conflicts:
302
303
1. **Three-section organization**: Standard library, third-party, first-party imports
304
2. **Import order**: `import` statements before `from` statements within each section
305
3. **Split multi-imports**: `from module import a, b` becomes separate lines
306
4. **Duplicate removal**: Automatically removes redundant import statements
307
5. **One import per line**: Reduces merge conflicts in collaborative development
308
309
## Error Handling
310
311
The tool handles common edge cases:
312
313
- **Syntax errors**: Invalid Python syntax in import statements
314
- **Circular imports**: Does not modify files with import cycle issues
315
- **Mixed line endings**: Preserves original file line ending style
316
- **Encoding issues**: Handles files with different text encodings
317
318
Import processing stops at the first non-import, non-comment, non-whitespace line or when encountering a `# noreorder` comment.