Modifying Code¶
Once you've found code elements, you can transform them.
Class Operations¶
Renaming¶
Adding Methods¶
cls = rj.file("models.py").find_class("User")
# Simple method
cls.add_method("validate", body="return True")
# With parameters and return type
# `params` lists the parameters after `self` (which is added automatically)
cls.add_method(
"get_display_name",
params="include_title: bool = False",
return_type="str",
body="return f'{self.first_name} {self.last_name}'"
)
# With decorator
cls.add_method(
"cached_value",
body="return self._compute()",
decorators=["@cached_property"]
)
Adding Attributes¶
cls.add_attribute("created_at", type_hint="datetime", default="None")
cls.add_attribute("MAX_RETRIES", type_hint="int", default="3")
Adding Decorators¶
Removing Decorators¶
Inheritance¶
Deleting¶
Duplicating¶
Method Operations¶
Renaming¶
Adding Decorators¶
Removing Decorators¶
Inserting Statements¶
# At the start of the method body
method.insert_statement("self.validate()", position="start")
# At the end of the method body
method.insert_statement("self.log_action()", position="end")
Parameters¶
# Add a parameter
method.add_parameter("timeout", type_annotation="int", default_value="30")
# Remove a parameter
method.remove_parameter("deprecated_arg")
# Rename a parameter
method.rename_parameter("old_name", "new_name")
Type Hints¶
method.set_return_type("list[str]")
method.set_parameter_type("data", "dict[str, Any]")
method.remove_type_hints() # Strip all type annotations
Deleting¶
Extracting to Function¶
Function Operations¶
Functions support the same operations as methods:
func = rj.file("utils.py").find_function("process")
func.rename("process_data")
func.add_decorator("lru_cache")
func.insert_statement("logger.debug('Starting')", position="start")
func.add_parameter("verbose", type_annotation="bool", default_value="False")
func.set_return_type("ProcessResult")
func.delete()
File Operations¶
Adding Imports¶
file = rj.file("mymodule.py")
file.add_import("from typing import Optional")
file.add_import("import json")
file.add_import("from myapp.utils import helper")
Organizing Imports¶
file.organize_imports() # Sort and group imports
file.remove_unused_imports() # Remove imports not used in file
file.add_missing_imports() # Add imports for undefined names
Converting Import Styles¶
file.convert_relative_to_absolute() # from .utils → from mypackage.utils
file.convert_absolute_to_relative() # from mypackage.utils → from .utils
Adding Functions/Classes¶
Async Conversions¶
func = rj.find_functions("fetch_data").first()
# Convert sync to async
func.convert_to_async()
# Convert async to sync
func.convert_to_sync()
Docstrings¶
Generating¶
func.generate_docstring(style="google") # or "numpy", "sphinx"
cls.generate_docstrings() # Generate for all methods
Updating¶
method.update_docstring_param("timeout", "Maximum wait time in seconds")
method.add_docstring_raises("ValueError", "If input is negative")
method.add_docstring_example(">>> process(5)\\n10")
method.add_docstring_returns("The processed result")
Converting Styles¶
Type Hint Modernization¶
# Modernize type hints (Python 3.10+ style)
file.modernize_type_hints() # List[str] → list[str], Optional[X] → X | None
# Convert type comments to annotations
file.convert_type_comments_to_annotations() # # type: str → : str
Class Conversions¶
cls = rj.find_classes("Config").first()
# Convert to dataclass
cls.convert_to_dataclass()
# Convert from dataclass
cls.convert_from_dataclass()
# Other conversions
cls.convert_to_typed_dict()
cls.convert_to_named_tuple()
Generating Dunder Methods¶
cls.generate_init()
cls.generate_repr()
cls.generate_eq()
cls.generate_hash()
cls.generate_all_dunders() # All of the above
Properties¶
# Convert attribute to property
cls.convert_attribute_to_property("_name", getter=True, setter=True)
# Add a computed property
cls.add_property("full_name", getter="return f'{self.first} {self.last}'")
Converting Format Strings¶
File-level helpers convert old-style string formatting to f-strings:
file = rj.file("legacy_module.py")
# "Hello {}".format(name) → f"Hello {name}"
file.convert_format_strings_to_fstrings()
# "Hello %s" % name → f"Hello {name}"
file.convert_percent_format_to_fstrings()
Result Handling¶
All operations return a Result:
result = cls.rename("NewName")
if result:
print(f"Modified: {result.files_changed}")
else:
print(f"Failed: {result.message}")
if result.exception:
result.raise_if_error() # Re-raise if you want
Next Steps¶
- Line Operations — Work with specific lines
- Batch Operations — Apply changes to multiple targets
- Error Handling — Handle failures gracefully