The Class API extends the Symbol API to support methods, attributes, and inheritance hierarchies.
Methods and Method Usages
Classes provide access to their methods and method usages through an intuitive API:
# Access methods
for method in class_def.methods:
print(f"Method: {method.name}")
# Find all usages of this method
for usage in method.usages:
print(f"Used in {usage.file.name}")
# Get specific methods
init_method = class_def.constructor # Get __init__ method
process_method = class_def.get_method("process_data")
# Filter methods
public_methods = class_def.methods(private=False) # Exclude private methods
regular_methods = class_def.methods(magic=False) # Exclude magic methods
Class Attributes
Attributes can be accessed and modified easily:
# Access all attributes
for attr in class_def.attributes:
print(f"Attribute: {attr.name}")
# Add new attributes
class_def.add_attribute_from_source("count: int = 0")
# Get specific attribute
name_attr = class_def.get_attribute("name")
# Add attribute from another class
other_class = codebase.get_class("OtherClass")
class_def.add_attribute(
other_class.get_attribute("config"),
include_dependencies=True # Also adds required imports
)
Manipulating Attributes
Attributes expose their own API for modification and analysis:
# Modify attribute values and types
attr = class_def.get_attribute("count")
attr.set_value("42") # Change value
attr.assignment.set_type_annotation("float") # Change type
attr.assignment.type.remove() # Remove type annotation
# Find attribute usages
for usage in attr.usages:
print(f"Used in {usage.file.name}")
# Find local usages (within the class)
for usage in attr.local_usages:
print(f"Used in method: {usage.parent_function.name}")
# Rename attributes (updates all references)
attr.rename("new_name") # Also updates self.count -> self.new_name
# Remove attributes
attr.remove() # Removes the attribute definition
# Check attribute properties
if attr.is_private: # Starts with underscore
print("Private attribute")
if attr.is_optional: # Optional[Type] or Type | None
print("Optional attribute")
# Access underlying value
if attr.value: # The expression assigned to the attribute
print(f"Default value: {attr.value.source}")
Attribute operations automatically handle all references, including
self.attribute
usages in methods and string references.
Working with Inheritance
You can navigate inheritance hierarchies with APIs including:
class_def = codebase.get_class("Cube")
# View ancestors
all_ancestors = class_def.superclasses # All classes inherited
immediate_parents = class_def.superclasses(max_depth=1) # Direct parents only
# Inheritance-aware method lookup
method = class_def.get_method("process") # Searches up inheritance chain
if method.parent_class != class_def:
print(f"Method inherited from {method.parent_class.name}")
# Handle external dependencies
if class_def.is_subclass_of("Enum"): # Works with stdlib/external classes
print("This is an enum class")
Likewise, you can modify inheritance by accessing:
Which return lists of Name objects.
# Modify inheritance
parent_names = class_def.parent_class_names
if parent_names[0] == 'BaseClass':
parent_names[0].edit("NewBaseClass") # Change parent class
# Get specific parent class
parent_class = class_def.get_parent_class("BaseClass")
if parent_class:
parent_class.edit("NewBaseClass") # Change parent class
When working with inheritance, use max_depth
to control how far up the
inheritance chain to look. max_depth=0
means current class only,
max_depth=None
means traverse entire hierarchy.
Codegen handles both internal and external parent classes (like stdlib
classes). The superclasses
property follows the language’s MRO rules for
method resolution.
Method Resolution Order (MRO)
Codegen follows the target language’s method resolution order (MRO) for inheritance:
# Access superclasses
for parent in class_def.superclasses:
print(f"Parent: {parent.name}")
# Check inheritance
if class_def.is_subclass_of("BaseClass"):
print("This is a subclass of BaseClass")
# Get all subclasses
for child in class_def.subclasses:
print(f"Child class: {child.name}")
# Access inherited methods/attributes
all_methods = class_def.methods(max_depth=None) # Include inherited methods
all_attrs = class_def.attributes(max_depth=None) # Include inherited attributes