0
# Build System Integration
1
2
Advanced APIs for custom build systems and development tools that need fine-grained control over the type checking process. These APIs provide programmatic access to mypy's internal build system and analysis engine.
3
4
## Capabilities
5
6
### Main Build Function
7
8
The primary entry point for programmatic type analysis with full control over the build process.
9
10
```python { .api }
11
def build(sources, options, alt_lib_path=None, flush_errors=None,
12
fscache=None, stdout=None, stderr=None, extra_plugins=None) -> BuildResult:
13
"""
14
Main function to analyze a program programmatically.
15
16
Parameters:
17
- sources: list[BuildSource] - List of BuildSource objects to analyze
18
- options: Options - Options object with configuration settings
19
- alt_lib_path: str | None - Alternative library path for imports
20
- flush_errors: callable | None - Callback for flushing error messages
21
- fscache: FileSystemCache | None - File system cache for performance
22
- stdout: TextIO | None - Output stream for messages
23
- stderr: TextIO | None - Error stream for diagnostics
24
- extra_plugins: list[Plugin] | None - Additional plugins to load
25
26
Returns:
27
- BuildResult: Analysis results with errors, types, and file information
28
29
Usage:
30
result = build(sources, options)
31
"""
32
```
33
34
### Build Source Definition
35
36
Represents source files or modules to be analyzed.
37
38
```python { .api }
39
class BuildSource:
40
"""
41
Represents a source file or module to be analyzed.
42
43
Attributes:
44
- path: str | None - File path (None for in-memory modules)
45
- module: str | None - Module name (None for file-based sources)
46
- text: str | None - Source code text (None to read from file)
47
- followed: bool - Whether this source was found by following imports
48
49
Usage:
50
# File-based source
51
source = BuildSource("myfile.py", module=None, text=None)
52
53
# Module-based source
54
source = BuildSource(path=None, module="mypackage.mymodule", text=None)
55
56
# In-memory source
57
source = BuildSource(path="<string>", module=None, text="def func(): pass")
58
"""
59
60
def __init__(self, path: str | None, module: str | None, text: str | None, followed: bool = False):
61
"""Initialize a build source."""
62
```
63
64
### Build Results
65
66
Contains the results of type checking analysis.
67
68
```python { .api }
69
class BuildResult:
70
"""
71
Contains the results of type checking analysis.
72
73
Attributes:
74
- errors: list[str] - List of error message strings
75
- files: dict[str, MypyFile] - Mapping of module names to AST nodes
76
- types: dict[Expression, Type] - Type information for expressions
77
- used_cache: bool - Whether cached results were used
78
- manager: BuildManager | None - Build manager instance
79
80
Usage:
81
if result.errors:
82
for error in result.errors:
83
print(error)
84
"""
85
```
86
87
### Build Manager
88
89
Advanced build management for fine-grained control over the type checking process.
90
91
```python { .api }
92
class BuildManager:
93
"""
94
Build manager that coordinates parsing, import processing, semantic analysis and type checking.
95
96
This class holds shared state for building a mypy program and is used for advanced
97
build scenarios that need fine-grained control over the analysis process.
98
99
Attributes:
100
- data_dir: str - Mypy data directory (contains stubs)
101
- search_paths: SearchPaths - Module search paths configuration
102
- modules: dict[str, MypyFile] - Mapping of module ID to MypyFile
103
- options: Options - Build options
104
- missing_modules: set[str] - Set of modules that could not be imported
105
- stale_modules: set[str] - Set of modules that needed to be rechecked
106
- version_id: str - The current mypy version identifier
107
- plugin: Plugin | None - Active mypy plugin(s)
108
109
Usage:
110
manager = BuildManager(data_dir, search_paths, options, version_id)
111
result = manager.build(sources)
112
"""
113
```
114
115
### File System Cache
116
117
Caching system for improved performance during type checking operations.
118
119
```python { .api }
120
class FileSystemCache:
121
"""
122
File system cache for improved performance during mypy operations.
123
124
Provides caching of file system operations and module information
125
to speed up repeated type checking runs.
126
127
Methods:
128
- flush(): Clear all cached data
129
- set_package_root(package_root: list[str]): Set package root directories
130
131
Usage:
132
cache = FileSystemCache()
133
cache.set_package_root(['/path/to/package'])
134
result = build(sources, options, fscache=cache)
135
"""
136
```
137
138
### Search Paths Configuration
139
140
Module search path configuration for finding Python modules and packages.
141
142
```python { .api }
143
class SearchPaths:
144
"""
145
Configuration for module search paths used during import resolution.
146
147
Attributes:
148
- python_path: tuple[str, ...] - Where user code is found
149
- mypy_path: tuple[str, ...] - From $MYPYPATH or config variable
150
- package_path: tuple[str, ...] - From get_site_packages_dirs()
151
- typeshed_path: tuple[str, ...] - Paths in typeshed
152
153
Usage:
154
paths = SearchPaths(python_path, mypy_path, package_path, typeshed_path)
155
"""
156
```
157
158
### Configuration Options
159
160
Comprehensive configuration object for controlling type checking behavior.
161
162
```python { .api }
163
class Options:
164
"""
165
Configuration container for all mypy settings.
166
167
Build Configuration:
168
- python_version: tuple[int, int] - Target Python version (default: current)
169
- platform: str - Target platform ('linux', 'win32', 'darwin')
170
- custom_typing_module: str | None - Custom typing module name
171
- mypy_path: list[str] - Additional module search paths
172
- namespace_packages: bool - Support namespace packages
173
- explicit_package_bases: bool - Require __init__.py for packages
174
175
Type Checking Options:
176
- strict_mode: bool - Enable all strict mode flags
177
- disallow_untyped_defs: bool - Disallow untyped function definitions
178
- disallow_incomplete_defs: bool - Disallow partially typed definitions
179
- disallow_untyped_decorators: bool - Disallow untyped decorators
180
- disallow_any_generics: bool - Disallow generic types without parameters
181
- disallow_any_unimported: bool - Disallow Any from missing imports
182
- disallow_subclassing_any: bool - Disallow subclassing Any
183
- warn_redundant_casts: bool - Warn about redundant casts
184
- warn_unused_ignores: bool - Warn about unused # type: ignore
185
- warn_return_any: bool - Warn about returning Any from functions
186
187
Error Reporting:
188
- show_error_codes: bool - Show error codes in output
189
- show_column_numbers: bool - Show column numbers in errors
190
- show_absolute_path: bool - Show absolute paths in errors
191
- ignore_missing_imports: bool - Ignore missing import errors
192
- follow_imports: str - Import following mode ('normal', 'silent', 'skip')
193
194
Performance:
195
- incremental: bool - Enable incremental mode
196
- cache_dir: str - Directory for cache files
197
- sqlite_cache: bool - Use SQLite for caching
198
- skip_version_check: bool - Skip cache version checks
199
200
Usage:
201
options = Options()
202
options.strict_mode = True
203
options.python_version = (3, 11)
204
"""
205
```
206
207
## Usage Examples
208
209
### Basic Build Integration
210
211
```python
212
from mypy.build import build, BuildSource
213
from mypy.options import Options
214
215
# Configure options
216
options = Options()
217
options.strict_mode = True
218
options.python_version = (3, 11)
219
options.show_error_codes = True
220
221
# Define sources to analyze
222
sources = [
223
BuildSource("src/main.py", module=None, text=None),
224
BuildSource("src/utils.py", module=None, text=None),
225
]
226
227
# Perform analysis
228
result = build(sources, options)
229
230
# Process results
231
if result.errors:
232
print("Type errors found:")
233
for error in result.errors:
234
print(f" {error}")
235
else:
236
print("No type errors!")
237
238
# Access type information
239
for expr, typ in result.types.items():
240
print(f"Expression {expr} has type {typ}")
241
```
242
243
### Advanced Build Configuration
244
245
```python
246
from mypy.build import build, BuildSource
247
from mypy.options import Options
248
from mypy.fscache import FileSystemCache
249
import sys
250
251
class AdvancedTypeChecker:
252
"""Advanced type checker with custom configuration."""
253
254
def __init__(self, cache_dir=".mypy_cache"):
255
self.options = Options()
256
self.cache = FileSystemCache(cache_dir)
257
self.setup_options()
258
259
def setup_options(self):
260
"""Configure type checking options."""
261
# Strict type checking
262
self.options.strict_mode = True
263
264
# Target configuration
265
self.options.python_version = (3, 11)
266
self.options.platform = sys.platform
267
268
# Error reporting
269
self.options.show_error_codes = True
270
self.options.show_column_numbers = True
271
self.options.color_output = True
272
273
# Performance
274
self.options.incremental = True
275
self.options.cache_dir = ".mypy_cache"
276
277
# Import handling
278
self.options.follow_imports = "normal"
279
self.options.namespace_packages = True
280
281
def check_project(self, source_files):
282
"""Type check a project."""
283
# Convert file paths to BuildSource objects
284
sources = []
285
for filepath in source_files:
286
source = BuildSource(filepath, module=None, text=None)
287
sources.append(source)
288
289
# Perform type checking
290
result = build(
291
sources=sources,
292
options=self.options,
293
fscache=self.cache,
294
stdout=sys.stdout,
295
stderr=sys.stderr
296
)
297
298
return result
299
300
def check_module(self, module_name, source_text):
301
"""Type check a module from source text."""
302
source = BuildSource(
303
path=f"<{module_name}>",
304
module=module_name,
305
text=source_text
306
)
307
308
result = build([source], self.options)
309
return result
310
311
# Usage
312
checker = AdvancedTypeChecker()
313
result = checker.check_project(['src/main.py', 'src/utils.py'])
314
315
if result.errors:
316
print(f"Found {len(result.errors)} type errors")
317
```
318
319
### Custom Error Handling
320
321
```python
322
from mypy.build import build, BuildSource
323
from mypy.options import Options
324
from mypy.errors import CompileError
325
import sys
326
from io import StringIO
327
328
def type_check_with_custom_errors(sources, options):
329
"""Type check with custom error handling and formatting."""
330
331
# Capture error output
332
error_stream = StringIO()
333
334
try:
335
result = build(
336
sources=sources,
337
options=options,
338
stderr=error_stream
339
)
340
341
# Parse and format errors
342
errors = []
343
if result.errors:
344
for error_line in result.errors:
345
# Parse error components
346
parts = error_line.split(":", 3)
347
if len(parts) >= 4:
348
file_path = parts[0]
349
line_num = parts[1]
350
level = parts[2].strip()
351
message = parts[3].strip()
352
353
errors.append({
354
'file': file_path,
355
'line': int(line_num) if line_num.isdigit() else 0,
356
'level': level,
357
'message': message
358
})
359
360
return {
361
'success': len(errors) == 0,
362
'errors': errors,
363
'result': result
364
}
365
366
except CompileError as e:
367
return {
368
'success': False,
369
'errors': [{'file': '<build>', 'line': 0, 'level': 'error', 'message': str(e)}],
370
'result': None
371
}
372
373
# Usage
374
options = Options()
375
options.strict_mode = True
376
377
sources = [BuildSource("myfile.py", None, None)]
378
analysis = type_check_with_custom_errors(sources, options)
379
380
if not analysis['success']:
381
print("Type checking failed:")
382
for error in analysis['errors']:
383
print(f" {error['file']}:{error['line']}: {error['message']}")
384
```
385
386
### Integration with Custom Plugins
387
388
```python
389
from mypy.build import build, BuildSource
390
from mypy.options import Options
391
from mypy.plugin import Plugin
392
393
class CustomPlugin(Plugin):
394
"""Custom plugin for specialized type checking."""
395
396
def get_function_hook(self, fullname):
397
"""Hook for function calls."""
398
if fullname == "mypackage.special_function":
399
return self.handle_special_function
400
return None
401
402
def handle_special_function(self, ctx):
403
"""Custom handling for special function."""
404
# Custom type checking logic
405
return ctx.default_return_type
406
407
def build_with_plugin():
408
"""Build with custom plugin."""
409
options = Options()
410
options.strict_mode = True
411
412
# Create custom plugin instance
413
plugin = CustomPlugin(options, "custom_plugin")
414
415
sources = [BuildSource("mycode.py", None, None)]
416
417
result = build(
418
sources=sources,
419
options=options,
420
extra_plugins=[plugin]
421
)
422
423
return result
424
425
# Usage
426
result = build_with_plugin()
427
```
428
429
## Build Manager Integration
430
431
### Advanced Build Control
432
433
```python
434
from mypy.build import BuildManager, BuildSource
435
from mypy.options import Options
436
from mypy.fscache import FileSystemCache
437
from mypy.modulefinder import SearchPaths
438
439
class CustomBuildManager:
440
"""Custom build manager for advanced scenarios."""
441
442
def __init__(self, data_dir=".mypy_cache"):
443
self.options = Options()
444
self.fscache = FileSystemCache()
445
self.data_dir = data_dir
446
447
# Configure search paths
448
self.search_paths = SearchPaths(
449
python_path=(),
450
mypy_path=(),
451
package_path=(),
452
typeshed_path=()
453
)
454
455
def incremental_build(self, sources, changed_files=None):
456
"""Perform incremental build with BuildManager."""
457
manager = BuildManager(
458
data_dir=self.data_dir,
459
search_paths=self.search_paths,
460
ignore_prefix="",
461
source_set=set(),
462
reports=None,
463
options=self.options,
464
version_id="custom_build",
465
plugin=None,
466
fscache=self.fscache,
467
t0=0
468
)
469
470
# Build with incremental support
471
if changed_files:
472
# Invalidate cache for changed files
473
for filepath in changed_files:
474
manager.flush_cache(filepath)
475
476
return manager.build(sources)
477
478
# Usage for development tools that need incremental checking
479
manager = CustomBuildManager()
480
sources = [BuildSource("myfile.py", None, None)]
481
result = manager.incremental_build(sources, changed_files=["myfile.py"])
482
```
483
484
## Performance Optimization
485
486
### Caching Strategies
487
488
```python
489
from mypy.build import build, BuildSource
490
from mypy.options import Options
491
from mypy.fscache import FileSystemCache
492
493
# Persistent cache for better performance
494
cache = FileSystemCache(".mypy_cache")
495
496
# Reuse cache across builds
497
options = Options()
498
options.incremental = True
499
options.cache_dir = ".mypy_cache"
500
501
sources = [BuildSource("myfile.py", None, None)]
502
503
# First build (slower)
504
result1 = build(sources, options, fscache=cache)
505
506
# Subsequent builds (faster)
507
result2 = build(sources, options, fscache=cache)
508
```
509
510
### Batch Processing
511
512
```python
513
from mypy.build import build, BuildSource
514
from mypy.options import Options
515
516
def batch_type_check(file_groups):
517
"""Process multiple file groups efficiently."""
518
options = Options()
519
options.incremental = True
520
521
results = []
522
523
for group in file_groups:
524
sources = [BuildSource(f, None, None) for f in group]
525
result = build(sources, options)
526
results.append(result)
527
528
return results
529
530
# Usage
531
file_groups = [
532
["core/main.py", "core/utils.py"],
533
["tests/test_main.py", "tests/test_utils.py"],
534
["plugins/plugin1.py", "plugins/plugin2.py"]
535
]
536
537
results = batch_type_check(file_groups)
538
```