Read/rewrite/write Python ASTs
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
Parse Python files directly into AST representations with support for standard input and file path resolution.
def parse_file(fname):
"""
Parse Python file into AST.
Parameters:
- fname: str, filename to parse (or 'stdin' for standard input)
Returns:
AST object representing the parsed Python code
Raises:
SyntaxError: If the file contains invalid Python syntax
FileNotFoundError: If the specified file does not exist
"""Usage Example:
import astor
# Parse a Python file
tree = astor.parse_file('my_script.py')
print(astor.dump_tree(tree))
# Parse from standard input
tree = astor.parse_file('stdin') # Read from stdin
# Convert parsed file back to source
source = astor.to_source(tree)
print(source)Advanced class for converting modules and functions to AST with caching support and metadata extraction.
class CodeToAst:
"""
Convert modules/functions to AST with caching support.
Provides efficient conversion of code objects to AST representations
with optional caching for improved performance.
"""
def __init__(self, cache=None):
"""
Initialize with optional cache.
Parameters:
- cache: dict, optional cache for storing parsed results (default: None)
"""
def __call__(self, codeobj):
"""
Convert code object to AST.
Parameters:
- codeobj: code object to convert to AST
Returns:
AST object representing the code
"""
@staticmethod
def parse_file(fname):
"""
Parse Python file to AST.
Parameters:
- fname: str, filename to parse
Returns:
AST object representing the parsed file
"""
@staticmethod
def find_py_files(srctree, ignore=None):
"""
Find Python files in directory tree.
Parameters:
- srctree: str, root directory to search
- ignore: set, filenames to ignore (default: None)
Returns:
Generator yielding Python file paths
"""
@staticmethod
def get_file_info(codeobj):
"""
Get file and line info from code object.
Parameters:
- codeobj: code object to extract info from
Returns:
tuple: (filename, line_number) information
"""Usage Example:
import astor
import types
# Create CodeToAst instance with caching
converter = astor.CodeToAst(cache={})
# Convert a function to AST
def example_function(x, y):
return x + y
code_obj = example_function.__code__
ast_tree = converter(code_obj)
print(astor.dump_tree(ast_tree))
# Find all Python files in a directory
py_files = list(astor.CodeToAst.find_py_files('./src', ignore={'__pycache__'}))
print(f"Found {len(py_files)} Python files")
# Get file information from code object
filename, line_num = astor.CodeToAst.get_file_info(code_obj)
print(f"Function defined in {filename} at line {line_num}")Pre-configured instance of CodeToAst for convenient file parsing operations.
code_to_ast: CodeToAstThis is a default instance that can be used directly without initialization:
import astor
# Use the default instance
tree = astor.code_to_ast.parse_file('example.py')
# Convert code object using default instance
def my_func():
pass
ast_tree = astor.code_to_ast(my_func.__code__)Utilities for systematically finding and processing Python source files in directory hierarchies.
Usage Example:
import astor
import os
# Find all Python files in a project
project_root = './my_project'
ignore_dirs = {'__pycache__', '.git', 'venv'}
for py_file in astor.CodeToAst.find_py_files(project_root, ignore=ignore_dirs):
print(f"Processing: {py_file}")
try:
tree = astor.parse_file(py_file)
# Process the AST
print(f" Functions: {len([n for n in ast.walk(tree) if isinstance(n, ast.FunctionDef)])}")
print(f" Classes: {len([n for n in ast.walk(tree) if isinstance(n, ast.ClassDef)])}")
except SyntaxError as e:
print(f" Syntax error: {e}")Extract useful metadata from Python code objects for analysis and debugging.
Usage Example:
import astor
import inspect
def sample_function(a, b=10):
"""Sample function for demonstration."""
return a * b
# Get code object
code_obj = sample_function.__code__
# Extract metadata
filename, line_number = astor.CodeToAst.get_file_info(code_obj)
print(f"Function '{sample_function.__name__}' defined in:")
print(f" File: {filename}")
print(f" Line: {line_number}")
print(f" Arguments: {code_obj.co_varnames[:code_obj.co_argcount]}")
print(f" Local variables: {code_obj.co_varnames}")Combine file discovery with AST parsing for processing multiple files efficiently.
Usage Example:
import astor
import ast
from collections import defaultdict
def analyze_project(project_path):
"""Analyze Python files in a project directory."""
stats = defaultdict(int)
for py_file in astor.CodeToAst.find_py_files(project_path):
try:
tree = astor.parse_file(py_file)
# Count different node types
for node in ast.walk(tree):
stats[type(node).__name__] += 1
except (SyntaxError, FileNotFoundError) as e:
print(f"Error processing {py_file}: {e}")
return dict(stats)
# Analyze a project
project_stats = analyze_project('./my_project')
print("Project AST Statistics:")
for node_type, count in sorted(project_stats.items()):
print(f" {node_type}: {count}")Install with Tessl CLI
npx tessl i tessl/pypi-astor