0
# File Operations
1
2
High-level interfaces for parsing Python files into ASTs and managing code objects. This module provides comprehensive file handling capabilities with caching support and utilities for working with Python source files and code objects.
3
4
## Capabilities
5
6
### File Parsing
7
8
Parse Python files directly into AST representations with support for standard input and file path resolution.
9
10
```python { .api }
11
def parse_file(fname):
12
"""
13
Parse Python file into AST.
14
15
Parameters:
16
- fname: str, filename to parse (or 'stdin' for standard input)
17
18
Returns:
19
AST object representing the parsed Python code
20
21
Raises:
22
SyntaxError: If the file contains invalid Python syntax
23
FileNotFoundError: If the specified file does not exist
24
"""
25
```
26
27
**Usage Example:**
28
29
```python
30
import astor
31
32
# Parse a Python file
33
tree = astor.parse_file('my_script.py')
34
print(astor.dump_tree(tree))
35
36
# Parse from standard input
37
tree = astor.parse_file('stdin') # Read from stdin
38
39
# Convert parsed file back to source
40
source = astor.to_source(tree)
41
print(source)
42
```
43
44
### Code to AST Conversion
45
46
Advanced class for converting modules and functions to AST with caching support and metadata extraction.
47
48
```python { .api }
49
class CodeToAst:
50
"""
51
Convert modules/functions to AST with caching support.
52
53
Provides efficient conversion of code objects to AST representations
54
with optional caching for improved performance.
55
"""
56
57
def __init__(self, cache=None):
58
"""
59
Initialize with optional cache.
60
61
Parameters:
62
- cache: dict, optional cache for storing parsed results (default: None)
63
"""
64
65
def __call__(self, codeobj):
66
"""
67
Convert code object to AST.
68
69
Parameters:
70
- codeobj: code object to convert to AST
71
72
Returns:
73
AST object representing the code
74
"""
75
76
@staticmethod
77
def parse_file(fname):
78
"""
79
Parse Python file to AST.
80
81
Parameters:
82
- fname: str, filename to parse
83
84
Returns:
85
AST object representing the parsed file
86
"""
87
88
@staticmethod
89
def find_py_files(srctree, ignore=None):
90
"""
91
Find Python files in directory tree.
92
93
Parameters:
94
- srctree: str, root directory to search
95
- ignore: set, filenames to ignore (default: None)
96
97
Returns:
98
Generator yielding Python file paths
99
"""
100
101
@staticmethod
102
def get_file_info(codeobj):
103
"""
104
Get file and line info from code object.
105
106
Parameters:
107
- codeobj: code object to extract info from
108
109
Returns:
110
tuple: (filename, line_number) information
111
"""
112
```
113
114
**Usage Example:**
115
116
```python
117
import astor
118
import types
119
120
# Create CodeToAst instance with caching
121
converter = astor.CodeToAst(cache={})
122
123
# Convert a function to AST
124
def example_function(x, y):
125
return x + y
126
127
code_obj = example_function.__code__
128
ast_tree = converter(code_obj)
129
print(astor.dump_tree(ast_tree))
130
131
# Find all Python files in a directory
132
py_files = list(astor.CodeToAst.find_py_files('./src', ignore={'__pycache__'}))
133
print(f"Found {len(py_files)} Python files")
134
135
# Get file information from code object
136
filename, line_num = astor.CodeToAst.get_file_info(code_obj)
137
print(f"Function defined in {filename} at line {line_num}")
138
```
139
140
### Default Code Converter Instance
141
142
Pre-configured instance of CodeToAst for convenient file parsing operations.
143
144
```python { .api }
145
code_to_ast: CodeToAst
146
```
147
148
This is a default instance that can be used directly without initialization:
149
150
```python
151
import astor
152
153
# Use the default instance
154
tree = astor.code_to_ast.parse_file('example.py')
155
156
# Convert code object using default instance
157
def my_func():
158
pass
159
160
ast_tree = astor.code_to_ast(my_func.__code__)
161
```
162
163
## File Discovery and Management
164
165
### Python File Discovery
166
167
Utilities for systematically finding and processing Python source files in directory hierarchies.
168
169
**Usage Example:**
170
171
```python
172
import astor
173
import os
174
175
# Find all Python files in a project
176
project_root = './my_project'
177
ignore_dirs = {'__pycache__', '.git', 'venv'}
178
179
for py_file in astor.CodeToAst.find_py_files(project_root, ignore=ignore_dirs):
180
print(f"Processing: {py_file}")
181
try:
182
tree = astor.parse_file(py_file)
183
# Process the AST
184
print(f" Functions: {len([n for n in ast.walk(tree) if isinstance(n, ast.FunctionDef)])}")
185
print(f" Classes: {len([n for n in ast.walk(tree) if isinstance(n, ast.ClassDef)])}")
186
except SyntaxError as e:
187
print(f" Syntax error: {e}")
188
```
189
190
### Code Object Metadata
191
192
Extract useful metadata from Python code objects for analysis and debugging.
193
194
**Usage Example:**
195
196
```python
197
import astor
198
import inspect
199
200
def sample_function(a, b=10):
201
"""Sample function for demonstration."""
202
return a * b
203
204
# Get code object
205
code_obj = sample_function.__code__
206
207
# Extract metadata
208
filename, line_number = astor.CodeToAst.get_file_info(code_obj)
209
print(f"Function '{sample_function.__name__}' defined in:")
210
print(f" File: {filename}")
211
print(f" Line: {line_number}")
212
print(f" Arguments: {code_obj.co_varnames[:code_obj.co_argcount]}")
213
print(f" Local variables: {code_obj.co_varnames}")
214
```
215
216
### Batch File Processing
217
218
Combine file discovery with AST parsing for processing multiple files efficiently.
219
220
**Usage Example:**
221
222
```python
223
import astor
224
import ast
225
from collections import defaultdict
226
227
def analyze_project(project_path):
228
"""Analyze Python files in a project directory."""
229
stats = defaultdict(int)
230
231
for py_file in astor.CodeToAst.find_py_files(project_path):
232
try:
233
tree = astor.parse_file(py_file)
234
235
# Count different node types
236
for node in ast.walk(tree):
237
stats[type(node).__name__] += 1
238
239
except (SyntaxError, FileNotFoundError) as e:
240
print(f"Error processing {py_file}: {e}")
241
242
return dict(stats)
243
244
# Analyze a project
245
project_stats = analyze_project('./my_project')
246
print("Project AST Statistics:")
247
for node_type, count in sorted(project_stats.items()):
248
print(f" {node_type}: {count}")
249
```