Rope
Rope is an advanced, open-source Python refactoring library. It provides extensive APIs for performing various code transformations like renaming, extracting methods, and moving elements. Actively maintained, it sees regular updates with recent releases like 1.14.0, and supports modern Python versions.
Warnings
- breaking Rope versions 1.0.0 and above no longer support Python 2. Users requiring Python 2 compatibility must use 0.x.x releases or the `python2` branch.
- gotcha By default, Rope creates a `.ropeproject` folder in the project root to store configuration and data (e.g., history, object information). This folder can be configured or disabled via the `ropefolder` parameter in the `Project` constructor.
- gotcha As of version 1.12.0, Rope no longer includes `site-packages` in its default search tree for modules. This might affect auto-import suggestions or object inference for packages not explicitly within the defined project source folders.
- gotcha Version 1.13.0 introduced validation to prevent renaming a symbol to a Python keyword. While a safety enhancement, this changes previous behavior that might have allowed such renames (which would lead to syntax errors).
Install
-
pip install rope
Imports
- Project
from rope.base.project import Project
- File
from rope.base.resources import File
- Rename
from rope.refactor.rename import Rename
Quickstart
import os
import tempfile
import shutil
from pathlib import Path
from rope.base.project import Project
from rope.base.resources import File
from rope.refactor.rename import Rename
# Create a temporary directory and a dummy Python file
temp_dir = Path(tempfile.mkdtemp())
file_path = temp_dir / "my_module.py"
file_path.write_text("""
def greet():
old_name = "World"
print(f"Hello, {old_name}!")
""")
project = Project(temp_dir)
resource = project.get_resource(file_path.name)
# Find the start offset of 'old_name'
# In ' old_name = "World"', 'old_name' starts at index 5
offset = file_path.read_text().find('old_name = "World"') + 4
# Perform rename refactoring
changes = Rename(project, resource, offset).get_changes('new_name')
# Apply the changes to the project files
project.do(changes)
# Verify the change
print(file_path.read_text())
# Clean up
project.close()
shutil.rmtree(temp_dir)