CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-darker

Apply Black formatting only in regions changed since last commit

Pending
Overview
Eval results
Files

chooser.mddocs/

Line Selection Algorithm

Line selection utilities for choosing between original and reformatted code chunks based on which lines were edited. This module implements the core logic for selective formatting that only applies changes to modified regions.

Capabilities

Chunk Selection

Functions for choosing original or reformatted chunks based on edit locations.

def choose_lines(
    black_chunks: Iterable[DiffChunk],
    edit_linenums: List[int],
) -> Generator[str, None, None]:
    """
    Choose formatted chunks for edited areas, original chunks for non-edited.
    
    This is the core function that implements Darker's selective formatting logic.
    For each chunk from the formatter diff, it decides whether to use the
    original or reformatted version based on whether any edited lines
    fall within that chunk.
    
    Parameters:
    - black_chunks: Chunks from formatter showing original vs reformatted content
    - edit_linenums: List of line numbers that were edited since last commit
    
    Yields:
    Lines from either original or reformatted content based on edit locations
    """

Internal Utilities

Helper functions used by the line selection algorithm.

def _any_item_in_range(items: List[int], start: int, length: int) -> bool:
    """
    Return True if any item falls inside the slice [start : start + length].
    
    If length == 0, add one to make sure an edit at the position of an inserted
    chunk causes the reformatted version to be chosen for that chunk.
    
    Parameters:
    - items: List of line numbers to check
    - start: Start of the range to check
    - length: Length of the range (0 means single position)
    
    Returns:
    True if any items fall within the specified range
    """

Usage Examples

Basic Line Selection

from darker.chooser import choose_lines
from darkgraylib.utils import DiffChunk

# Example chunks from formatter output
chunks = [
    DiffChunk(
        1,                        # chunk starts on line 1 in original
        ['def hello():', '    pass'],  # original lines
        ['def hello() -> None:', '    pass']  # reformatted lines
    ),
    DiffChunk(
        3,                        # chunk starts on line 3 in original  
        ['print("world")'],       # original lines
        ['print("world")']        # reformatted lines (no change)
    )
]

# Lines that were edited since last commit
edited_lines = [1]  # only line 1 was modified

# Choose lines based on edits
result_lines = list(choose_lines(chunks, edited_lines))

print("Resulting code:")
for line in result_lines:
    print(line)
# Output will use reformatted version for chunk 1 (contains edit)
# and original version for chunk 3 (no edits)

Integration with Git Diff

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

# Get files modified in git
revrange = RevisionRange.parse_with_common_ancestor("HEAD", ":WORKTREE:")
modified_files = git_get_modified_python_files(["src/"], revrange, Path.cwd())

for file_path in modified_files:
    # Get edited line numbers from git
    differ = EditedLinenumsDiffer(Path.cwd(), revrange)
    
    with open(file_path) as f:
        current_content = TextDocument.from_str(f.read())
    
    edited_lines = differ.revision_vs_lines(
        Path(file_path), 
        current_content, 
        context_lines=0
    )
    
    # Assume we have formatter output chunks (from Black, Ruff, etc.)
    # formatter_chunks = get_formatter_chunks(file_path, current_content)
    
    # Choose lines based on git edits
    # selected_lines = list(choose_lines(formatter_chunks, edited_lines))
    
    print(f"File {file_path} has edits on lines: {edited_lines}")

Debugging Line Selection

import logging
from darker.chooser import choose_lines

# Enable debug logging to see selection decisions
logging.basicConfig(level=logging.DEBUG)

# The choose_lines function will log its decisions:
# - "Found edits on line X" or "Found no edits on lines X-Y" 
# - "Using N reformatted/original/unmodified lines at line X"

chunks = [...]  # your diff chunks
edited_lines = [...]  # your edited line numbers

result = list(choose_lines(chunks, edited_lines))

Install with Tessl CLI

npx tessl i tessl/pypi-darker@3.0.1

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