0
# flake8-isort
1
2
A flake8 plugin that integrates with isort to enforce consistent import ordering in Python code. This plugin checks if imports in Python files are sorted according to isort configuration and reports various import-related style violations including wrong import positions, missing configuration, incorrect blank lines, and missing imports.
3
4
## Package Information
5
6
- **Package Name**: flake8-isort
7
- **Language**: Python
8
- **Installation**: `pip install flake8-isort`
9
- **Dependencies**: flake8, isort >= 4.3.5, <6
10
11
## Core Imports
12
13
The plugin is automatically discovered by flake8 through entry points - no direct imports needed:
14
15
```python
16
# No direct imports required - plugin auto-discovery via flake8
17
```
18
19
For testing or custom usage, the main class can be imported:
20
21
```python
22
from flake8_isort import Flake8Isort
23
```
24
25
## Basic Usage
26
27
After installation, flake8-isort works automatically with flake8:
28
29
```bash
30
# Install the plugin
31
pip install flake8-isort
32
33
# Run flake8 - plugin automatically checks import sorting
34
flake8 myproject/
35
36
# Enable specific error codes if using --select
37
flake8 --select=E,W,I myproject/
38
39
# Show detailed traceback when imports are wrong
40
flake8 --isort-show-traceback myproject/
41
```
42
43
Configure isort behavior through `.isort.cfg`, `setup.cfg`, or `pyproject.toml`:
44
45
```ini
46
# .isort.cfg
47
[settings]
48
line_length = 88
49
multi_line_output = 3
50
include_trailing_comma = true
51
force_grid_wrap = 0
52
combine_as_imports = true
53
```
54
55
## Architecture
56
57
The plugin employs a sophisticated multi-version compatibility architecture to support both legacy and modern isort versions:
58
59
- **Dynamic Class Selection**: `Flake8Isort` automatically selects between `Flake8Isort5` (isort >=5) and `Flake8Isort4` (isort <5) based on API availability
60
- **Base Class Pattern**: `Flake8IsortBase` provides shared functionality including error message constants and configuration handling
61
- **Version-Specific Processing**: Each implementation class handles isort's different APIs and output formats appropriately
62
- **flake8 Integration**: Uses setuptools entry points for automatic plugin discovery and registration with the `I00` error code prefix
63
64
This architecture ensures seamless operation across different isort versions while maintaining consistent error reporting and configuration handling.
65
66
## Capabilities
67
68
### Plugin Registration
69
70
The plugin registers with flake8 through entry points and provides error checking for import sorting violations.
71
72
```python { .api }
73
# Entry point registration (automatic)
74
# flake8.extension: I00 = flake8_isort:Flake8Isort
75
```
76
77
### Main Plugin Class
78
79
The primary plugin class that flake8 instantiates, which is dynamically assigned to the appropriate implementation.
80
81
```python { .api }
82
# Dynamic class alias - automatically selects implementation based on isort version
83
Flake8Isort = Flake8Isort5 if hasattr(isort, 'api') else Flake8Isort4
84
85
# The actual implementation depends on isort version:
86
# - For isort >=5: Uses Flake8Isort5 with modern isort.api
87
# - For isort <5: Uses Flake8Isort4 with legacy isort.SortImports
88
```
89
90
**Note**: `Flake8Isort` is not a standalone class but an alias that points to either `Flake8Isort5` or `Flake8Isort4` based on the installed isort version. This provides backward compatibility while using the most appropriate API for the installed isort version.
91
92
### Base Plugin Class
93
94
Abstract base class containing shared functionality for different isort versions.
95
96
```python { .api }
97
from typing import List, Optional, Union, Iterator, Tuple, Type, Any
98
from ast import AST
99
from io import StringIO
100
101
class Flake8IsortBase:
102
"""
103
Abstract base class for isort integration with shared error messages and configuration.
104
105
Class Attributes:
106
name (str): Plugin name 'flake8_isort'
107
version (str): Plugin version '5.0.3' (Note: hardcoded in class as '5.0.1')
108
isort_unsorted (str): Error message for I001 - 'isort found an import in the wrong position'
109
no_config_msg (str): Error message for I002 - 'no configuration found (.isort.cfg or [isort] in configs)'
110
isort_blank_req (str): Error message for I003 - 'isort expected 1 blank line in imports, found 0'
111
isort_blank_unexp (str): Error message for I004 - 'isort found an unexpected blank line in imports'
112
isort_add_unexp (str): Error message for I005 - 'isort found an unexpected missing import'
113
show_traceback (bool): Whether to show full traceback (defaults to False)
114
stdin_display_name (Optional[str]): Display name for stdin processing (defaults to None)
115
search_current (bool): Whether to search current directory (defaults to True)
116
"""
117
118
def __init__(self, tree: Optional[AST], filename: Optional[str], lines: Union[List[str], str]) -> None:
119
"""
120
Initialize base plugin functionality.
121
122
Args:
123
tree: AST tree of the Python file (None for string-based processing)
124
filename: Path to the file being checked (None for stdin)
125
lines: Lines of the file content as list of strings or single string
126
"""
127
128
@staticmethod
129
def add_options(option_manager: Any) -> None:
130
"""
131
Add plugin-specific command line options to flake8.
132
133
Args:
134
option_manager: flake8's option manager instance
135
"""
136
137
@classmethod
138
def parse_options(cls, option_manager: Any, options: Any, args: Any) -> None:
139
"""
140
Parse and store plugin options.
141
142
Args:
143
option_manager: flake8's option manager instance
144
options: Parsed command line options
145
args: Command line arguments
146
"""
147
```
148
149
### Version-Specific Implementation Classes
150
151
Implementation classes for different isort versions with specialized processing logic.
152
153
```python { .api }
154
class Flake8Isort4(Flake8IsortBase):
155
"""
156
Implementation for isort version <5 compatibility using SortImports API.
157
"""
158
159
def run(self) -> Iterator[Tuple[int, int, str, Type]]:
160
"""
161
Run import checking using isort v4 SortImports API.
162
163
Yields:
164
tuple: (line_number, column, message, plugin_class)
165
"""
166
167
def sortimports_linenum_msg(self, sort_result: Any) -> Iterator[Tuple[int, str]]:
168
"""
169
Parse isort.SortImports results for line number changes and generate error messages.
170
171
Args:
172
sort_result: isort.SortImports result object
173
174
Yields:
175
tuple: (line_number, error_message)
176
"""
177
178
class Flake8Isort5(Flake8IsortBase):
179
"""
180
Implementation for isort version >=5 compatibility using modern isort.api.
181
"""
182
183
def run(self) -> Iterator[Tuple[int, int, str, Type]]:
184
"""
185
Run import checking using isort v5 API with stream processing.
186
187
Handles isort.exceptions.FileSkipped and isort.exceptions.ISortError gracefully.
188
189
Yields:
190
tuple: (line_number, column, message, plugin_class)
191
"""
192
193
def isort_linenum_msg(self, udiff: str) -> Iterator[Tuple[int, str]]:
194
"""
195
Parse unified diff for import changes and generate error messages.
196
197
Args:
198
udiff: Unified diff output from isort comparison
199
200
Yields:
201
tuple: (line_number, error_message)
202
"""
203
204
# Additional utility methods in Flake8Isort4
205
class Flake8Isort4(Flake8IsortBase):
206
"""Additional methods for isort v4 compatibility"""
207
208
def _format_isort_output(self, isort_buffer: StringIO) -> str:
209
"""
210
Format isort output by filtering out diff metadata lines.
211
212
Args:
213
isort_buffer: Buffer containing isort output
214
215
Returns:
216
Formatted output with filtered lines and normalized newlines
217
"""
218
219
@staticmethod
220
def _fixup_sortimports_eof(sort_imports: Any) -> None:
221
"""
222
Ensure single end-of-file newline in isort.SortImports.in_lines.
223
224
Fixes EOF blank lines to avoid conflicts with flake8's own EOF checks.
225
226
Args:
227
sort_imports: isort.SortImports result object
228
"""
229
230
@staticmethod
231
def _fixup_sortimports_wrapped(sort_imports: Any) -> None:
232
"""
233
Split wrapped import lines in SortImports.out_lines for diff comparison.
234
235
isort combines wrapped lines into single strings, but in_lines keeps them separate.
236
This method splits them for proper diff comparison.
237
238
Args:
239
sort_imports: isort.SortImports result object
240
"""
241
```
242
243
## Configuration
244
245
### Command Line Options
246
247
Options that can be passed to flake8 when using this plugin.
248
249
```python { .api }
250
# Command line options
251
--isort-show-traceback # Show full traceback with diff from isort (boolean flag)
252
```
253
254
### Configuration Files
255
256
The plugin respects isort configuration from multiple sources:
257
258
- `.isort.cfg`: Dedicated isort configuration file
259
- `setup.cfg`: Under `[isort]` section
260
- `pyproject.toml`: Under `[tool.isort]` section
261
- `tox.ini`: Under `[isort]` section
262
263
Example configurations:
264
265
```ini
266
# .isort.cfg
267
[settings]
268
line_length = 88
269
multi_line_output = 3
270
include_trailing_comma = true
271
force_grid_wrap = 0
272
combine_as_imports = true
273
known_first_party = myproject
274
known_third_party = requests,click
275
```
276
277
```toml
278
# pyproject.toml
279
[tool.isort]
280
line_length = 88
281
multi_line_output = 3
282
include_trailing_comma = true
283
force_grid_wrap = 0
284
combine_as_imports = true
285
known_first_party = ["myproject"]
286
known_third_party = ["requests", "click"]
287
```
288
289
## Error Codes
290
291
The plugin reports five specific error codes for different import issues:
292
293
```python { .api }
294
# Error code definitions
295
I001 # isort found an import in the wrong position
296
I002 # no configuration found (.isort.cfg or [isort] in configs)
297
I003 # isort expected 1 blank line in imports, found 0
298
I004 # isort found an unexpected blank line in imports
299
I005 # isort found an unexpected missing import
300
```
301
302
## Usage Examples
303
304
### Basic flake8 Integration
305
306
```bash
307
# Check specific file
308
flake8 mymodule.py
309
310
# Check entire project with import sorting
311
flake8 src/ tests/
312
313
# Only check import-related issues
314
flake8 --select=I src/
315
316
# Show detailed diff when imports are wrong
317
flake8 --isort-show-traceback src/
318
```
319
320
### Custom flake8 Configuration
321
322
```ini
323
# setup.cfg or tox.ini
324
[flake8]
325
select = E,W,F,I
326
max-line-length = 88
327
isort-show-traceback = true
328
329
[isort]
330
line_length = 88
331
multi_line_output = 3
332
include_trailing_comma = true
333
```
334
335
### Integration with CI/CD
336
337
```yaml
338
# .github/workflows/lint.yml
339
- name: Run flake8 with import sorting
340
run: |
341
pip install flake8 flake8-isort
342
flake8 --select=E,W,F,I src/ tests/
343
```
344
345
### Direct Class Usage (Advanced)
346
347
```python
348
# For custom tooling or testing
349
from flake8_isort import Flake8Isort
350
import ast
351
352
# Parse Python code
353
code = '''
354
import os
355
import sys
356
import requests
357
'''
358
359
tree = ast.parse(code)
360
lines = code.splitlines(keepends=True)
361
362
# Create plugin instance
363
checker = Flake8Isort(tree, 'example.py', lines)
364
365
# Run checks
366
for line_num, col, message, cls in checker.run():
367
print(f"{line_num}: {message}")
368
```
369
370
## Integration Notes
371
372
### flake8 Plugin System
373
374
This plugin integrates with flake8 through the entry points system:
375
376
- **Entry Point**: `flake8.extension` with key `I00 = flake8_isort:Flake8Isort`
377
- **Error Code Prefix**: `I` (I001-I005)
378
- **Plugin Discovery**: Automatic through setuptools entry points
379
380
### isort Version Compatibility
381
382
The plugin automatically detects and adapts to different isort versions:
383
384
- **isort <5**: Uses `isort.SortImports` API with diff processing
385
- **isort >=5**: Uses `isort.api.sort_stream` with unified diff parsing
386
- **Automatic Selection**: `Flake8Isort5 if hasattr(isort, 'api') else Flake8Isort4`
387
388
### Workflow Integration
389
390
Common integration patterns:
391
392
1. **Local Development**: Install plugin, configure isort, run flake8
393
2. **Pre-commit Hooks**: Combine with isort for auto-fixing and checking
394
3. **CI/CD Pipelines**: Include in automated quality checks
395
4. **IDE Integration**: Works with any flake8-compatible IDE plugin