CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-darker

Apply Black formatting only in regions changed since last commit

Pending
Overview
Eval results
Files

diff-utilities.mddocs/

Diff Processing Utilities

Utilities for diffing text files and processing diff opcodes to extract changed line numbers and content chunks. These functions form the foundation for comparing original code with reformatted code.

Capabilities

Diff Generation

Functions for generating and processing diffs between text documents.

def diff_and_get_opcodes(src: TextDocument, dst: TextDocument) -> List[Tuple[str, int, int, int, int]]:
    """
    Generate diff opcodes between source and destination documents.
    
    Divides a diff between the original and reformatted content into 
    alternating chunks of intact (represented by the 'equal' tag) and 
    modified ('delete', 'replace' or 'insert' tag) lines.
    
    Parameters:
    - src: Source document (original content)
    - dst: Destination document (reformatted content)
    
    Returns:
    List of opcodes, where each opcode is a tuple of:
    (tag, src_start, src_end, dst_start, dst_end)
    
    Example opcode: ('replace', 0, 1, 0, 2) means replace line 0-1 in src
    with lines 0-2 in dst
    """

def opcodes_to_chunks(
    opcodes: List[Tuple[str, int, int, int, int]], 
    src: TextDocument, 
    dst: TextDocument
) -> Generator[DiffChunk, None, None]:
    """
    Convert diff opcodes into chunks with line content and offsets.
    
    Picks the lines from original and reformatted content for each opcode
    and combines line content with the 1-based line offset in the original content.
    
    Parameters:
    - opcodes: List of diff opcodes from diff_and_get_opcodes
    - src: Source document (original content)  
    - dst: Destination document (reformatted content)
    
    Yields:
    DiffChunk objects containing:
    - original_lines_offset: 1-based line number where chunk starts in original
    - original_lines: List of original line content
    - formatted_lines: List of reformatted line content
    """

Line Number Extraction

Functions for extracting changed line numbers from diff opcodes.

def opcodes_to_edit_linenums(opcodes: List[Tuple[str, int, int, int, int]]) -> List[int]:
    """
    Convert diff opcodes to a list of changed line numbers.
    
    Parameters:
    - opcodes: List of diff opcodes
    
    Returns:
    List of 1-based line numbers that were changed
    """

Usage Examples

Basic Diff Processing

from darker.diff import diff_and_get_opcodes, opcodes_to_chunks
from darkgraylib.utils import TextDocument

# Create example documents
original = TextDocument.from_lines([
    'for i in range(5): print(i)',
    'print("done")'
])

reformatted = TextDocument.from_lines([
    'for i in range(5):',
    '    print(i)', 
    'print("done")'
])

# Generate diff opcodes
opcodes = diff_and_get_opcodes(original, reformatted)
print(f"Generated {len(opcodes)} opcodes:")

for opcode in opcodes:
    tag, src_start, src_end, dst_start, dst_end = opcode
    print(f"  {tag}: src[{src_start}:{src_end}] -> dst[{dst_start}:{dst_end}]")

# Convert to chunks
chunks = list(opcodes_to_chunks(opcodes, original, reformatted))
print(f"\nGenerated {len(chunks)} chunks:")

for i, chunk in enumerate(chunks):
    print(f"  Chunk {i+1}: starts at line {chunk.original_lines_offset}")
    print(f"    Original: {chunk.original_lines}")
    print(f"    Formatted: {chunk.formatted_lines}")

Extract Changed Line Numbers

from darker.diff import diff_and_get_opcodes, opcodes_to_edit_linenums
from darkgraylib.utils import TextDocument

# Compare git working tree version with formatted version
with open("myfile.py") as f:
    current_content = TextDocument.from_str(f.read())

# Assume we have formatted content from Black/Ruff/etc
# formatted_content = apply_formatter(current_content)

# Get diff and extract changed lines
opcodes = diff_and_get_opcodes(current_content, formatted_content)
changed_lines = opcodes_to_edit_linenums(opcodes)

if changed_lines:
    print(f"Formatter would change lines: {changed_lines}")
else:
    print("No formatting changes needed")

Integration with Formatter Output

from darker.diff import diff_and_get_opcodes, opcodes_to_chunks
from darker.chooser import choose_lines
from darker.git import EditedLinenumsDiffer
from darkgraylib.utils import TextDocument
from pathlib import Path

def apply_selective_formatting(file_path: Path, original: TextDocument, formatted: TextDocument, git_edits: List[int]) -> TextDocument:
    """Apply formatting only to git-edited regions."""
    
    # Get diff chunks between original and formatted
    opcodes = diff_and_get_opcodes(original, formatted)
    chunks = list(opcodes_to_chunks(opcodes, original, formatted))
    
    # Choose lines based on git edits
    selected_lines = list(choose_lines(chunks, git_edits))
    
    # Reconstruct document
    return TextDocument.from_lines(selected_lines)

# Example usage
file_path = Path("src/module.py")
with open(file_path) as f:
    original_content = TextDocument.from_str(f.read())

# Get git edits (implementation depends on git integration)
# git_edited_lines = get_git_edited_lines(file_path)

# Apply formatter (Black, Ruff, etc.) 
# formatted_content = apply_formatter(original_content)

# Apply selective formatting
# result = apply_selective_formatting(file_path, original_content, formatted_content, git_edited_lines)

Advanced Opcode Analysis

from darker.diff import diff_and_get_opcodes

def analyze_diff_opcodes(opcodes):
    """Analyze diff opcodes to understand change patterns."""
    stats = {
        'equal': 0,    # unchanged chunks
        'delete': 0,   # deleted lines
        'insert': 0,   # inserted lines  
        'replace': 0   # modified lines
    }
    
    for tag, src_start, src_end, dst_start, dst_end in opcodes:
        stats[tag] += 1
        
        if tag == 'equal':
            print(f"Unchanged: {src_end - src_start} lines")
        elif tag == 'delete':
            print(f"Deleted: lines {src_start+1}-{src_end}")
        elif tag == 'insert':
            print(f"Inserted: {dst_end - dst_start} lines at position {src_start+1}")
        elif tag == 'replace':
            print(f"Replaced: lines {src_start+1}-{src_end} with {dst_end - dst_start} lines")
    
    return stats

# Usage
opcodes = diff_and_get_opcodes(original_doc, formatted_doc)
stats = analyze_diff_opcodes(opcodes)
print(f"Diff summary: {stats}")

Install with Tessl CLI

npx tessl i tessl/pypi-darker

docs

chooser.md

command-line.md

configuration.md

diff-utilities.md

file-utilities.md

formatters.md

git-integration.md

index.md

main-functions.md

preprocessors.md

verification.md

tile.json