From bf8dcd2ba82953118abbe591dcb86874404611c7 Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Sun, 13 Sep 2026 12:14:12 -0300 Subject: [PATCH] Handle binary diffs without a target filename --- tests/test_parser.py | 18 ++++++++++++++++++ unidiff/patch.py | 5 ++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/test_parser.py b/tests/test_parser.py index 432d9fb..0be3177 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -361,6 +361,24 @@ def test_parse_diff_with_new_and_modified_binary_files(self): self.assertFalse(res[4].is_binary_file) self.assertEqual(res[4].diff_line_no, 15) + def test_parse_binary_diff_without_target_filename(self): + # hg emits "Binary file X has changed", with no target filename; + # both sides should then refer to the same file + diff = ( + 'diff -r a1b2c3d4 image.png\n' + 'Binary file image.png has changed\n' + ) + res = PatchSet(diff) + + self.assertEqual(len(res), 1) + self.assertTrue(res[0].is_binary_file) + self.assertEqual(res[0].source_file, 'image.png') + self.assertEqual(res[0].target_file, 'image.png') + self.assertFalse(res[0].is_rename) + self.assertEqual(res[0].path, 'image.png') + # the diff still round-trips + self.assertEqual(str(res), diff) + def test_parse_debdiff_binary_file_line_numbers(self): # issue #122 / PR #123: a binary change without hunks should still # expose the diff line number where its entry appears. diff --git a/unidiff/patch.py b/unidiff/patch.py index 3cb87f0..efba616 100644 --- a/unidiff/patch.py +++ b/unidiff/patch.py @@ -596,7 +596,10 @@ def _parse(self, diff: Iterable, encoding: Optional[str], is_binary_diff = RE_BINARY_DIFF.match(line) if is_binary_diff: source_file = is_binary_diff.group('source_filename') - target_file = is_binary_diff.group('target_filename') + # formats like hg's "Binary file X has changed" carry no + # target filename; both sides refer to the same file + target_file = (is_binary_diff.group('target_filename') + or source_file) patch_info.append(line) if current_file is not None: current_file.is_binary_file = True