]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
ELLIPSIS implementation: an ellipsis couldn't match nothing if it
authorTim Peters <tim.peters@gmail.com>
Thu, 19 Aug 2004 06:49:33 +0000 (06:49 +0000)
committerTim Peters <tim.peters@gmail.com>
Thu, 19 Aug 2004 06:49:33 +0000 (06:49 +0000)
appeared at the end of a line.  Repaired that.  Also noted that it's
too easy to provoke this implementation into requiring exponential
time, and especially when a test fails.  I'll replace the implementation
with an always-efficient one later.

Lib/doctest.py
Lib/test/test_doctest.py

index c033b0d8df8f80252b7081d02a1c0f87c6c52f46..f7b29d3a50a33e34f49a2395cf04a2d188093b32 100644 (file)
@@ -1468,7 +1468,7 @@ class OutputChecker:
         # This flag causes doctest to ignore any differences in the
         # contents of whitespace strings.  Note that this can be used
         # in conjunction with the ELLISPIS flag.
-        if (optionflags & NORMALIZE_WHITESPACE):
+        if optionflags & NORMALIZE_WHITESPACE:
             got = ' '.join(got.split())
             want = ' '.join(want.split())
             if got == want:
@@ -1477,10 +1477,14 @@ class OutputChecker:
         # The ELLIPSIS flag says to let the sequence "..." in `want`
         # match any substring in `got`.  We implement this by
         # transforming `want` into a regular expression.
-        if (optionflags & ELLIPSIS):
+        if optionflags & ELLIPSIS:
+            # Remove \n from ...\n, else the newline will be required,
+            # and (for example) ... on a line by itself can't match
+            # nothing gracefully.
+            want_re = want.replace(ELLIPSIS_MARKER + '\n', ELLIPSIS_MARKER)
             # Escape any special regexp characters
-            want_re = re.escape(want)
-            # Replace ellipsis markers ('...') with .*
+            want_re = re.escape(want_re)
+            # Replace escaped ellipsis markers ('\.\.\.') with .*
             want_re = want_re.replace(re.escape(ELLIPSIS_MARKER), '.*')
             # Require that it matches the entire string; and set the
             # re.DOTALL flag (with '(?s)').
index dec9110f3fdba03fd85e092d2dab677549c89155..d49e6cff0cb67046e40e5607cdfe9a4bb38997d6 100644 (file)
@@ -780,6 +780,29 @@ output to match any substring in the actual output:
     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
     (0, 1)
 
+... should also match nothing gracefully:
+XXX This can be provoked into requiring exponential time by adding more
+XXX ellipses; the implementation should change.  It's much easier to
+XXX provoke exponential time with expected output that doesn't match,
+XXX BTW (then multiple regexp .* thingies each try all possiblities,
+XXX multiplicatively, without hope of success).  That's the real danger,
+XXX that a failing test will appear to be hung.
+
+    >>> for i in range(100):
+    ...     print i**2 #doctest: +ELLIPSIS
+    0
+    ...
+    1
+    ...
+    36
+    ...
+    ...
+    49
+    64
+    ......
+    9801
+    ...
+
 The UNIFIED_DIFF flag causes failures that involve multi-line expected
 and actual outputs to be displayed using a unified diff: