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.
This commit is contained in:
Tim Peters 2004-08-19 06:49:33 +00:00
parent caa9798410
commit 1cf3aa6e66
2 changed files with 31 additions and 4 deletions

View file

@ -1468,7 +1468,7 @@ def check_output(self, want, got, optionflags):
# 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 @@ def check_output(self, want, got, optionflags):
# 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)').

View file

@ -780,6 +780,29 @@ def optionflags(): r"""
>>> 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: