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

Skip to content

Commit 49353d0

Browse files
committed
Issue #11747: Fix range formatting in context and unified diffs.
1 parent fdb2df4 commit 49353d0

3 files changed

Lines changed: 42 additions & 11 deletions

File tree

Lib/difflib.py

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

11461146

1147+
def _format_range(start, stop):
1148+
'Convert range to the "ed" format'
1149+
# Per the diff spec at http://www.unix.org/single_unix_specification/
1150+
beginning = start + 1 # lines start numbering with one
1151+
length = stop - start
1152+
if length == 1:
1153+
return '{}'.format(beginning)
1154+
if not length:
1155+
beginning -= 1 # empty ranges begin at line just before the range
1156+
return '{},{}'.format(beginning, length)
1157+
11471158
def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
11481159
tofiledate='', n=3, lineterm='\n'):
11491160
r"""
@@ -1193,9 +1204,12 @@ def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
11931204
todate = '\t{}'.format(tofiledate) if tofiledate else ''
11941205
yield '--- {}{}{}'.format(fromfile, fromdate, lineterm)
11951206
yield '+++ {}{}{}'.format(tofile, todate, lineterm)
1207+
11961208
first, last = group[0], group[-1]
1197-
i1, i2, j1, j2 = first[1], last[2], first[3], last[4]
1198-
yield '@@ -{},{} +{},{} @@{}'.format(i1+1, i2-i1, j1+1, j2-j1, lineterm)
1209+
file1_range = _format_range(first[1], last[2])
1210+
file2_range = _format_range(first[3], last[4])
1211+
yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm)
1212+
11991213
for tag, i1, i2, j1, j2 in group:
12001214
if tag == 'equal':
12011215
for line in a[i1:i2]:
@@ -1264,22 +1278,20 @@ def context_diff(a, b, fromfile='', tofile='',
12641278
yield '--- {}{}{}'.format(tofile, todate, lineterm)
12651279

12661280
first, last = group[0], group[-1]
1267-
yield '***************{}'.format(lineterm)
1281+
yield '***************' + lineterm
1282+
1283+
file1_range = _format_range(first[1], last[2])
1284+
yield '*** {} ****{}'.format(file1_range, lineterm)
12681285

1269-
if last[2] - first[1] > 1:
1270-
yield '*** {},{} ****{}'.format(first[1]+1, last[2], lineterm)
1271-
else:
1272-
yield '*** {} ****{}'.format(last[2], lineterm)
12731286
if any(tag in {'replace', 'delete'} for tag, _, _, _, _ in group):
12741287
for tag, i1, i2, _, _ in group:
12751288
if tag != 'insert':
12761289
for line in a[i1:i2]:
12771290
yield prefix[tag] + line
12781291

1279-
if last[4] - first[3] > 1:
1280-
yield '--- {},{} ----{}'.format(first[3]+1, last[4], lineterm)
1281-
else:
1282-
yield '--- {} ----{}'.format(last[4], lineterm)
1292+
file2_range = _format_range(first[3], last[4])
1293+
yield '--- {} ----{}'.format(file2_range, lineterm)
1294+
12831295
if any(tag in {'replace', 'insert'} for tag, _, _, _, _ in group):
12841296
for tag, _, _, j1, j2 in group:
12851297
if tag != 'delete':

Lib/test/test_difflib.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,22 @@ 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):
240+
# Per the diff spec at http://www.unix.org/single_unix_specification/
241+
spec = '''\
242+
Each <range> field shall be of the form:
243+
%1d", <beginning line number> if the range contains exactly one line,
244+
and:
245+
"%1d,%1d", <beginning line number>, <number of lines> otherwise.
246+
If a range is empty, its beginning line number shall be the number of
247+
the line just before the range, or 0 if the empty range starts the file.
248+
'''
249+
fmt = difflib._format_range
250+
self.assertEqual(fmt(3,3), '3,0')
251+
self.assertEqual(fmt(3,4), '4')
252+
self.assertEqual(fmt(3,5), '4,2')
253+
self.assertEqual(fmt(3,6), '4,3')
254+
self.assertEqual(fmt(0,0), '0,0')
239255

240256
def test_main():
241257
difflib.HtmlDiff._default_prefix = 0

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ Library
5555

5656
- Issue #11814: Fix likely typo in multiprocessing.Pool._terminate().
5757

58+
- Issue #11747: Fix range formatting in difflib.context_diff() and
59+
difflib.unified_diff().
60+
5861
- Issue #8428: Fix a race condition in multiprocessing.Pool when terminating
5962
worker processes: new processes would be spawned while the pool is being
6063
shut down. Patch by Charles-François Natali.

0 commit comments

Comments
 (0)