summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEzio Melotti <devnull@localhost>2011-04-27 09:45:46 +0300
committerEzio Melotti <devnull@localhost>2011-04-27 09:45:46 +0300
commitfd44bcb9cd589b3f34ed53625594d53787e7d0cc (patch)
tree87111cc7cf80c2d42033349e16531f1057b33ec8
parent2e1129b1085e3f6cb6060d505b5dd3e1774d1bae (diff)
downloadcpython-fd44bcb9cd589b3f34ed53625594d53787e7d0cc.tar.gz
#11763: don't use difflib in TestCase.assertMultiLineEqual if the strings are too long.
-rw-r--r--Lib/unittest/case.py8
-rw-r--r--Lib/unittest/test/test_case.py36
-rw-r--r--Misc/NEWS3
3 files changed, 47 insertions, 0 deletions
diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py
index ecb6a3e419..dcaae93aed 100644
--- a/Lib/unittest/case.py
+++ b/Lib/unittest/case.py
@@ -169,6 +169,10 @@ class TestCase(object):
maxDiff = 80*8
+ # If a string is longer than _diffThreshold, use normal comparison instead
+ # of difflib. See #11763.
+ _diffThreshold = 2**16
+
# Attribute used by TestSuite for classSetUp
_classSetupFailed = False
@@ -900,6 +904,10 @@ class TestCase(object):
'Second argument is not a string')
if first != second:
+ # don't use difflib if the strings are too long
+ if (len(first) > self._diffThreshold or
+ len(second) > self._diffThreshold):
+ self._baseAssertEqual(first, second, msg)
firstlines = first.splitlines(True)
secondlines = second.splitlines(True)
if len(firstlines) == 1 and first.strip('\r\n') == first:
diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py
index 06eeda1503..2e449c5c2a 100644
--- a/Lib/unittest/test/test_case.py
+++ b/Lib/unittest/test/test_case.py
@@ -667,6 +667,42 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing):
else:
self.fail('assertMultiLineEqual did not fail')
+ def testAssertEqual_diffThreshold(self):
+ # check threshold value
+ self.assertEqual(self._diffThreshold, 2**16)
+ # disable madDiff to get diff markers
+ self.maxDiff = None
+
+ # set a lower threshold value and add a cleanup to restore it
+ old_threshold = self._diffThreshold
+ self._diffThreshold = 2**8
+ self.addCleanup(lambda: setattr(self, '_diffThreshold', old_threshold))
+
+ # under the threshold: diff marker (^) in error message
+ s = u'x' * (2**7)
+ with self.assertRaises(self.failureException) as cm:
+ self.assertEqual(s + 'a', s + 'b')
+ self.assertIn('^', str(cm.exception))
+ self.assertEqual(s + 'a', s + 'a')
+
+ # over the threshold: diff not used and marker (^) not in error message
+ s = u'x' * (2**9)
+ # if the path that uses difflib is taken, _truncateMessage will be
+ # called -- replace it with explodingTruncation to verify that this
+ # doesn't happen
+ def explodingTruncation(message, diff):
+ raise SystemError('this should not be raised')
+ old_truncate = self._truncateMessage
+ self._truncateMessage = explodingTruncation
+ self.addCleanup(lambda: setattr(self, '_truncateMessage', old_truncate))
+
+ s1, s2 = s + 'a', s + 'b'
+ with self.assertRaises(self.failureException) as cm:
+ self.assertEqual(s1, s2)
+ self.assertNotIn('^', str(cm.exception))
+ self.assertEqual(str(cm.exception), '%r != %r' % (s1, s2))
+ self.assertEqual(s + 'a', s + 'a')
+
def testAssertItemsEqual(self):
a = object()
self.assertItemsEqual([1, 2, 3], [3, 2, 1])
diff --git a/Misc/NEWS b/Misc/NEWS
index 3bd61e4dea..4c573480d4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -61,6 +61,9 @@ Core and Builtins
Library
-------
+- Issue #11763: don't use difflib in TestCase.assertMultiLineEqual if the
+ strings are too long.
+
- Issue #11236: getpass.getpass responds to ctrl-c or ctrl-z on terminal.
- Issue #11768: The signal handler of the signal module only calls