Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9180deb

Browse files
committed
Issue 11747: Fix output format for context diffs.
1 parent 4d65224 commit 9180deb

2 files changed

Lines changed: 52 additions & 7 deletions

File tree

Lib/difflib.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,11 @@ def IS_CHARACTER_JUNK(ch, ws=" \t"):
11441144
return ch in ws
11451145

11461146

1147-
def _format_range(start, stop):
1147+
########################################################################
1148+
### Unified Diff
1149+
########################################################################
1150+
1151+
def _format_range_unified(start, stop):
11481152
'Convert range to the "ed" format'
11491153
# Per the diff spec at http://www.unix.org/single_unix_specification/
11501154
beginning = start + 1 # lines start numbering with one
@@ -1206,8 +1210,8 @@ def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
12061210
yield '+++ {}{}{}'.format(tofile, todate, lineterm)
12071211

12081212
first, last = group[0], group[-1]
1209-
file1_range = _format_range(first[1], last[2])
1210-
file2_range = _format_range(first[3], last[4])
1213+
file1_range = _format_range_unified(first[1], last[2])
1214+
file2_range = _format_range_unified(first[3], last[4])
12111215
yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm)
12121216

12131217
for tag, i1, i2, j1, j2 in group:
@@ -1222,6 +1226,22 @@ def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
12221226
for line in b[j1:j2]:
12231227
yield '+' + line
12241228

1229+
1230+
########################################################################
1231+
### Context Diff
1232+
########################################################################
1233+
1234+
def _format_range_context(start, stop):
1235+
'Convert range to the "ed" format'
1236+
# Per the diff spec at http://www.unix.org/single_unix_specification/
1237+
beginning = start + 1 # lines start numbering with one
1238+
length = stop - start
1239+
if not length:
1240+
beginning -= 1 # empty ranges begin at line just before the range
1241+
if length <= 1:
1242+
return '{}'.format(beginning)
1243+
return '{},{}'.format(beginning, beginning + length - 1)
1244+
12251245
# See http://www.unix.org/single_unix_specification/
12261246
def context_diff(a, b, fromfile='', tofile='',
12271247
fromfiledate='', tofiledate='', n=3, lineterm='\n'):
@@ -1280,7 +1300,7 @@ def context_diff(a, b, fromfile='', tofile='',
12801300
first, last = group[0], group[-1]
12811301
yield '***************' + lineterm
12821302

1283-
file1_range = _format_range(first[1], last[2])
1303+
file1_range = _format_range_context(first[1], last[2])
12841304
yield '*** {} ****{}'.format(file1_range, lineterm)
12851305

12861306
if any(tag in {'replace', 'delete'} for tag, _, _, _, _ in group):
@@ -1289,7 +1309,7 @@ def context_diff(a, b, fromfile='', tofile='',
12891309
for line in a[i1:i2]:
12901310
yield prefix[tag] + line
12911311

1292-
file2_range = _format_range(first[3], last[4])
1312+
file2_range = _format_range_context(first[3], last[4])
12931313
yield '--- {} ----{}'.format(file2_range, lineterm)
12941314

12951315
if any(tag in {'replace', 'insert'} for tag, _, _, _, _ in group):

Lib/test/test_difflib.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ def test_no_trailing_tab_on_empty_filedate(self):
236236
cd = difflib.context_diff(*args, lineterm='')
237237
self.assertEqual(list(cd)[0:2], ["*** Original", "--- Current"])
238238

239-
def test_range_format(self):
239+
def test_range_format_unified(self):
240240
# Per the diff spec at http://www.unix.org/single_unix_specification/
241241
spec = '''\
242242
Each <range> field shall be of the form:
@@ -246,13 +246,38 @@ def test_range_format(self):
246246
If a range is empty, its beginning line number shall be the number of
247247
the line just before the range, or 0 if the empty range starts the file.
248248
'''
249-
fmt = difflib._format_range
249+
fmt = difflib._format_range_unified
250250
self.assertEqual(fmt(3,3), '3,0')
251251
self.assertEqual(fmt(3,4), '4')
252252
self.assertEqual(fmt(3,5), '4,2')
253253
self.assertEqual(fmt(3,6), '4,3')
254254
self.assertEqual(fmt(0,0), '0,0')
255255

256+
def test_range_format_context(self):
257+
# Per the diff spec at http://www.unix.org/single_unix_specification/
258+
spec = '''\
259+
The range of lines in file1 shall be written in the following format
260+
if the range contains two or more lines:
261+
"*** %d,%d ****\n", <beginning line number>, <ending line number>
262+
and the following format otherwise:
263+
"*** %d ****\n", <ending line number>
264+
The ending line number of an empty range shall be the number of the preceding line,
265+
or 0 if the range is at the start of the file.
266+
267+
Next, the range of lines in file2 shall be written in the following format
268+
if the range contains two or more lines:
269+
"--- %d,%d ----\n", <beginning line number>, <ending line number>
270+
and the following format otherwise:
271+
"--- %d ----\n", <ending line number>
272+
'''
273+
fmt = difflib._format_range_context
274+
self.assertEqual(fmt(3,3), '3')
275+
self.assertEqual(fmt(3,4), '4')
276+
self.assertEqual(fmt(3,5), '4,5')
277+
self.assertEqual(fmt(3,6), '4,6')
278+
self.assertEqual(fmt(0,0), '0')
279+
280+
256281
def test_main():
257282
difflib.HtmlDiff._default_prefix = 0
258283
Doctests = doctest.DocTestSuite(difflib)

0 commit comments

Comments
 (0)