ast

Updated March 13, 2026 · Modules
stdlib parsing ast abstract-syntax-tree code-analysis

The ast module lets you parse Python source code into an Abstract Syntax Tree (AST). Each node in the tree represents a construct in the source code — expressions, statements, functions, classes, and so on. This is the same parsing that Python’s compiler uses internally, so you can inspect and transform code programmatically.

Main Functions

ast.parse()

Parses source code into an AST. This is the entry point for most ast operations.

import ast

source = """
def greet(name):
    return f"Hello, {name}!"
"""

tree = ast.parse(source)
print(ast.dump(tree))
# Module(body=[FunctionDef(name='greet', args=arguments(...), body=[Return(...)])])

Parameters:

ParameterTypeDefaultDescription
sourcestrThe Python source code to parse
modestr"exec"Parse mode: "exec" for module, "eval" for expressions, "single" for interactive
filenamestr"<unknown>"Filename for error reporting
type_commentsboolFalseWhether to parse type comments

Returns: A Module node containing the parsed AST.

ast.literal_eval()

Safely evaluates a string containing a Python literal or container display. Unlike eval(), this only allows literals — numbers, strings, lists, tuples, dicts, sets, booleans, and None.

import ast

# Safe evaluation of literals
result = ast.literal_eval("[1, 2, {'a': 3}]")
print(result)
# [1, 2, {'a': 3}]

# This would be dangerous with eval, but safe with literal_eval
json_string = '{"key": [1, 2, 3], "nested": {"x": true}}'
data = ast.literal_eval(json_string)
print(data)
# {'key': [1, 2, 3], 'nested': {'x': True}}

Parameters:

ParameterTypeDefaultDescription
node_or_stringstrA string containing a Python literal

Returns: The evaluated Python object.

ast.walk()

Generates all nodes in the tree, recursively, including the node itself.

import ast

source = """
def example():
    x = 1 + 2
    y = [i for i in range(10)]
    return x + sum(y)
"""

tree = ast.parse(source)

for node in ast.walk(tree):
    print(type(node).__name__)
# Module, FunctionDef, arguments, arg, Assign, AugAssign, Name, Constant, comprehension...

ast.dump()

Returns a formatted string representation of the AST. Useful for debugging.

import ast

tree = ast.parse("x = 1 + 2")
print(ast.dump(tree, indent=2))
# Module(
#   body=[
#     Assign(
#       targets=[Name(id='x', ctx=Store())],
#       value=BinOp(
#         left=Constant(value=1),
#         op=Add(),
#         right=Constant(value=2)
#       )
#     )
#   ]
# )

ast.fix_missing_locations()

Populates nodes that have lineno and col_offset set to None. Useful when you modify or create AST nodes and want them to have valid line numbers.

import ast

# Create a simple expression
expr = ast.Expression(body=ast.Constant(value=42))

# Fix missing locations
ast.fix_missing_locations(expr)

# Now we can compile it
code = compile(expr, '<string>', 'eval')
print(eval(code))
# 42

ast.increment_lineno()

Increments the line numbers of all nodes by a given offset. Useful when generating code from snippets.

import ast

source = "x = 1\ny = 2"
tree = ast.parse(source)

# Increment line numbers by 10
ast.increment_lineno(tree, 10)

print(tree.body[0].lineno)  # 11
print(tree.body[1].lineno)  # 12

Common Patterns

Inspecting function definitions

import ast

source = """
def add(a, b):
    '''Add two numbers'''
    return a + b
"""

tree = ast.parse(source)
func = tree.body[0]

print(f"Function name: {func.name}")
print(f"Arguments: {[arg.arg for arg in func.args.args]}")
print(f"Docstring: {ast.get_docstring(func)}")
# Function name: add
# Arguments: ['a', 'b']
# Docstring: Add two numbers

Finding all function calls

import ast

source = """
def process():
    result = calculate(x, y)
    print(result)
    return result * 2
"""

class FunctionCallFinder(ast.NodeVisitor):
    def visit_Call(self, node):
        print(f"Found call: {ast.unparse(node)}")
        self.generic_visit(node)

tree = ast.parse(source)
finder = FunctionCallFinder()
finder.visit(tree)
# Found call: calculate(x, y)
# Found call: print(result)
# Found call: result * 2

Transforming code programmatically

import ast

source = "x = 1 + 2"

class AddToMultiply(ast.NodeTransformer):
    def visit_BinOp(self, node):
        if isinstance(node.op, ast.Add):
            node.op = ast.Mult()
        return self.generic_visit(node)

tree = ast.parse(source)
transformed = AddToMultiply().visit(tree)

# Compile and run the transformed code
code = compile(ast.fix_missing_locations(ast.Module(body=transformed.body)), '<string>', 'exec')
exec(code)
print(x)  # 2 (1 * 2 instead of 1 + 2)

Validating syntax without executing

import ast

def is_valid_python(code: str) -> bool:
    try:
        ast.parse(code)
        return True
    except SyntaxError:
        return False

print(is_valid_python("x = 1 + 2"))  # True
print(is_valid_python("x = 1 +"))     # False

AST Node Classes

The ast module defines many node classes. Common ones include:

NodeRepresents
ModuleA complete module
FunctionDefA function definition
AsyncFunctionDefAn async function definition
ClassDefA class definition
AssignAn assignment statement
AugAssignAn augmented assignment (+=, -=, etc.)
ReturnA return statement
CallA function call
NameA variable name
ConstantA literal value
BinOpA binary operation (+, -, *, /)
UnaryOpA unary operation (-, +, not)
IfAn if statement
ForA for loop
WhileA while loop

See Also