summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Loper <edloper@gradient.cis.upenn.edu>2004-08-12 02:34:27 (GMT)
committerEdward Loper <edloper@gradient.cis.upenn.edu>2004-08-12 02:34:27 (GMT)
commit8e4a34ba090a4ad9753ea8d9ccf95703c85fdbb4 (patch)
tree376bc708032ff21cf85bff23a1bf9f82a7254c14
parent74bca7aa44be315c669edcc0e02126fdd927062b (diff)
downloadcpython-8e4a34ba090a4ad9753ea8d9ccf95703c85fdbb4.zip
cpython-8e4a34ba090a4ad9753ea8d9ccf95703c85fdbb4.tar.gz
cpython-8e4a34ba090a4ad9753ea8d9ccf95703c85fdbb4.tar.bz2
- Added __docformat__
- Added comments for some regexps - If the traceback type/message don't match, then still print full traceback in report_failure (not just the first & last lines) - Renamed DocTestRunner.__failure_header -> _failure_header
-rw-r--r--Lib/doctest.py40
-rw-r--r--Lib/test/test_doctest.py10
2 files changed, 33 insertions, 17 deletions
diff --git a/Lib/doctest.py b/Lib/doctest.py
index 6927779..aad9dfe 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -167,6 +167,7 @@ output as appeared in the initial ">>>" line that triggered it.
If you execute this very file, the examples above will be found and
executed.
"""
+__docformat__ = 'reStructuredText en'
__all__ = [
'is_private',
@@ -330,6 +331,17 @@ def _tag_msg(tag, msg, indent=' '):
msg = '\n'.join([indent+l for l in msg[:-1].split('\n')])
return '%s:\n%s\n' % (tag, msg)
+def _exception_traceback(exc_info):
+ """
+ Return a string containing a traceback message for the given
+ exc_info tuple (as returned by sys.exc_info()).
+ """
+ # Get a traceback message.
+ excout = StringIO()
+ exc_type, exc_val, exc_tb = exc_info
+ traceback.print_exception(exc_type, exc_val, exc_tb, file=excout)
+ return excout.getvalue()
+
# Override some StringIO methods.
class _SpoofOut(StringIO):
def getvalue(self):
@@ -467,6 +479,11 @@ class DocTestParser:
"""
A class used to parse strings containing doctest examples.
"""
+ # This regular expression is used to find doctest examples in a
+ # string. It defines three groups: `source` is the source code
+ # (including leading indentation and prompts); `indent` is the
+ # indentation of the first (PS1) line of the source code; and
+ # `want` is the expected output (including leading indentation).
_EXAMPLE_RE = re.compile(r'''
# Source consists of a PS1 line followed by zero or more PS2 lines.
(?P<source>
@@ -479,7 +496,10 @@ class DocTestParser:
.*$\n? # But any other line
)*)
''', re.MULTILINE | re.VERBOSE)
- _IS_BLANK_OR_COMMENT = re.compile('^[ ]*(#.*)?$').match
+
+ # This regular expression matcher checks if a given string is a
+ # blank line or contains a single comment.
+ _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match
def get_doctest(self, string, globs, name, filename, lineno):
"""
@@ -1125,7 +1145,7 @@ class DocTestRunner:
Report that the given example failed.
"""
# Print an error message.
- out(self.__failure_header(test, example) +
+ out(self._failure_header(test, example) +
self._checker.output_difference(example.want, got,
self.optionflags))
@@ -1133,16 +1153,10 @@ class DocTestRunner:
"""
Report that the given example raised an unexpected exception.
"""
- # Get a traceback message.
- excout = StringIO()
- exc_type, exc_val, exc_tb = exc_info
- traceback.print_exception(exc_type, exc_val, exc_tb, file=excout)
- exception_tb = excout.getvalue()
- # Print an error message.
- out(self.__failure_header(test, example) +
- _tag_msg("Exception raised", exception_tb))
+ out(self._failure_header(test, example) +
+ _tag_msg("Exception raised", _exception_traceback(exc_info)))
- def __failure_header(self, test, example):
+ def _failure_header(self, test, example):
s = (self.DIVIDER + "\n" +
_tag_msg("Failure in example", example.source))
if test.filename is None:
@@ -1256,10 +1270,10 @@ class DocTestRunner:
self.optionflags)):
# Is +exc_msg the right thing here??
self.report_success(out, test, example,
- got+exc_hdr+exc_msg)
+ got+_exception_traceback(exc_info))
else:
self.report_failure(out, test, example,
- got+exc_hdr+exc_msg)
+ got+_exception_traceback(exc_info))
failures += 1
# Restore the option flags (in case they were modified)
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index 977ade7..c734cae 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -269,10 +269,10 @@ will return a single test (for that function's docstring):
>>> finder = doctest.DocTestFinder()
>>> tests = finder.find(sample_func)
-
+
>>> print tests # doctest: +ELLIPSIS
[<DocTest sample_func from ...:12 (1 example)>]
-
+
>>> e = tests[0].examples[0]
>>> (e.source, e.want, e.lineno)
('print sample_func(22)\n', '44\n', 3)
@@ -620,6 +620,7 @@ message is raised, then it is reported as a failure:
... '''
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
+ ... # doctest: +ELLIPSIS
**********************************************************************
Failure in example: raise ValueError, 'message'
from line #1 of f
@@ -628,6 +629,7 @@ message is raised, then it is reported as a failure:
ValueError: wrong message
Got:
Traceback (most recent call last):
+ ...
ValueError: message
(1, 1)
@@ -897,7 +899,7 @@ comment of the form ``# doctest: -OPTION``:
Option directives affect only the example that they appear with; they
do not change the options for surrounding examples:
-
+
>>> def f(x): r'''
... >>> print range(10) # Should fail: no ellipsis
... [0, 1, ..., 9]
@@ -984,7 +986,7 @@ long as a continuation prompt is used:
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
(0, 1)
-
+
For examples with multi-line source, the option directive may appear
at the end of any line: