The Symbol is the primary way developers interact with code in Codegen. It maps to how developers think about code - as functions, classes, variables, and other named entities.
Both the Function and Class symbols are subclasses of the Symbol class.
Accessing Symbols
The Codebase class provides getters and iterators for functions, classes and symbols:
# Core symbol types
symbol = codebase.get_symbol("process_data") # will return a Function, Class, etc.
function = codebase.get_function("process_data")
class_def = codebase.get_class("DataProcessor")
# Iterate over all symbols (includes functions + classes)
for symbol in codebase.symbols:
print(symbol.name)
# Iterate over all functions and classes
for symbol in codebase.functions + codebase.classes:
print(symbol.name)
Shared APIs
All symbols share common APIs for manipulation:
Name operations
# Name operations
print(symbol.name)
symbol.rename("new_name")
# Source code
print(symbol.source) # Get source code
symbol.edit("new source code") # Modify source
# Documentation
print(symbol.docstring) # Get docstring
symbol.set_docstring("New documentation")
# Move symbol to new file
symbol.move_to_file(new_file)
# Add before/after other symbols
symbol.insert_before("# deprecated")
symbol.insert_after("# end deprecated")
Function Statement Manipulation
Functions provide special APIs for adding statements to their body:
# Add statements at the start of a function
function.prepend_statements("print('Starting function')")
method.prepend_statements("self.validate_input()")
# Add statements at the end of a function
function.add_statements("print('Done')")
method.add_statements("return self.result")
The statement manipulation APIs (prepend_statements and add_statements)
are only available on Function objects. For other symbols, use the general
Editable APIs like insert_before and insert_after.
Common Patterns
Most Graph-sitter programs focus on finding and manipulating symbols:
# Find and modify functions
for function in codebase.functions:
if function.name.startswith("old_"):
# Rename function
function.rename(function.name.replace("old_", "new_"))
# Update docstring
function.set_docstring("Updated version of function")
# Update class methods
for method in class_def.methods:
# Add logging
method.prepend_statements("logger.info('Called {}'".format(method.name))
The Symbol API is designed to be intuitive and match how developers think
about code. Most transformations start with finding relevant symbols and then
applying changes to them.