0
# Command Line Interface
1
2
Command-line entry point and application management for running flake8 as a standalone tool or integrating it into scripts and build systems.
3
4
## Capabilities
5
6
### Main CLI Entry Point
7
8
Execute flake8 from Python code with full command-line argument support.
9
10
```python { .api }
11
from collections.abc import Sequence
12
13
def main(argv: Sequence[str] | None = None) -> int:
14
"""
15
Main entry point for flake8 command-line execution.
16
17
Creates an Application instance, runs the complete flake8 workflow
18
(argument parsing, file discovery, checking, reporting), and returns
19
the appropriate exit code.
20
21
Parameters:
22
argv: Command-line arguments to process. If None, uses sys.argv[1:]
23
Arguments follow standard flake8 CLI format:
24
- File/directory paths to check
25
- Configuration options (--max-line-length, --ignore, etc.)
26
- Output options (--format, --output-file, --statistics, etc.)
27
28
Returns:
29
int: Exit code indicating success (0) or failure (>0)
30
- 0: No violations found
31
- >0: Number of violations found (or general error)
32
33
Example:
34
# Check specific files with custom options
35
exit_code = main(['--max-line-length=88', '--ignore=E203,W503', 'myapp/'])
36
37
# Check with statistics output
38
exit_code = main(['--statistics', '--show-source', 'project/'])
39
"""
40
```
41
42
Usage example:
43
44
```python
45
from flake8.main import cli
46
import sys
47
48
# Run flake8 on current directory with custom settings
49
exit_code = cli.main([
50
'--max-line-length=88',
51
'--ignore=E203,W503',
52
'--exclude=migrations,venv',
53
'--statistics',
54
'.'
55
])
56
57
# Exit with flake8's exit code
58
sys.exit(exit_code)
59
```
60
61
### Application Management
62
63
Core application class for advanced integration and custom flake8 workflows.
64
65
```python { .api }
66
class Application:
67
"""
68
Core application class that orchestrates flake8 execution.
69
70
Manages the complete flake8 workflow including plugin loading,
71
option parsing, file discovery, checking execution, and result reporting.
72
"""
73
74
def __init__(self) -> None:
75
"""Initialize a new Application instance."""
76
77
def run(self, argv: list[str]) -> None:
78
"""
79
Execute the complete flake8 workflow.
80
81
Parameters:
82
argv: Command-line arguments to process
83
"""
84
85
def exit_code(self) -> int:
86
"""
87
Get the exit code after running flake8.
88
89
Returns:
90
int: Exit code based on execution results
91
- 0: Success, no violations
92
- >0: Violations found or error occurred
93
"""
94
95
@property
96
def result_count(self) -> int:
97
"""
98
Number of violations found after execution.
99
100
Returns:
101
int: Total count of errors and warnings found
102
"""
103
104
@property
105
def start_time(self) -> float:
106
"""Timestamp when Application was instantiated."""
107
108
@property
109
def end_time(self) -> float | None:
110
"""Timestamp when Application finished, or None if still running."""
111
```
112
113
Usage example:
114
115
```python
116
from flake8.main.application import Application
117
118
# Create and run application manually
119
app = Application()
120
app.run(['--show-source', 'myproject/'])
121
122
# Check results
123
if app.result_count > 0:
124
print(f"Found {app.result_count} violations")
125
exit_code = app.exit_code()
126
else:
127
print("No violations found!")
128
exit_code = 0
129
130
# Calculate execution time
131
if app.end_time:
132
duration = app.end_time - app.start_time
133
print(f"Execution took {duration:.2f} seconds")
134
```
135
136
## Command Line Arguments
137
138
When using the main() function or Application.run(), flake8 accepts standard command-line arguments:
139
140
### File Selection
141
- Positional arguments: Files and directories to check
142
- `--exclude`: Comma-separated patterns to exclude
143
- `--filename`: Patterns for files to include
144
- `--stdin-display-name`: Display name when reading from stdin
145
146
### Error Selection
147
- `--select`: Comma-separated error codes to check for
148
- `--ignore`: Comma-separated error codes to ignore
149
- `--extend-ignore`: Additional error codes to ignore
150
- `--per-file-ignores`: File-specific ignores
151
152
### Output Options
153
- `--format`: Output format string
154
- `--output-file`: Write output to file
155
- `--show-source`: Show source code for each error
156
- `--statistics`: Show violation statistics
157
- `--count`: Show total error count
158
- `--quiet`: Reduce output verbosity
159
160
### Configuration
161
- `--config`: Path to configuration file
162
- `--max-line-length`: Maximum line length
163
- `--max-complexity`: Maximum cyclomatic complexity
164
- `--jobs`: Number of parallel jobs
165
166
## Integration Examples
167
168
### Script Integration
169
170
```python
171
#!/usr/bin/env python3
172
"""Code quality check script."""
173
174
from flake8.main import cli
175
import sys
176
import os
177
178
def main():
179
"""Run flake8 with project-specific configuration."""
180
181
# Define project-specific settings
182
flake8_args = [
183
'--max-line-length=88',
184
'--ignore=E203,W503,E501',
185
'--exclude=migrations,venv,.git,__pycache__',
186
'--statistics',
187
'--show-source',
188
]
189
190
# Add target directories
191
target_dirs = ['src/', 'tests/']
192
for directory in target_dirs:
193
if os.path.exists(directory):
194
flake8_args.append(directory)
195
196
# Run flake8
197
print("Running flake8 code quality checks...")
198
exit_code = cli.main(flake8_args)
199
200
if exit_code == 0:
201
print("✅ All code quality checks passed!")
202
else:
203
print("❌ Code quality issues found!")
204
205
return exit_code
206
207
if __name__ == "__main__":
208
sys.exit(main())
209
```
210
211
### Pre-commit Hook
212
213
```python
214
#!/usr/bin/env python3
215
"""Git pre-commit hook using flake8."""
216
217
from flake8.main import cli
218
import subprocess
219
import sys
220
221
def get_staged_python_files():
222
"""Get list of staged Python files."""
223
result = subprocess.run(
224
['git', 'diff', '--cached', '--name-only', '--diff-filter=ACM'],
225
capture_output=True, text=True
226
)
227
228
files = result.stdout.strip().split('\n')
229
python_files = [f for f in files if f.endswith('.py') and f]
230
return python_files
231
232
def main():
233
"""Run flake8 on staged files."""
234
staged_files = get_staged_python_files()
235
236
if not staged_files:
237
print("No Python files staged for commit.")
238
return 0
239
240
print(f"Checking {len(staged_files)} staged Python files...")
241
242
# Run flake8 on staged files only
243
flake8_args = [
244
'--max-line-length=88',
245
'--ignore=E203,W503',
246
'--show-source'
247
] + staged_files
248
249
exit_code = cli.main(flake8_args)
250
251
if exit_code != 0:
252
print("❌ Flake8 found issues in staged files.")
253
print("Fix the issues or use 'git commit --no-verify' to bypass.")
254
255
return exit_code
256
257
if __name__ == "__main__":
258
sys.exit(main())
259
```
260
261
### Build System Integration
262
263
```python
264
"""Build system integration example."""
265
266
from flake8.main.application import Application
267
import time
268
269
class BuildStep:
270
"""Flake8 build step for CI/CD integration."""
271
272
def __init__(self, config=None):
273
self.config = config or {}
274
275
def run_quality_check(self, source_dirs):
276
"""Run flake8 as part of build process."""
277
278
print("Starting code quality check...")
279
start_time = time.time()
280
281
# Configure flake8 arguments
282
args = [
283
'--statistics',
284
'--format=%(path)s:%(row)d:%(col)d: %(code)s %(text)s',
285
'--output-file=flake8-report.txt'
286
]
287
288
# Add configuration
289
if 'max_line_length' in self.config:
290
args.append(f"--max-line-length={self.config['max_line_length']}")
291
292
if 'ignore' in self.config:
293
args.append(f"--ignore={','.join(self.config['ignore'])}")
294
295
# Add source directories
296
args.extend(source_dirs)
297
298
# Run application
299
app = Application()
300
app.run(args)
301
302
# Report results
303
duration = time.time() - start_time
304
print(f"Quality check completed in {duration:.2f}s")
305
print(f"Found {app.result_count} violations")
306
307
return app.exit_code() == 0
308
309
# Usage in build script
310
build_step = BuildStep({
311
'max_line_length': 88,
312
'ignore': ['E203', 'W503']
313
})
314
315
success = build_step.run_quality_check(['src/', 'tests/'])
316
if not success:
317
print("Build failed due to code quality issues")
318
exit(1)
319
```