mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-01-10 23:38:08 -05:00
fix: Normalize whitespace when comparing patch context lines (#6541)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -94,12 +94,17 @@ def apply_diff(diff, text, reverse=False, use_patch=False):
|
||||
hunk=hunk,
|
||||
)
|
||||
if lines[old - 1] != line:
|
||||
raise HunkApplyException(
|
||||
'context line {n}, "{line}" does not match "{sl}"'.format(
|
||||
n=old, line=line, sl=lines[old - 1]
|
||||
),
|
||||
hunk=hunk,
|
||||
)
|
||||
# Try to normalize whitespace by replacing multiple spaces with a single space
|
||||
# This helps with patches that have different indentation levels
|
||||
normalized_line = ' '.join(line.split())
|
||||
normalized_source = ' '.join(lines[old - 1].split())
|
||||
if normalized_line != normalized_source:
|
||||
raise HunkApplyException(
|
||||
'context line {n}, "{line}" does not match "{sl}"'.format(
|
||||
n=old, line=line, sl=lines[old - 1]
|
||||
),
|
||||
hunk=hunk,
|
||||
)
|
||||
|
||||
# for calculating the old line
|
||||
r = 0
|
||||
|
||||
79
tests/unit/test_patch_whitespace.py
Normal file
79
tests/unit/test_patch_whitespace.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from openhands.resolver.patching.apply import apply_diff
|
||||
from openhands.resolver.patching.patch import parse_patch
|
||||
|
||||
|
||||
def test_patch_whitespace_mismatch():
|
||||
"""Test that the patch application succeeds even when whitespace doesn't match."""
|
||||
# Original content has a line with spaces
|
||||
original_content = """class Example:
|
||||
def method(self):
|
||||
pass
|
||||
|
||||
def another(self):
|
||||
pass"""
|
||||
|
||||
# Patch expects an empty line (no spaces)
|
||||
patch_text = """diff --git a/example.py b/example.py
|
||||
index 1234567..89abcdef 100644
|
||||
--- a/example.py
|
||||
+++ b/example.py
|
||||
@@ -2,6 +2,10 @@ class Example:
|
||||
def method(self):
|
||||
pass
|
||||
|
||||
+ new_field: str = "value"
|
||||
+
|
||||
def another(self):
|
||||
pass"""
|
||||
|
||||
patch = next(parse_patch(patch_text))
|
||||
# The patch should still work because we normalize whitespace
|
||||
new_content = apply_diff(patch, original_content)
|
||||
assert new_content == [
|
||||
'class Example:',
|
||||
' def method(self):',
|
||||
' pass',
|
||||
'',
|
||||
' new_field: str = "value"',
|
||||
'',
|
||||
' def another(self):',
|
||||
' pass',
|
||||
]
|
||||
|
||||
|
||||
def test_patch_whitespace_match():
|
||||
"""Test that the patch application succeeds when whitespace matches."""
|
||||
# Original content has an empty line (no spaces)
|
||||
original_content = """class Example:
|
||||
def method(self):
|
||||
pass
|
||||
|
||||
def another(self):
|
||||
pass"""
|
||||
|
||||
# Patch expects an empty line (no spaces)
|
||||
patch_text = """diff --git a/example.py b/example.py
|
||||
index 1234567..89abcdef 100644
|
||||
--- a/example.py
|
||||
+++ b/example.py
|
||||
@@ -2,6 +2,10 @@ class Example:
|
||||
def method(self):
|
||||
pass
|
||||
|
||||
+ new_field: str = "value"
|
||||
+
|
||||
def another(self):
|
||||
pass"""
|
||||
|
||||
patch = next(parse_patch(patch_text))
|
||||
new_content = apply_diff(patch, original_content)
|
||||
assert new_content == [
|
||||
'class Example:',
|
||||
' def method(self):',
|
||||
' pass',
|
||||
'',
|
||||
' new_field: str = "value"',
|
||||
'',
|
||||
' def another(self):',
|
||||
' pass',
|
||||
]
|
||||
Reference in New Issue
Block a user