Python

Parse a py file read the AST modify it then write back the modified source code

25 September 2026 · 8 min read

Parse a py file read the AST modify it then write back the modified source code

Python’s versatility stems in part from its ability to introspect and manipulate its own code. Programmatically understanding and modifying Python source is a powerful technique. This article explores the process of how to parse a .py file, read its Abstract Syntax Tree (AST), modify it, and then write back the modified source code. By leveraging Python’s built-in ast module, developers can automate code transformations, perform static analysis, and even build code generation tools. This capability opens doors to advanced programming paradigms like metaprogramming and domain-specific language creation. Understanding these techniques is crucial for tasks ranging from simple code refactoring to building complex development tools.

Understanding the Abstract Syntax Tree (AST)

The Abstract Syntax Tree (AST) is a tree representation of the abstract syntactic structure of source code written in a programming language. Each node of the tree denotes a construct occurring in the source code. The syntax is ‘abstract’ in the sense that it does not represent every detail appearing in the real syntax, but rather just the structural and content-related details. For Python, the ast module provides the tools to generate and manipulate these trees. Understanding the AST is fundamental to modifying code programmatically because it allows you to work with the code’s logical structure rather than its raw text.

When you parse a .py file using the ast module, Python analyzes the source code and generates an AST. This AST breaks down the code into its constituent parts, such as function definitions, variable assignments, loops, and conditional statements. Each of these elements becomes a node in the tree, with relationships between nodes reflecting the code’s structure. For instance, a function definition node will have child nodes representing the function’s name, arguments, and body. Examining the AST reveals how Python interprets and organizes your code, enabling targeted modifications. Consider this simple function:

def add(x, y): return x + y 

The AST for this function would contain nodes representing the function definition (FunctionDef), the function name (add), the arguments (x and y), and the return statement (Return), along with the addition operation (BinOp). You can visualize this structure using tools like AST visualizers or by printing the AST using ast.dump(). According to the Python documentation, “The ast module helps Python applications to process trees of the Python abstract syntax grammar.” Python AST Documentation

Parsing a .py File and Reading the AST

The first step in programmatically modifying Python code is to parse a .py file and read its Abstract Syntax Tree (AST). Python’s ast module simplifies this process, providing functions to parse source code and generate the corresponding AST. The ast.parse() function takes a string of Python code as input and returns an AST object representing the parsed code. You can also use ast.parse with open() to read directly from a .py file.

Here’s how you can parse a .py file and explore its AST:

  1. Read the .py file: Open the file in read mode and read its contents into a string.
  2. Parse the code: Use ast.parse() to generate the AST from the code string.
  3. Explore the AST: Use functions like ast.dump() to print a representation of the AST, or traverse the tree manually to examine specific nodes.

For example:

import ast with open('my_script.py', 'r') as f: code = f.read() tree = ast.parse(code) print(ast.dump(tree)) 

This code snippet reads the contents of my_script.py, parses it into an AST, and then prints a detailed representation of the AST to the console. Analyzing the output of ast.dump() will help you understand the structure of the AST and identify the nodes you want to modify. Understanding how to traverse the AST allows for targeted modifications. Tools such as Green Tree Snakes can further assist in simplifying AST manipulations.

Modifying the AST

Once you have the AST representation of your Python code, you can begin modifying it to achieve your desired transformations. The ast module provides classes representing various AST nodes, allowing you to create new nodes, modify existing ones, and insert or delete nodes from the tree. This is where the real power of programmatic code manipulation becomes apparent. You can automate refactoring tasks, inject debugging code, or even rewrite entire sections of code based on specific criteria.

To modify the AST, you typically traverse the tree, identify the nodes you want to change, and then use the ast module’s classes to create or modify those nodes. For instance, you can replace a variable assignment with a different value, insert a print statement before a function call, or even completely rewrite a function’s body. Consider adding a simple print statement to the beginning of every function. This can be achieved by identifying FunctionDef nodes and inserting a Print node at the beginning of the function body. According to a study by Sourcegraph, automated code refactoring can reduce technical debt by up to 30%. Sourcegraph Technical Debt Survey

Here are some common AST modification techniques:

  • Node Replacement: Replace one node with another using assignment.
  • Node Insertion: Insert a new node into the tree structure, often within a list of statements.
  • Node Deletion: Remove a node from the tree structure.

Remember to carefully consider the impact of your modifications on the overall code structure and functionality. Incorrect modifications can lead to syntax errors or unexpected behavior. Always test your changes thoroughly after modifying the AST.

Writing Back the Modified Source Code

After modifying the AST, the final step is to write back the modified source code to a .py file. Python’s ast module provides the ast.unparse() function (available in Python 3.9 and later) for this purpose. This function takes an AST object as input and returns a string containing the corresponding Python code. For older versions, libraries like astor can be used to achieve the same result. It’s crucial to ensure that the unparsed code is syntactically correct and semantically equivalent to the modified AST.

Here’s how you can write back the modified source code:

  • Unparse the AST: Use ast.unparse() (or astor.to_source() for older versions) to generate a string of Python code from the modified AST.
  • Write to file: Open the .py file in write mode and write the generated code string to the file.

For example:

import ast import astor If using Python < 3.9 Assuming 'tree' is your modified AST modified_code = ast.unparse(tree) ast.unparse available after python 3.9 modified_code = astor.to_source(tree) Use astor for older versions with open('modified_script.py', 'w') as f: f.write(modified_code) 

This code snippet unparses the modified AST into a string and then writes that string to a new file named modified_script.py. The resulting file contains the transformed code, reflecting the modifications you made to the AST. Ensure proper error handling and validation to avoid writing invalid code. You may also want to consider preserving code formatting and comments during the transformation process using tools designed for code style preservation.

This process allows for complete programmatic control over the source code. Careful planning and robust testing are crucial to ensuring that the transformed code functions correctly and meets the intended requirements. The ability to parse a .py file, modify it, and write it back programmatically opens up a wide range of possibilities for automating code management and enhancement.

Infographic here
FAQ ---
What is the primary advantage of using the AST for code modification?
The primary advantage is that you're working with the code's structure rather than raw text, making modifications more reliable and less prone to errors.
What Python version is required for ast.unparse()?
ast.unparse() is available in Python 3.9 and later. For older versions, you can use the astor library.
Can I use this technique to refactor large codebases?
Yes, this technique is suitable for refactoring large codebases, but careful planning and thorough testing are essential.
The ability to **parse a .py file**, manipulate its AST, and regenerate the source code is a powerful tool for any Python developer. It allows for automated refactoring, code generation, and advanced static analysis. While the process can seem complex initially, understanding the basics of the ast module unlocks a new level of control over your code. Start experimenting with simple transformations and gradually explore more complex scenarios.

Further explore AST transformations with real-world examples.Ready to take your Python skills to the next level? Dive into the world of AST manipulation and discover the power of programmatic code transformation. Start with a simple project, such as automating a repetitive refactoring task, and gradually expand your knowledge. The possibilities are endless, and the rewards are significant.

Question & Answer :
I want to programmatically edit python source code. Basically I want to read a .py file, generate the AST, and then write back the modified python source code (i.e. another .py file).

There are ways to parse/compile python source code using standard python modules, such as ast or compiler. However, I don’t think any of them support ways to modify the source code (e.g. delete this function declaration) and then write back the modifying python source code.

UPDATE: The reason I want to do this is I’d like to write a Mutation testing library for python, mostly by deleting statements / expressions, rerunning tests and seeing what breaks.

Pythoscope does this to the test cases it automatically generates as does the 2to3 tool for python 2.6 (it converts python 2.x source into python 3.x source).

Both these tools uses the lib2to3 library which is an implementation of the python parser/compiler machinery that can preserve comments in source when it’s round tripped from source -> AST -> source.

The rope project may meet your needs if you want to do more refactoring like transforms.

The ast module is your other option, and there’s an older example of how to “unparse” syntax trees back into code (using the parser module). But the ast module is more useful when doing an AST transform on code that is then transformed into a code object.

The redbaron project also may be a good fit (ht Xavier Combelle)