Apply Black formatting only in regions changed since last commit
—
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.
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
"""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
"""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)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}")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