summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/difflib.rst8
-rw-r--r--Lib/difflib.py35
-rw-r--r--Lib/test/test_difflib.py24
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS4
5 files changed, 51 insertions, 21 deletions
diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst
index 433764c..566de72 100644
--- a/Doc/library/difflib.rst
+++ b/Doc/library/difflib.rst
@@ -140,8 +140,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
The context diff format normally has a header for filenames and modification
times. Any or all of these may be specified using strings for *fromfile*,
- *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally
- expressed in the format returned by :func:`time.ctime`. If not specified, the
+ *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally
+ expressed in the ISO 8601 format. If not specified, the
strings default to blanks.
>>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n']
@@ -272,8 +272,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
The context diff format normally has a header for filenames and modification
times. Any or all of these may be specified using strings for *fromfile*,
- *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally
- expressed in the format returned by :func:`time.ctime`. If not specified, the
+ *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally
+ expressed in the ISO 8601 format. If not specified, the
strings default to blanks.
diff --git a/Lib/difflib.py b/Lib/difflib.py
index 292bba9..92d58fa 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -1160,18 +1160,18 @@ def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
The unidiff format normally has a header for filenames and modification
times. Any or all of these may be specified using strings for
- 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. The modification
- times are normally expressed in the format returned by time.ctime().
+ 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
+ The modification times are normally expressed in the ISO 8601 format.
Example:
>>> for line in unified_diff('one two three four'.split(),
... 'zero one tree four'.split(), 'Original', 'Current',
- ... 'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:20:52 2003',
+ ... '2005-01-26 23:30:50', '2010-04-02 10:20:52',
... lineterm=''):
- ... print(line)
- --- Original Sat Jan 26 23:30:50 1991
- +++ Current Fri Jun 06 10:20:52 2003
+ ... print(line) # doctest: +NORMALIZE_WHITESPACE
+ --- Original 2005-01-26 23:30:50
+ +++ Current 2010-04-02 10:20:52
@@ -1,4 +1,4 @@
+zero
one
@@ -1184,8 +1184,10 @@ def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
started = False
for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
if not started:
- yield '--- %s %s%s' % (fromfile, fromfiledate, lineterm)
- yield '+++ %s %s%s' % (tofile, tofiledate, lineterm)
+ fromdate = '\t%s' % fromfiledate if fromfiledate else ''
+ todate = '\t%s' % tofiledate if tofiledate else ''
+ yield '--- %s%s%s' % (fromfile, fromdate, lineterm)
+ yield '+++ %s%s%s' % (tofile, todate, lineterm)
started = True
i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]
yield "@@ -%d,%d +%d,%d @@%s" % (i1+1, i2-i1, j1+1, j2-j1, lineterm)
@@ -1223,17 +1225,16 @@ def context_diff(a, b, fromfile='', tofile='',
The context diff format normally has a header for filenames and
modification times. Any or all of these may be specified using
strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
- The modification times are normally expressed in the format returned
- by time.ctime(). If not specified, the strings default to blanks.
+ The modification times are normally expressed in the ISO 8601 format.
+ If not specified, the strings default to blanks.
Example:
>>> print(''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(1),
- ... 'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current',
- ... 'Sat Jan 26 23:30:50 1991', 'Fri Jun 06 10:22:46 2003')),
+ ... 'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current')),
... end="")
- *** Original Sat Jan 26 23:30:50 1991
- --- Current Fri Jun 06 10:22:46 2003
+ *** Original
+ --- Current
***************
*** 1,4 ****
one
@@ -1251,8 +1252,10 @@ def context_diff(a, b, fromfile='', tofile='',
prefixmap = {'insert':'+ ', 'delete':'- ', 'replace':'! ', 'equal':' '}
for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n):
if not started:
- yield '*** %s %s%s' % (fromfile, fromfiledate, lineterm)
- yield '--- %s %s%s' % (tofile, tofiledate, lineterm)
+ fromdate = '\t%s' % fromfiledate if fromfiledate else ''
+ todate = '\t%s' % tofiledate if tofiledate else ''
+ yield '*** %s%s%s' % (fromfile, fromdate, lineterm)
+ yield '--- %s%s%s' % (tofile, todate, lineterm)
started = True
yield '***************%s' % (lineterm,)
diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py
index 852aae9..6c9bde6 100644
--- a/Lib/test/test_difflib.py
+++ b/Lib/test/test_difflib.py
@@ -159,10 +159,32 @@ class TestSFpatches(unittest.TestCase):
difflib.SequenceMatcher(None, old, new).get_opcodes()
+class TestOutputFormat(unittest.TestCase):
+ def test_tab_delimiter(self):
+ args = ['one', 'two', 'Original', 'Current',
+ '2005-01-26 23:30:50', '2010-04-02 10:20:52']
+ ud = difflib.unified_diff(*args, lineterm='')
+ self.assertEqual(list(ud)[0:2], [
+ "--- Original\t2005-01-26 23:30:50",
+ "+++ Current\t2010-04-02 10:20:52"])
+ cd = difflib.context_diff(*args, lineterm='')
+ self.assertEqual(list(cd)[0:2], [
+ "*** Original\t2005-01-26 23:30:50",
+ "--- Current\t2010-04-02 10:20:52"])
+
+ def test_no_trailing_tab_on_empty_filedate(self):
+ args = ['one', 'two', 'Original', 'Current']
+ ud = difflib.unified_diff(*args, lineterm='')
+ self.assertEqual(list(ud)[0:2], ["--- Original", "+++ Current"])
+
+ cd = difflib.context_diff(*args, lineterm='')
+ self.assertEqual(list(cd)[0:2], ["*** Original", "--- Current"])
+
+
def test_main():
difflib.HtmlDiff._default_prefix = 0
Doctests = doctest.DocTestSuite(difflib)
- run_unittest(TestSFpatches, TestSFbugs, Doctests)
+ run_unittest(TestSFpatches, TestSFbugs, TestOutputFormat, Doctests)
if __name__ == '__main__':
test_main()
diff --git a/Misc/ACKS b/Misc/ACKS
index 8457595..d2c01aa 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -755,6 +755,7 @@ Christian Tanzer
Steven Taschuk
Monty Taylor
Amy Taylor
+Anatoly Techtonik
Tobias Thelen
James Thomas
Robin Thomas
diff --git a/Misc/NEWS b/Misc/NEWS
index e34d63e..8f80a96 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -312,6 +312,10 @@ C-API
Library
-------
+- Issue #7585: difflib context and unified diffs now place a tab between
+ filename and date, conforming to the 'standards' they were originally
+ designed to follow. This improves compatibility with patch tools.
+
- Issue #7472: Fixed typo in email.encoders module; messages using ISO-2022
character sets will now consistently use a Content-Transfer-Encoding of
7bit rather than sometimes being marked as 8bit.