import difflib import whatthepatch def get_diff(old_contents: str, new_contents: str, filepath: str = "file") -> str: diff = list( difflib.unified_diff( old_contents.split("\n"), new_contents.split("\n"), fromfile=filepath, tofile=filepath, # do not output unchange lines # because they can cause `parse_diff` to fail n=0, ) ) return "\n".join(map(lambda x: x.rstrip(), diff)) def parse_diff(diff_patch: str) -> list[whatthepatch.patch.Change]: # handle empty patch if diff_patch.strip() == "": return [] patch = whatthepatch.parse_patch(diff_patch) patch_list = list(patch) assert len(patch_list) == 1, ( "parse_diff only supports single file diff. But got:\nPATCH:\n" + diff_patch + "\nPATCH LIST:\n" + str(patch_list) ) changes = patch_list[0].changes # ignore changes that are the same (i.e., old_lineno == new_lineno) output_changes = [] for change in changes: if change.old != change.new: output_changes.append(change) return output_changes