CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-rope

A comprehensive Python refactoring library providing powerful and safe code transformations, analysis, and IDE integration capabilities.

Pending
Overview
Eval results
Files

change-management.mddocs/

Change Management

System for representing, combining, and applying code changes safely. Enables previewing modifications before applying them and supports undo operations through project history.

Capabilities

Change Representation

Changes represent modifications to be made to the project, providing a safe way to preview and apply code transformations.

class Change:
    """
    Base class for representing code changes.
    """
    
    def do(self):
        """
        Apply the change to the project.
        This method should not be called directly - use project.do() instead.
        """
    
    def get_description(self):
        """
        Get human-readable description of the change.
        
        Returns:
        str: Description of what this change does
        """

class ChangeSet:
    """
    Collection of multiple changes to be applied together.
    """
    
    def __init__(self, description=""):
        """
        Create a new change set.
        
        Parameters:
        - description (str): Description of the change set
        """
    
    def add_change(self, change):
        """
        Add a change to the set.
        
        Parameters:
        - change (Change): Change to add to the set
        """
    
    def do(self):
        """Apply all changes in the set."""
    
    def get_description(self):
        """Get description of all changes in the set."""

Content Changes

Modifications to file contents including text replacement and formatting changes.

class ChangeContents(Change):
    """
    Change the contents of a file.
    
    Parameters:
    - resource (Resource): File to modify
    - new_contents (str): New file contents
    - old_contents (str, optional): Expected current contents for validation
    """
    def __init__(self, resource, new_contents, old_contents=None): ...

class ChangeContentsContent(Change):
    """
    Change specific content within a file using string replacement.
    
    Parameters:
    - resource (Resource): File to modify  
    - old_content (str): Content to replace
    - new_content (str): Replacement content
    - offset (int, optional): Starting offset for change
    """
    def __init__(self, resource, old_content, new_content, offset=None): ...

Resource Changes

Operations for creating, moving, and removing files and folders.

class CreateResource(Change):
    """
    Create a new file or folder.
    
    Parameters:
    - project (Project): Project instance
    - path (str): Path for new resource
    """
    def __init__(self, project, path): ...

class CreateFile(CreateResource):
    """
    Create a new file with optional initial content.
    
    Parameters:
    - project (Project): Project instance
    - path (str): File path relative to project root
    - contents (str, optional): Initial file contents
    """
    def __init__(self, project, path, contents=""): ...

class CreateFolder(CreateResource):
    """
    Create a new folder.
    
    Parameters:
    - project (Project): Project instance
    - path (str): Folder path relative to project root
    """
    def __init__(self, project, path): ...

class RemoveResource(Change):
    """
    Remove a file or folder.
    
    Parameters:
    - project (Project): Project instance
    - path (str): Path of resource to remove
    """
    def __init__(self, project, path): ...

class MoveResource(Change):
    """
    Move or rename a file or folder.
    
    Parameters:
    - project (Project): Project instance
    - path (str): Current resource path
    - new_path (str): New resource path
    """
    def __init__(self, project, path, new_path): ...

Task Handling

Progress monitoring and cancellation support for long-running operations.

class BaseTaskHandle:
    """Abstract base class for task monitoring."""
    
    def stop(self):
        """Request task cancellation."""
    
    def is_stopped(self):
        """
        Check if task has been cancelled.
        
        Returns:
        bool: True if task should stop
        """
    
    def is_finished(self):
        """
        Check if task has completed.
        
        Returns:
        bool: True if task is finished
        """

class TaskHandle(BaseTaskHandle):
    """
    Concrete task handle for monitoring refactoring progress.
    
    Parameters:
    - name (str): Task name for display
    - cancel (callable, optional): Cancellation callback
    """
    def __init__(self, name, cancel=None): ...

class BaseJobSet:
    """Abstract base class for managing multiple jobs."""
    
    def create_job(self, name, count=None):
        """
        Create a new job within the set.
        
        Parameters:
        - name (str): Job name
        - count (int, optional): Expected number of work units
        
        Returns:
        Job instance for progress tracking
        """

class JobSet(BaseJobSet):
    """
    Concrete job set for managing multiple parallel operations.
    
    Parameters:
    - task_handle (TaskHandle): Parent task handle
    - count (int): Number of expected jobs
    """
    def __init__(self, task_handle, count): ...

class NullTaskHandle(BaseTaskHandle):
    """No-op task handle that does nothing."""
    pass

class NullJobSet(BaseJobSet):
    """No-op job set that does nothing."""
    pass

Constants

DEFAULT_TASK_HANDLE = NullTaskHandle()
"""Default task handle instance for operations without progress monitoring."""

History Management

Project history tracking for undo/redo functionality.

class History:
    """
    Project change history for undo/redo operations.
    """
    
    def do(self, changes):
        """
        Execute changes and add to history.
        
        Parameters:
        - changes (Change or ChangeSet): Changes to execute and record
        """
    
    def undo(self):
        """
        Undo the last set of changes.
        
        Returns:
        ChangeSet: Changes that were undone
        """
    
    def redo(self):
        """
        Redo previously undone changes.
        
        Returns:
        ChangeSet: Changes that were redone
        """
    
    def get_description(self):
        """Get description of current history state."""

class ChangeStack:
    """
    Stack-based change management for contrib modules.
    """
    
    def push(self, changes):
        """
        Add changes to the stack.
        
        Parameters:
        - changes (Change or ChangeSet): Changes to add
        """
    
    def pop(self):
        """
        Remove and return top changes from stack.
        
        Returns:
        Change or ChangeSet: Top changes from stack
        """
    
    def top(self):
        """
        Get top changes without removing them.
        
        Returns:
        Change or ChangeSet: Top changes from stack
        """
    
    def is_empty(self):
        """Check if stack is empty."""

Usage Examples

Basic Change Operations

from rope.base.project import Project
from rope.base.change import ChangeContents, ChangeSet, CreateFile

project = Project('/path/to/project')

try:
    # Create individual changes
    myfile = project.get_resource('mymodule.py')
    
    # Change file contents
    new_content = "# Modified content\nprint('Hello, World!')\n"
    content_change = ChangeContents(myfile, new_content)
    
    # Create a new file
    new_file_change = CreateFile(project, 'newmodule.py', '# New module\n')
    
    # Combine changes into a change set
    changes = ChangeSet("Update project files")
    changes.add_change(content_change)
    changes.add_change(new_file_change)
    
    # Preview changes
    print(f"About to apply: {changes.get_description()}")
    
    # Apply all changes
    project.do(changes)
    
finally:
    project.close()

Task Progress Monitoring

from rope.base.project import Project
from rope.base.taskhandle import TaskHandle
from rope.refactor.rename import Rename

def my_cancel_callback():
    print("Cancellation requested!")
    return True

project = Project('/path/to/project')

try:
    # Create task handle for monitoring
    task_handle = TaskHandle("Rename refactoring", my_cancel_callback)
    
    # Perform refactoring with progress monitoring
    myfile = project.get_resource('mymodule.py')
    renamer = Rename(project, myfile, 150)
    changes = renamer.get_changes('new_name', task_handle=task_handle)
    
    # Check if operation was cancelled
    if not task_handle.is_stopped():
        project.do(changes, task_handle)
        print("Refactoring completed")
    else:
        print("Refactoring cancelled")
        
finally:
    project.close()

Resource Management Changes

from rope.base.project import Project
from rope.base.change import CreateFolder, MoveResource, RemoveResource

project = Project('/path/to/project')

try:
    # Create a new package structure
    package_folder = CreateFolder(project, 'mypackage')
    init_file = CreateFile(project, 'mypackage/__init__.py', '# Package init\n')
    
    # Move existing module into package
    move_module = MoveResource(project, 'oldmodule.py', 'mypackage/module.py')
    
    # Remove obsolete file
    remove_old = RemoveResource(project, 'obsolete.py')
    
    # Apply all changes together
    changes = ChangeSet("Reorganize project structure")
    changes.add_change(package_folder)
    changes.add_change(init_file)
    changes.add_change(move_module)
    changes.add_change(remove_old)
    
    project.do(changes)
    
finally:
    project.close()

History and Undo Operations

from rope.base.project import Project
from rope.base.change import ChangeContents

project = Project('/path/to/project')

try:
    # Enable history tracking
    history = project.history
    
    # Make some changes
    myfile = project.get_resource('mymodule.py')
    original_content = myfile.read()
    
    # First change
    change1 = ChangeContents(myfile, original_content + "\n# First change")
    history.do(change1)
    
    # Second change  
    current_content = myfile.read()
    change2 = ChangeContents(myfile, current_content + "\n# Second change")
    history.do(change2)
    
    # Undo last change
    undone = history.undo()
    print(f"Undone: {undone.get_description()}")
    
    # Redo the change
    redone = history.redo()
    print(f"Redone: {redone.get_description()}")
    
finally:
    project.close()

Change Validation

from rope.base.project import Project
from rope.base.change import ChangeContents

project = Project('/path/to/project')

try:
    myfile = project.get_resource('mymodule.py')
    original_content = myfile.read()
    
    # Create change with content validation
    new_content = "# New content\nprint('Hello')\n"
    change = ChangeContents(
        myfile, 
        new_content, 
        old_contents=original_content  # Validate current content
    )
    
    try:
        project.do(change)
        print("Change applied successfully")
    except Exception as e:
        print(f"Change failed: {e}")
        
finally:
    project.close()

Install with Tessl CLI

npx tessl i tessl/pypi-rope

docs

change-management.md

code-assistance.md

error-handling.md

index.md

project-management.md

refactoring-operations.md

tile.json