Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,16 @@ def test_parse_malformed_diff_shorter_than_expected(self):
with open(utf8_file, 'r') as diff_file:
self.assertRaises(UnidiffParseError, PatchSet, diff_file)

def test_parse_target_without_source(self):
"""Parse a target file header with no preceding source header."""
# regression test for issue #148: this used to raise UnboundLocalError
for diff in ('+++ b/file\n',
'+++ b/file\n@@ -0,0 +1 @@\n+a\n',
'some preamble\n+++ b/file\n'):
with self.assertRaises(UnidiffParseError) as cm:
PatchSet(diff)
self.assertIn('Target without source', str(cm.exception))

def test_from_filename_with_cr_in_diff_text_files(self):
"""Parse git diff text files that contain CR"""
utf8_file = os.path.join(self.samples_dir, 'samples/git_cr.diff')
Expand Down
10 changes: 10 additions & 0 deletions unidiff/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@ def _parse(self, diff: Iterable, encoding: Optional[str],
metadata_only: bool) -> None:
current_file = None
patch_info = None
# pending source file header details, consumed by the target header
source_file = None
source_timestamp = None

diff_lines = enumerate(diff, 1)
for diff_line_no, line in diff_lines:
Expand Down Expand Up @@ -552,13 +555,20 @@ def _parse(self, diff: Iterable, encoding: Optional[str],
if current_file is not None and not (current_file.target_file == target_file):
raise UnidiffParseError('Target without source: %s' % line)
if current_file is None:
if source_file is None:
# a target header requires a preceding source header
raise UnidiffParseError(
'Target without source: %s' % line)
# add current file to PatchSet
current_file = PatchedFile(
patch_info, source_file, target_file,
source_timestamp, target_timestamp,
diff_line_no=diff_line_no)
self.append(current_file)
patch_info = None
# the source header has been consumed by this file
source_file = None
source_timestamp = None
else:
current_file.target_timestamp = target_timestamp
continue
Expand Down
Loading