[Python-checkins] cpython (3.2): Issue 11747: Fix output format for context diffs.

raymond.hettinger python-checkins at python.org
Wed Apr 13 00:26:13 CEST 2011


http://hg.python.org/cpython/rev/e3387295a24f
changeset:   69278:e3387295a24f
branch:      3.2
parent:      69273:4254085bae84
user:        Raymond Hettinger <python at rcn.com>
date:        Tue Apr 12 15:19:33 2011 -0700
summary:
  Issue 11747: Fix output format for context diffs.

files:
  Lib/difflib.py           |  30 +++++++++++++++++++++++----
  Lib/test/test_difflib.py |  29 +++++++++++++++++++++++++-
  2 files changed, 52 insertions(+), 7 deletions(-)


diff --git a/Lib/difflib.py b/Lib/difflib.py
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -1144,7 +1144,11 @@
     return ch in ws
 
 
-def _format_range(start, stop):
+########################################################################
+###  Unified Diff
+########################################################################
+
+def _format_range_unified(start, stop):
     'Convert range to the "ed" format'
     # Per the diff spec at http://www.unix.org/single_unix_specification/
     beginning = start + 1     # lines start numbering with one
@@ -1206,8 +1210,8 @@
             yield '+++ {}{}{}'.format(tofile, todate, lineterm)
 
         first, last = group[0], group[-1]
-        file1_range = _format_range(first[1], last[2])
-        file2_range = _format_range(first[3], last[4])
+        file1_range = _format_range_unified(first[1], last[2])
+        file2_range = _format_range_unified(first[3], last[4])
         yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm)
 
         for tag, i1, i2, j1, j2 in group:
@@ -1222,6 +1226,22 @@
                 for line in b[j1:j2]:
                     yield '+' + line
 
+
+########################################################################
+###  Context Diff
+########################################################################
+
+def _format_range_context(start, stop):
+    'Convert range to the "ed" format'
+    # Per the diff spec at http://www.unix.org/single_unix_specification/
+    beginning = start + 1     # lines start numbering with one
+    length = stop - start
+    if not length:
+        beginning -= 1        # empty ranges begin at line just before the range
+    if length <= 1:
+        return '{}'.format(beginning)
+    return '{},{}'.format(beginning, beginning + length - 1)
+
 # See http://www.unix.org/single_unix_specification/
 def context_diff(a, b, fromfile='', tofile='',
                  fromfiledate='', tofiledate='', n=3, lineterm='\n'):
@@ -1280,7 +1300,7 @@
         first, last = group[0], group[-1]
         yield '***************' + lineterm
 
-        file1_range = _format_range(first[1], last[2])
+        file1_range = _format_range_context(first[1], last[2])
         yield '*** {} ****{}'.format(file1_range, lineterm)
 
         if any(tag in {'replace', 'delete'} for tag, _, _, _, _ in group):
@@ -1289,7 +1309,7 @@
                     for line in a[i1:i2]:
                         yield prefix[tag] + line
 
-        file2_range = _format_range(first[3], last[4])
+        file2_range = _format_range_context(first[3], last[4])
         yield '--- {} ----{}'.format(file2_range, lineterm)
 
         if any(tag in {'replace', 'insert'} for tag, _, _, _, _ in group):
diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py
--- a/Lib/test/test_difflib.py
+++ b/Lib/test/test_difflib.py
@@ -236,7 +236,7 @@
         cd = difflib.context_diff(*args, lineterm='')
         self.assertEqual(list(cd)[0:2], ["*** Original", "--- Current"])
 
-    def test_range_format(self):
+    def test_range_format_unified(self):
         # Per the diff spec at http://www.unix.org/single_unix_specification/
         spec = '''\
            Each <range> field shall be of the form:
@@ -246,13 +246,38 @@
            If a range is empty, its beginning line number shall be the number of
            the line just before the range, or 0 if the empty range starts the file.
         '''
-        fmt = difflib._format_range
+        fmt = difflib._format_range_unified
         self.assertEqual(fmt(3,3), '3,0')
         self.assertEqual(fmt(3,4), '4')
         self.assertEqual(fmt(3,5), '4,2')
         self.assertEqual(fmt(3,6), '4,3')
         self.assertEqual(fmt(0,0), '0,0')
 
+    def test_range_format_context(self):
+        # Per the diff spec at http://www.unix.org/single_unix_specification/
+        spec = '''\
+           The range of lines in file1 shall be written in the following format
+           if the range contains two or more lines:
+               "*** %d,%d ****\n", <beginning line number>, <ending line number>
+           and the following format otherwise:
+               "*** %d ****\n", <ending line number>
+           The ending line number of an empty range shall be the number of the preceding line,
+           or 0 if the range is at the start of the file.
+
+           Next, the range of lines in file2 shall be written in the following format
+           if the range contains two or more lines:
+               "--- %d,%d ----\n", <beginning line number>, <ending line number>
+           and the following format otherwise:
+               "--- %d ----\n", <ending line number>
+        '''
+        fmt = difflib._format_range_context
+        self.assertEqual(fmt(3,3), '3')
+        self.assertEqual(fmt(3,4), '4')
+        self.assertEqual(fmt(3,5), '4,5')
+        self.assertEqual(fmt(3,6), '4,6')
+        self.assertEqual(fmt(0,0), '0')
+
+
 def test_main():
     difflib.HtmlDiff._default_prefix = 0
     Doctests = doctest.DocTestSuite(difflib)

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list