]> granicus.if.org Git - python/commitdiff
#11763: don't use difflib in TestCase.assertMultiLineEqual if the strings are too...
authorEzio Melotti <ezio.melotti@gmail.com>
Wed, 27 Apr 2011 07:17:34 +0000 (10:17 +0300)
committerEzio Melotti <ezio.melotti@gmail.com>
Wed, 27 Apr 2011 07:17:34 +0000 (10:17 +0300)
Lib/test/test_unittest.py
Lib/unittest.py
Misc/NEWS

index 21e0806a31ba5876499639e06f05a9f6bf8610f0..c4cad83cd434320bdbec1daabb8fadd6a9736de2 100644 (file)
@@ -2719,6 +2719,41 @@ test case
             # no fair testing ourself with ourself, use assertEqual..
             self.assertEqual(sample_text_error, str(e))
 
+    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 = 'x' * (2**7)
+        try:
+            self.assertMultiLineEqual(s + 'a', s + 'b')
+        except self.failureException as exc:
+            err_msg = str(exc)
+        else:
+            self.fail('assertEqual unexpectedly succeeded')
+        self.assertIn('^', err_msg)
+        self.assertMultiLineEqual(s + 'a', s + 'a')
+
+        # over the threshold: diff not used and marker (^) not in error message
+        s = 'x' * (2**9)
+        s1, s2 = s + 'a', s + 'b'
+        try:
+            self.assertMultiLineEqual(s1, s2)
+        except self.failureException as exc:
+            err_msg = str(exc)
+        else:
+            self.fail('assertEqual unexpectedly succeeded')
+        self.assertNotIn('^', err_msg)
+        self.assertEqual(err_msg, '%r != %r' % (s1, s2))
+        self.assertMultiLineEqual(s + 'a', s + 'a')
+
     def testAssertIsNone(self):
         self.assertIsNone(None)
         self.assertRaises(self.failureException, self.assertIsNone, False)
index 03a11b7d1ce8e35f448b0f52a261b959aac23c3c..cabd857a0e8e898f6ca95fec1654d5297714bb7b 100644 (file)
@@ -346,6 +346,9 @@ class TestCase(object):
 
     longMessage = False
 
+    # If a string is longer than _diffThreshold, use normal comparison instead
+    # of difflib.  See #11763.
+    _diffThreshold = 2**16
 
     def __init__(self, methodName='runTest'):
         """Create an instance of the class that will use the named test
@@ -955,6 +958,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)
             standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True)))
             self.fail(self._formatMessage(msg, standardMsg))
 
index 8eefdafcc30c13774b705bb6daeee9ea7b563585..b4ba3b67cb0d021e2de6e354f54bf657506bf13b 100644 (file)
--- 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