summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2004-08-19 06:49:33 (GMT)
committerTim Peters <tim.peters@gmail.com>2004-08-19 06:49:33 (GMT)
commit1cf3aa6e6615dcddc58e42d4fb214f9e0d90d22c (patch)
tree6b9f482fa3db48cdc47ca711991120186ac09a9a
parentcaa9798410887317226c4bf89f38d318b8436612 (diff)
downloadcpython-1cf3aa6e6615dcddc58e42d4fb214f9e0d90d22c.zip
cpython-1cf3aa6e6615dcddc58e42d4fb214f9e0d90d22c.tar.gz
cpython-1cf3aa6e6615dcddc58e42d4fb214f9e0d90d22c.tar.bz2
ELLIPSIS implementation: an ellipsis couldn't match nothing if it
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.
-rw-r--r--Lib/doctest.py12
-rw-r--r--Lib/test/test_doctest.py23
2 files changed, 31 insertions, 4 deletions
diff --git a/Lib/doctest.py b/Lib/doctest.py
index c033b0d..f7b29d3 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -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)').
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index dec9110..d49e6cf 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -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: