0
# Manager System
1
2
Central management system for building, caching, and retrieving astroid AST trees from various sources. The manager provides a high-level interface for working with Python modules and handles caching to improve performance.
3
4
## Capabilities
5
6
### AstroidManager Class
7
8
The main management class that coordinates building, caching, and transform application for astroid AST trees.
9
10
```python { .api }
11
class AstroidManager:
12
"""Central manager for astroid AST trees."""
13
14
def __init__(self) -> None:
15
"""Initialize the manager with default settings."""
16
17
def ast_from_file(self, filepath: str, modname: str | None = None, fallback: bool = True, source: bool = False) -> Module:
18
"""
19
Build astroid tree from a Python file.
20
21
Parameters:
22
- filepath: Path to the Python file
23
- modname: Module name (defaults to filename)
24
- fallback: Try alternative loading methods on failure
25
- source: Get source code instead of compiled module
26
27
Returns:
28
Module node representing the file
29
30
Raises:
31
AstroidBuildingError: If file cannot be loaded or parsed
32
"""
33
34
def ast_from_string(self, data: str, modname: str = "", filepath: str | None = None) -> Module:
35
"""
36
Build astroid tree from source string.
37
38
Parameters:
39
- data: Python source code
40
- modname: Name for the module
41
- filepath: Optional file path for error reporting
42
43
Returns:
44
Module node representing the source
45
46
Raises:
47
AstroidSyntaxError: If source contains syntax errors
48
"""
49
50
def ast_from_module_name(self, modname: str | None, context_file: str | None = None, use_cache: bool = True) -> Module:
51
"""
52
Build astroid tree from module name.
53
54
Parameters:
55
- modname: Fully qualified module name
56
- context_file: File requesting the module (for relative imports)
57
- use_cache: Whether to use cached version if available
58
59
Returns:
60
Module node for the imported module
61
62
Raises:
63
AstroidImportError: If module cannot be imported
64
"""
65
66
def ast_from_module(self, module: Any, modname: str | None = None) -> Module:
67
"""
68
Build astroid tree from live Python module.
69
70
Parameters:
71
- module: Python module object
72
- modname: Name for the astroid module
73
74
Returns:
75
Module node representing the live module
76
77
Raises:
78
AstroidBuildingError: If module cannot be introspected
79
"""
80
81
def ast_from_class(self, klass: type, modname: str | None = None) -> Module:
82
"""
83
Build astroid tree from a Python class.
84
85
Parameters:
86
- klass: Python class object
87
- modname: Module name for the generated tree
88
89
Returns:
90
Module containing the class definition
91
92
Raises:
93
AstroidBuildingError: If class cannot be introspected
94
"""
95
```
96
97
### Manager Configuration
98
99
Control manager behavior through properties and methods.
100
101
```python { .api }
102
class AstroidManager:
103
# Configuration properties
104
always_load_extensions: bool
105
"""Whether to always load brain extensions."""
106
107
optimize_ast: bool
108
"""Enable AST optimization during building."""
109
110
max_inferable_values: int
111
"""Maximum number of values to infer for sequences."""
112
113
prefer_stubs: bool
114
"""Prefer .pyi stub files over .py files."""
115
116
# Cache management
117
def clear_cache(self) -> None:
118
"""Clear all cached AST trees."""
119
120
def cache_size(self) -> int:
121
"""Get number of cached modules."""
122
123
# Transform system
124
def register_transform(self, node_class: type[NodeNG], transform: Callable, predicate: Callable | None = None) -> None:
125
"""
126
Register an AST transform function.
127
128
Parameters:
129
- node_class: Node class to transform
130
- transform: Transform function
131
- predicate: Optional condition for applying transform
132
"""
133
134
def unregister_transform(self, node_class: type[NodeNG], transform: Callable, predicate: Callable | None = None) -> None:
135
"""Unregister a previously registered transform."""
136
137
# Import hooks
138
def register_failed_import_hook(self, hook: Callable) -> None:
139
"""Register hook for handling failed imports."""
140
141
def unregister_failed_import_hook(self, hook: Callable) -> None:
142
"""Unregister a failed import hook."""
143
```
144
145
### Global Manager Instance
146
147
```python { .api }
148
MANAGER: AstroidManager
149
"""Global singleton manager instance."""
150
```
151
152
### Builder Integration
153
154
The manager works with builder classes to create AST trees.
155
156
```python { .api }
157
class TreeRebuilder:
158
"""Rebuilds Python AST as astroid AST."""
159
160
def __init__(self, manager: AstroidManager) -> None:
161
"""Initialize with manager instance."""
162
163
def visit_module(self, node: ast.Module, parent: NodeNG) -> Module:
164
"""Convert ast.Module to astroid.Module."""
165
```
166
167
## Usage Examples
168
169
### Basic Module Loading
170
171
```python
172
import astroid
173
174
# Get the global manager
175
manager = astroid.MANAGER
176
177
# Load module from file
178
try:
179
module = manager.ast_from_file('mymodule.py')
180
print(f"Loaded module: {module.name}")
181
except astroid.AstroidBuildingError as e:
182
print(f"Failed to load: {e}")
183
184
# Load module by name
185
try:
186
os_module = manager.ast_from_module_name('os')
187
print(f"OS module functions: {len(os_module.keys())}")
188
except astroid.AstroidImportError as e:
189
print(f"Import failed: {e}")
190
```
191
192
### Caching and Performance
193
194
```python
195
import astroid
196
197
manager = astroid.MANAGER
198
199
# First load - builds and caches
200
module1 = manager.ast_from_module_name('sys')
201
202
# Second load - uses cache
203
module2 = manager.ast_from_module_name('sys')
204
205
print(f"Same instance: {module1 is module2}") # True
206
207
# Clear cache if needed
208
manager.clear_cache()
209
print(f"Cache size: {manager.cache_size()}") # 0
210
```
211
212
### Transform Registration
213
214
```python
215
import astroid
216
from astroid import nodes
217
218
def remove_pass_statements(node):
219
"""Transform to remove pass statements."""
220
if isinstance(node, nodes.Pass):
221
return None # Remove the node
222
return node
223
224
# Register transform
225
astroid.MANAGER.register_transform(nodes.Pass, remove_pass_statements)
226
227
# Parse code with pass statements
228
code = '''
229
def func():
230
pass # This will be removed
231
return 42
232
'''
233
234
module = astroid.parse(code)
235
# Pass statement will be removed from the AST
236
```
237
238
### Failed Import Handling
239
240
```python
241
import astroid
242
243
def handle_failed_import(modname):
244
"""Handle modules that can't be imported."""
245
if modname == 'missing_module':
246
# Create a dummy module
247
return astroid.parse('# Dummy module', modname)
248
return None
249
250
# Register the hook
251
astroid.MANAGER.register_failed_import_hook(handle_failed_import)
252
253
# Now imports of 'missing_module' will use the dummy
254
try:
255
module = astroid.MANAGER.ast_from_module_name('missing_module')
256
print("Got dummy module")
257
except astroid.AstroidImportError:
258
print("Import still failed")
259
```
260
261
### Configuration
262
263
```python
264
import astroid
265
266
manager = astroid.MANAGER
267
268
# Configure manager behavior
269
manager.optimize_ast = True
270
manager.max_inferable_values = 100
271
manager.prefer_stubs = True
272
273
# Load with brain extensions
274
manager.always_load_extensions = True
275
module = manager.ast_from_module_name('requests')
276
```
277
278
## Error Handling
279
280
The manager system raises specific exceptions:
281
282
- **AstroidBuildingError**: General building failures
283
- **AstroidImportError**: Module import failures
284
- **AstroidSyntaxError**: Syntax errors in source code
285
286
## Advanced Features
287
288
### Custom Module Loaders
289
290
Create custom loaders for special module types:
291
292
```python
293
import astroid
294
295
class CustomModuleLoader:
296
def load_module(self, modname):
297
# Custom loading logic
298
return astroid.parse(f'# Custom module {modname}', modname)
299
300
# Integration with manager requires modifying the import system
301
```
302
303
### Performance Optimization
304
305
```python
306
import astroid
307
308
# Optimize for performance
309
manager = astroid.MANAGER
310
manager.optimize_ast = True
311
manager.max_inferable_values = 50 # Limit inference depth
312
313
# Bulk loading with caching
314
modules = []
315
for name in ['os', 'sys', 'json', 'collections']:
316
modules.append(manager.ast_from_module_name(name))
317
318
print(f"Cached {manager.cache_size()} modules")
319
```