# Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org).
# Major enhancements and refactoring by:
# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
r"""Module doctest -- a framework for running examples in docstrings.
In simplest use, end each module M to be tested with:
if __name__ == "__main__":
Then running the module as a script will cause the examples in the
docstrings to get executed and verified:
This won't display anything unless an example fails, in which case the
failing example(s) and the cause(s) of the failure(s) are printed to stdout
(why not stderr? because stderr is a lame hack <0.2 wink>), and the final
line of output is "Test failed.".
Run it with the -v switch instead:
and a detailed report of all examples tried is printed to stdout, along
with assorted summaries at the end.
You can force verbose mode by passing "verbose=True" to testmod, or prohibit
it by passing "verbose=False". In either of those cases, sys.argv is not
There are a variety of other ways to run doctests, including integration
with the unittest framework, and support for running non-Python text
files containing doctests. There are also many ways to override parts
of doctest's default behaviors. See the Library Reference Manual for
__docformat__ = 'reStructuredText en'
'DONT_ACCEPT_TRUE_FOR_1',
'IGNORE_EXCEPTION_DETAIL',
'REPORT_ONLY_FIRST_FAILURE',
'run_docstring_examples',
'set_unittest_reportflags',
from collections import namedtuple
TestResults = namedtuple('TestResults', 'failed attempted')
# There are 4 basic classes:
# - Example: a <source, want> pair, plus an intra-docstring line number.
# - DocTest: a collection of examples, parsed from a docstring, plus
# info about where the docstring came from (name, filename, lineno).
# - DocTestFinder: extracts DocTests from a given object's docstring and
# its contained objects' docstrings.
# - DocTestRunner: runs DocTest cases, and accumulates statistics.
# So the basic picture is:
# +------+ +---------+ +-------+
# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results|
# +------+ +---------+ +-------+
def register_optionflag(name):
# Create a new flag unless `name` is already known.
return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME))
DONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1')
DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE')
NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE')
ELLIPSIS = register_optionflag('ELLIPSIS')
SKIP = register_optionflag('SKIP')
IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL')
COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 |
REPORT_UDIFF = register_optionflag('REPORT_UDIFF')
REPORT_CDIFF = register_optionflag('REPORT_CDIFF')
REPORT_NDIFF = register_optionflag('REPORT_NDIFF')
REPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE')
FAIL_FAST = register_optionflag('FAIL_FAST')
REPORTING_FLAGS = (REPORT_UDIFF |
REPORT_ONLY_FIRST_FAILURE |
# Special string markers for use in `want` strings:
BLANKLINE_MARKER = '<BLANKLINE>'
######################################################################
######################################################################
# 2. Example & DocTest -- store test cases
# 3. DocTest Parser -- extracts examples from strings
# 4. DocTest Finder -- extracts test cases from objects
# 5. DocTest Runner -- runs test cases
# 6. Test Functions -- convenient wrappers for testing
######################################################################
######################################################################
def _extract_future_flags(globs):
Return the compiler-flags associated with the future features that
have been imported into the given namespace (globs).
for fname in __future__.all_feature_names:
feature = globs.get(fname, None)
if feature is getattr(__future__, fname):
flags |= feature.compiler_flag
def _normalize_module(module, depth=2):
Return the module specified by `module`. In particular:
- If `module` is a module, then return module.
- If `module` is a string, then import and return the
- If `module` is None, then return the calling module.
The calling module is assumed to be the module of
the stack frame at the given depth in the call stack.
if inspect.ismodule(module):
elif isinstance(module, str):
return __import__(module, globals(), locals(), ["*"])
return sys.modules[sys._getframe(depth).f_globals['__name__']]
raise TypeError("Expected a module, string, or None")
def _newline_convert(data):
# We have two cases to cover and we need to make sure we do
# them in the right order
for newline in ('\r\n', '\r'):
data = data.replace(newline, '\n')
def _load_testfile(filename, package, module_relative, encoding):
package = _normalize_module(package, 3)
filename = _module_relative_path(package, filename)
if getattr(package, '__loader__', None) is not None:
if hasattr(package.__loader__, 'get_data'):
file_contents = package.__loader__.get_data(filename)
file_contents = file_contents.decode(encoding)
# get_data() opens files as 'rb', so one must do the equivalent
# conversion as universal newlines would do.
return _newline_convert(file_contents), filename
with open(filename, encoding=encoding) as f:
return f.read(), filename
def _indent(s, indent=4):
Add the given number of space characters to the beginning of
every non-blank line in `s`, and return the result.
# This regexp matches the start of non-blank lines:
return re.sub('(?m)^(?!$)', indent*' ', s)
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.
exc_type, exc_val, exc_tb = exc_info
traceback.print_exception(exc_type, exc_val, exc_tb, file=excout)
# Override some StringIO methods.
class _SpoofOut(StringIO):
result = StringIO.getvalue(self)
# If anything at all was written, make sure there's a trailing
# newline. There's no way for the expected output to indicate
# that a trailing newline is missing.
if result and not result.endswith("\n"):
def truncate(self, size=None):
# Worst-case linear-time ellipsis matching.
def _ellipsis_match(want, got):
Essentially the only subtle case:
>>> _ellipsis_match('aa...aa', 'aaa')
if ELLIPSIS_MARKER not in want:
# Find "the real" strings.
ws = want.split(ELLIPSIS_MARKER)
# Deal with exact matches possibly needed at one or both ends.
startpos, endpos = 0, len(got)
if w: # starts with exact match
if w: # ends with exact match
# Exact end matches required more characters than we have, as in
# _ellipsis_match('aa...aa', 'aaa')
# For the rest, we only need to find the leftmost non-overlapping
# match for each piece. If there's no overall match that way alone,
# there's no overall match period.
# w may be '' at times, if there are consecutive ellipses, or
# due to an ellipsis at the start or end of `want`. That's OK.
# Search for an empty string succeeds, and doesn't change startpos.
startpos = got.find(w, startpos, endpos)
"Return a commented form of the given line"
def _strip_exception_details(msg):
# Support for IGNORE_EXCEPTION_DETAIL.
# Get rid of everything except the exception name; in particular, drop
# the possibly dotted module path (if any) and the exception message (if
# any). We assume that a colon is never part of a dotted name, or of an
# "foo.bar.MyError: la di da"
# Or for "abc.def" or "abc.def:\n" return "def".
# The exception name must appear on the first line.
# retain up to the first colon (if any)
i = msg.find(':', 0, end)
# retain just the exception name
i = msg.rfind('.', 0, end)
class _OutputRedirectingPdb(pdb.Pdb):
A specialized version of the python debugger that redirects stdout
to a given stream when interacting with the user. Stdout is *not*
redirected when traced code is executed.
self.__debugger_used = False
# do not play signal games in the pdb
pdb.Pdb.__init__(self, stdout=out, nosigint=True)
# still use input() to get user input
def set_trace(self, frame=None):
self.__debugger_used = True
frame = sys._getframe().f_back
pdb.Pdb.set_trace(self, frame)
# Calling set_continue unconditionally would break unit test
# coverage reporting, as Bdb.set_continue calls sys.settrace(None).
pdb.Pdb.set_continue(self)
def trace_dispatch(self, *args):
# Redirect stdout to the given stream.
# Call Pdb's trace dispatch method.
return pdb.Pdb.trace_dispatch(self, *args)
# [XX] Normalize with respect to os.path.pardir?
def _module_relative_path(module, test_path):
if not inspect.ismodule(module):
raise TypeError('Expected a module: %r' % module)
if test_path.startswith('/'):
raise ValueError('Module-relative files may not have absolute paths')
# Normalize the path. On Windows, replace "/" with "\".
test_path = os.path.join(*(test_path.split('/')))
# Find the base directory for the path.
if hasattr(module, '__file__'):
# A normal module/package
basedir = os.path.split(module.__file__)[0]
elif module.__name__ == '__main__':
# An interactive session.
if len(sys.argv)>0 and sys.argv[0] != '':
basedir = os.path.split(sys.argv[0])[0]
if hasattr(module, '__path__'):
for directory in module.__path__:
fullpath = os.path.join(directory, test_path)
if os.path.exists(fullpath):
# A module w/o __file__ (this includes builtins)
raise ValueError("Can't resolve paths relative to the module "
"%r (it has no __file__)"
# Combine the base directory and the test path.
return os.path.join(basedir, test_path)
######################################################################
######################################################################
## - An "example" is a <source, want> pair, where "source" is a
## fragment of source code, and "want" is the expected output for
## "source." The Example class also includes information about
## where the example was extracted from.
## - A "doctest" is a collection of examples, typically extracted from
## a string (such as an object's docstring). The DocTest class also
## includes information about where the string was extracted from.
A single doctest example, consisting of source code and expected
output. `Example` defines the following attributes:
- source: A single Python statement, always ending with a newline.
The constructor adds a newline if needed.
- want: The expected output from running the source code (either
from stdout, or a traceback in case of exception). `want` ends
with a newline unless it's empty, in which case it's an empty
string. The constructor adds a newline if needed.
- exc_msg: The exception message generated by the example, if
the example is expected to generate an exception; or `None` if
it is not expected to generate an exception. This exception
message is compared against the return value of
`traceback.format_exception_only()`. `exc_msg` ends with a
newline unless it's `None`. The constructor adds a newline
- lineno: The line number within the DocTest string containing
this Example where the Example begins. This line number is
zero-based, with respect to the beginning of the DocTest.
- indent: The example's indentation in the DocTest string.
I.e., the number of space characters that precede the
- options: A dictionary mapping from option flags to True or
False, which is used to override default options for this
example. Any option flags not contained in this dictionary
are left at their default value (as specified by the
DocTestRunner's optionflags). By default, no options are set.
def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
if not source.endswith('\n'):
if want and not want.endswith('\n'):
if exc_msg is not None and not exc_msg.endswith('\n'):
if options is None: options = {}
if type(self) is not type(other):
return self.source == other.source and \
self.want == other.want and \
self.lineno == other.lineno and \
self.indent == other.indent and \
self.options == other.options and \
self.exc_msg == other.exc_msg