mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1177 lines
		
	
	
	
		
			38 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1177 lines
		
	
	
	
		
			38 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Module doctest.
 | 
						|
# Released to the public domain 16-Jan-2001,
 | 
						|
# by Tim Peters (tim.one@home.com).
 | 
						|
 | 
						|
# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
 | 
						|
 | 
						|
"""Module doctest -- a framework for running examples in docstrings.
 | 
						|
 | 
						|
NORMAL USAGE
 | 
						|
 | 
						|
In normal use, end each module M with:
 | 
						|
 | 
						|
def _test():
 | 
						|
    import doctest, M           # replace M with your module's name
 | 
						|
    return doctest.testmod(M)   # ditto
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    _test()
 | 
						|
 | 
						|
Then running the module as a script will cause the examples in the
 | 
						|
docstrings to get executed and verified:
 | 
						|
 | 
						|
python M.py
 | 
						|
 | 
						|
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:
 | 
						|
 | 
						|
python M.py -v
 | 
						|
 | 
						|
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=1" to testmod, or prohibit
 | 
						|
it by passing "verbose=0".  In either of those cases, sys.argv is not
 | 
						|
examined by testmod.
 | 
						|
 | 
						|
In any case, testmod returns a 2-tuple of ints (f, t), where f is the
 | 
						|
number of docstring examples that failed and t is the total number of
 | 
						|
docstring examples attempted.
 | 
						|
 | 
						|
 | 
						|
WHICH DOCSTRINGS ARE EXAMINED?
 | 
						|
 | 
						|
+ M.__doc__.
 | 
						|
 | 
						|
+ f.__doc__ for all functions f in M.__dict__.values(), except those
 | 
						|
  with private names and those defined in other modules.
 | 
						|
 | 
						|
+ C.__doc__ for all classes C in M.__dict__.values(), except those with
 | 
						|
  private names and those defined in other modules.
 | 
						|
 | 
						|
+ If M.__test__ exists and "is true", it must be a dict, and
 | 
						|
  each entry maps a (string) name to a function object, class object, or
 | 
						|
  string.  Function and class object docstrings found from M.__test__
 | 
						|
  are searched even if the name is private, and strings are searched
 | 
						|
  directly as if they were docstrings.  In output, a key K in M.__test__
 | 
						|
  appears with name
 | 
						|
      <name of M>.__test__.K
 | 
						|
 | 
						|
Any classes found are recursively searched similarly, to test docstrings in
 | 
						|
their contained methods and nested classes.  Private names reached from M's
 | 
						|
globals are skipped, but all names reached from M.__test__ are searched.
 | 
						|
 | 
						|
By default, a name is considered to be private if it begins with an
 | 
						|
underscore (like "_my_func") but doesn't both begin and end with (at least)
 | 
						|
two underscores (like "__init__").  You can change the default by passing
 | 
						|
your own "isprivate" function to testmod.
 | 
						|
 | 
						|
If you want to test docstrings in objects with private names too, stuff
 | 
						|
them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your
 | 
						|
own isprivate function to Tester's constructor, or call the rundoc method
 | 
						|
of a Tester instance).
 | 
						|
 | 
						|
WHAT'S THE EXECUTION CONTEXT?
 | 
						|
 | 
						|
By default, each time testmod finds a docstring to test, it uses a *copy*
 | 
						|
of M's globals (so that running tests on a module doesn't change the
 | 
						|
module's real globals, and so that one test in M can't leave behind crumbs
 | 
						|
that accidentally allow another test to work).  This means examples can
 | 
						|
freely use any names defined at top-level in M.  It also means that sloppy
 | 
						|
imports (see above) can cause examples in external docstrings to use
 | 
						|
globals inappropriate for them.
 | 
						|
 | 
						|
You can force use of your own dict as the execution context by passing
 | 
						|
"globs=your_dict" to testmod instead.  Presumably this would be a copy of
 | 
						|
M.__dict__ merged with the globals from other imported modules.
 | 
						|
 | 
						|
 | 
						|
WHAT IF I WANT TO TEST A WHOLE PACKAGE?
 | 
						|
 | 
						|
Piece o' cake, provided the modules do their testing from docstrings.
 | 
						|
Here's the test.py I use for the world's most elaborate Rational/
 | 
						|
floating-base-conversion pkg (which I'll distribute some day):
 | 
						|
 | 
						|
from Rational import Cvt
 | 
						|
from Rational import Format
 | 
						|
from Rational import machprec
 | 
						|
from Rational import Rat
 | 
						|
from Rational import Round
 | 
						|
from Rational import utils
 | 
						|
 | 
						|
modules = (Cvt,
 | 
						|
           Format,
 | 
						|
           machprec,
 | 
						|
           Rat,
 | 
						|
           Round,
 | 
						|
           utils)
 | 
						|
 | 
						|
def _test():
 | 
						|
    import doctest
 | 
						|
    import sys
 | 
						|
    verbose = "-v" in sys.argv
 | 
						|
    for mod in modules:
 | 
						|
        doctest.testmod(mod, verbose=verbose, report=0)
 | 
						|
    doctest.master.summarize()
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    _test()
 | 
						|
 | 
						|
IOW, it just runs testmod on all the pkg modules.  testmod remembers the
 | 
						|
names and outcomes (# of failures, # of tries) for each item it's seen, and
 | 
						|
passing "report=0" prevents it from printing a summary in verbose mode.
 | 
						|
Instead, the summary is delayed until all modules have been tested, and
 | 
						|
then "doctest.master.summarize()" forces the summary at the end.
 | 
						|
 | 
						|
So this is very nice in practice:  each module can be tested individually
 | 
						|
with almost no work beyond writing up docstring examples, and collections
 | 
						|
of modules can be tested too as a unit with no more work than the above.
 | 
						|
 | 
						|
 | 
						|
WHAT ABOUT EXCEPTIONS?
 | 
						|
 | 
						|
No problem, as long as the only output generated by the example is the
 | 
						|
traceback itself.  For example:
 | 
						|
 | 
						|
    >>> [1, 2, 3].remove(42)
 | 
						|
    Traceback (most recent call last):
 | 
						|
      File "<stdin>", line 1, in ?
 | 
						|
    ValueError: list.remove(x): x not in list
 | 
						|
    >>>
 | 
						|
 | 
						|
Note that only the exception type and value are compared (specifically,
 | 
						|
only the last line in the traceback).
 | 
						|
 | 
						|
 | 
						|
ADVANCED USAGE
 | 
						|
 | 
						|
doctest.testmod() captures the testing policy I find most useful most
 | 
						|
often.  You may want other policies.
 | 
						|
 | 
						|
testmod() actually creates a local instance of class doctest.Tester, runs
 | 
						|
appropriate methods of that class, and merges the results into global
 | 
						|
Tester instance doctest.master.
 | 
						|
 | 
						|
You can create your own instances of doctest.Tester, and so build your own
 | 
						|
policies, or even run methods of doctest.master directly.  See
 | 
						|
doctest.Tester.__doc__ for details.
 | 
						|
 | 
						|
 | 
						|
SO WHAT DOES A DOCSTRING EXAMPLE LOOK LIKE ALREADY!?
 | 
						|
 | 
						|
Oh ya.  It's easy!  In most cases a copy-and-paste of an interactive
 | 
						|
console session works fine -- just make sure the leading whitespace is
 | 
						|
rigidly consistent (you can mix tabs and spaces if you're too lazy to do it
 | 
						|
right, but doctest is not in the business of guessing what you think a tab
 | 
						|
means).
 | 
						|
 | 
						|
    >>> # comments are ignored
 | 
						|
    >>> x = 12
 | 
						|
    >>> x
 | 
						|
    12
 | 
						|
    >>> if x == 13:
 | 
						|
    ...     print "yes"
 | 
						|
    ... else:
 | 
						|
    ...     print "no"
 | 
						|
    ...     print "NO"
 | 
						|
    ...     print "NO!!!"
 | 
						|
    ...
 | 
						|
    no
 | 
						|
    NO
 | 
						|
    NO!!!
 | 
						|
    >>>
 | 
						|
 | 
						|
Any expected output must immediately follow the final ">>>" or "..." line
 | 
						|
containing the code, and the expected output (if any) extends to the next
 | 
						|
">>>" or all-whitespace line.  That's it.
 | 
						|
 | 
						|
Bummers:
 | 
						|
 | 
						|
+ Expected output cannot contain an all-whitespace line, since such a line
 | 
						|
  is taken to signal the end of expected output.
 | 
						|
 | 
						|
+ Output to stdout is captured, but not output to stderr (exception
 | 
						|
  tracebacks are captured via a different means).
 | 
						|
 | 
						|
+ If you continue a line via backslashing in an interactive session, or for
 | 
						|
  any other reason use a backslash, you need to double the backslash in the
 | 
						|
  docstring version.  This is simply because you're in a string, and so the
 | 
						|
  backslash must be escaped for it to survive intact.  Like:
 | 
						|
 | 
						|
>>> if "yes" == \\
 | 
						|
...     "y" +   \\
 | 
						|
...     "es":   # in the source code you'll see the doubled backslashes
 | 
						|
...     print 'yes'
 | 
						|
yes
 | 
						|
 | 
						|
The starting column doesn't matter:
 | 
						|
 | 
						|
>>> assert "Easy!"
 | 
						|
     >>> import math
 | 
						|
            >>> math.floor(1.9)
 | 
						|
            1.0
 | 
						|
 | 
						|
and as many leading whitespace characters are stripped from the expected
 | 
						|
output as appeared in the initial ">>>" line that triggered it.
 | 
						|
 | 
						|
If you execute this very file, the examples above will be found and
 | 
						|
executed, leading to this output in verbose mode:
 | 
						|
 | 
						|
Running doctest.__doc__
 | 
						|
Trying: [1, 2, 3].remove(42)
 | 
						|
Expecting:
 | 
						|
Traceback (most recent call last):
 | 
						|
  File "<stdin>", line 1, in ?
 | 
						|
ValueError: list.remove(x): x not in list
 | 
						|
ok
 | 
						|
Trying: x = 12
 | 
						|
Expecting: nothing
 | 
						|
ok
 | 
						|
Trying: x
 | 
						|
Expecting: 12
 | 
						|
ok
 | 
						|
Trying:
 | 
						|
if x == 13:
 | 
						|
    print "yes"
 | 
						|
else:
 | 
						|
    print "no"
 | 
						|
    print "NO"
 | 
						|
    print "NO!!!"
 | 
						|
Expecting:
 | 
						|
no
 | 
						|
NO
 | 
						|
NO!!!
 | 
						|
ok
 | 
						|
... and a bunch more like that, with this summary at the end:
 | 
						|
 | 
						|
5 items had no tests:
 | 
						|
    doctest.Tester.__init__
 | 
						|
    doctest.Tester.run__test__
 | 
						|
    doctest.Tester.summarize
 | 
						|
    doctest.run_docstring_examples
 | 
						|
    doctest.testmod
 | 
						|
12 items passed all tests:
 | 
						|
   8 tests in doctest
 | 
						|
   6 tests in doctest.Tester
 | 
						|
  10 tests in doctest.Tester.merge
 | 
						|
  14 tests in doctest.Tester.rundict
 | 
						|
   3 tests in doctest.Tester.rundoc
 | 
						|
   3 tests in doctest.Tester.runstring
 | 
						|
   2 tests in doctest.__test__._TestClass
 | 
						|
   2 tests in doctest.__test__._TestClass.__init__
 | 
						|
   2 tests in doctest.__test__._TestClass.get
 | 
						|
   1 tests in doctest.__test__._TestClass.square
 | 
						|
   2 tests in doctest.__test__.string
 | 
						|
   7 tests in doctest.is_private
 | 
						|
60 tests in 17 items.
 | 
						|
60 passed and 0 failed.
 | 
						|
Test passed.
 | 
						|
"""
 | 
						|
 | 
						|
__all__ = [
 | 
						|
    'testmod',
 | 
						|
    'run_docstring_examples',
 | 
						|
    'is_private',
 | 
						|
    'Tester',
 | 
						|
]
 | 
						|
 | 
						|
import __future__
 | 
						|
 | 
						|
import re
 | 
						|
PS1 = ">>>"
 | 
						|
PS2 = "..."
 | 
						|
_isPS1 = re.compile(r"(\s*)" + re.escape(PS1)).match
 | 
						|
_isPS2 = re.compile(r"(\s*)" + re.escape(PS2)).match
 | 
						|
_isEmpty = re.compile(r"\s*$").match
 | 
						|
_isComment = re.compile(r"\s*#").match
 | 
						|
del re
 | 
						|
 | 
						|
from types import StringTypes as _StringTypes
 | 
						|
 | 
						|
from inspect import isclass    as _isclass
 | 
						|
from inspect import isfunction as _isfunction
 | 
						|
from inspect import ismodule   as _ismodule
 | 
						|
from inspect import classify_class_attrs as _classify_class_attrs
 | 
						|
 | 
						|
# Extract interactive examples from a string.  Return a list of triples,
 | 
						|
# (source, outcome, lineno).  "source" is the source code, and ends
 | 
						|
# with a newline iff the source spans more than one line.  "outcome" is
 | 
						|
# the expected output if any, else an empty string.  When not empty,
 | 
						|
# outcome always ends with a newline.  "lineno" is the line number,
 | 
						|
# 0-based wrt the start of the string, of the first source line.
 | 
						|
 | 
						|
def _extract_examples(s):
 | 
						|
    isPS1, isPS2 = _isPS1, _isPS2
 | 
						|
    isEmpty, isComment = _isEmpty, _isComment
 | 
						|
    examples = []
 | 
						|
    lines = s.split("\n")
 | 
						|
    i, n = 0, len(lines)
 | 
						|
    while i < n:
 | 
						|
        line = lines[i]
 | 
						|
        i = i + 1
 | 
						|
        m = isPS1(line)
 | 
						|
        if m is None:
 | 
						|
            continue
 | 
						|
        j = m.end(0)  # beyond the prompt
 | 
						|
        if isEmpty(line, j) or isComment(line, j):
 | 
						|
            # a bare prompt or comment -- not interesting
 | 
						|
            continue
 | 
						|
        lineno = i - 1
 | 
						|
        if line[j] != " ":
 | 
						|
            raise ValueError("line " + `lineno` + " of docstring lacks "
 | 
						|
                "blank after " + PS1 + ": " + line)
 | 
						|
        j = j + 1
 | 
						|
        blanks = m.group(1)
 | 
						|
        nblanks = len(blanks)
 | 
						|
        # suck up this and following PS2 lines
 | 
						|
        source = []
 | 
						|
        while 1:
 | 
						|
            source.append(line[j:])
 | 
						|
            line = lines[i]
 | 
						|
            m = isPS2(line)
 | 
						|
            if m:
 | 
						|
                if m.group(1) != blanks:
 | 
						|
                    raise ValueError("inconsistent leading whitespace "
 | 
						|
                        "in line " + `i` + " of docstring: " + line)
 | 
						|
                i = i + 1
 | 
						|
            else:
 | 
						|
                break
 | 
						|
        if len(source) == 1:
 | 
						|
            source = source[0]
 | 
						|
        else:
 | 
						|
            # get rid of useless null line from trailing empty "..."
 | 
						|
            if source[-1] == "":
 | 
						|
                del source[-1]
 | 
						|
            source = "\n".join(source) + "\n"
 | 
						|
        # suck up response
 | 
						|
        if isPS1(line) or isEmpty(line):
 | 
						|
            expect = ""
 | 
						|
        else:
 | 
						|
            expect = []
 | 
						|
            while 1:
 | 
						|
                if line[:nblanks] != blanks:
 | 
						|
                    raise ValueError("inconsistent leading whitespace "
 | 
						|
                        "in line " + `i` + " of docstring: " + line)
 | 
						|
                expect.append(line[nblanks:])
 | 
						|
                i = i + 1
 | 
						|
                line = lines[i]
 | 
						|
                if isPS1(line) or isEmpty(line):
 | 
						|
                    break
 | 
						|
            expect = "\n".join(expect) + "\n"
 | 
						|
        examples.append( (source, expect, lineno) )
 | 
						|
    return examples
 | 
						|
 | 
						|
# Capture stdout when running examples.
 | 
						|
 | 
						|
class _SpoofOut:
 | 
						|
    def __init__(self):
 | 
						|
        self.clear()
 | 
						|
    def write(self, s):
 | 
						|
        self.buf.append(s)
 | 
						|
    def get(self):
 | 
						|
        guts = "".join(self.buf)
 | 
						|
        # 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 guts and not guts.endswith("\n"):
 | 
						|
            guts = guts + "\n"
 | 
						|
        # Prevent softspace from screwing up the next test case, in
 | 
						|
        # case they used print with a trailing comma in an example.
 | 
						|
        if hasattr(self, "softspace"):
 | 
						|
            del self.softspace
 | 
						|
        return guts
 | 
						|
    def clear(self):
 | 
						|
        self.buf = []
 | 
						|
        if hasattr(self, "softspace"):
 | 
						|
            del self.softspace
 | 
						|
    def flush(self):
 | 
						|
        # JPython calls flush
 | 
						|
        pass
 | 
						|
 | 
						|
# Display some tag-and-msg pairs nicely, keeping the tag and its msg
 | 
						|
# on the same line when that makes sense.
 | 
						|
 | 
						|
def _tag_out(printer, *tag_msg_pairs):
 | 
						|
    for tag, msg in tag_msg_pairs:
 | 
						|
        printer(tag + ":")
 | 
						|
        msg_has_nl = msg[-1:] == "\n"
 | 
						|
        msg_has_two_nl = msg_has_nl and \
 | 
						|
                        msg.find("\n") < len(msg) - 1
 | 
						|
        if len(tag) + len(msg) < 76 and not msg_has_two_nl:
 | 
						|
            printer(" ")
 | 
						|
        else:
 | 
						|
            printer("\n")
 | 
						|
        printer(msg)
 | 
						|
        if not msg_has_nl:
 | 
						|
            printer("\n")
 | 
						|
 | 
						|
# Run list of examples, in context globs.  "out" can be used to display
 | 
						|
# stuff to "the real" stdout, and fakeout is an instance of _SpoofOut
 | 
						|
# that captures the examples' std output.  Return (#failures, #tries).
 | 
						|
 | 
						|
def _run_examples_inner(out, fakeout, examples, globs, verbose, name,
 | 
						|
                        compileflags):
 | 
						|
    import sys, traceback
 | 
						|
    OK, BOOM, FAIL = range(3)
 | 
						|
    NADA = "nothing"
 | 
						|
    stderr = _SpoofOut()
 | 
						|
    failures = 0
 | 
						|
    for source, want, lineno in examples:
 | 
						|
        if verbose:
 | 
						|
            _tag_out(out, ("Trying", source),
 | 
						|
                          ("Expecting", want or NADA))
 | 
						|
        fakeout.clear()
 | 
						|
        try:
 | 
						|
            exec compile(source, "<string>", "single",
 | 
						|
                         compileflags, 1) in globs
 | 
						|
            got = fakeout.get()
 | 
						|
            state = OK
 | 
						|
        except KeyboardInterrupt:
 | 
						|
            raise
 | 
						|
        except:
 | 
						|
            # See whether the exception was expected.
 | 
						|
            if want.find("Traceback (innermost last):\n") == 0 or \
 | 
						|
               want.find("Traceback (most recent call last):\n") == 0:
 | 
						|
                # Only compare exception type and value - the rest of
 | 
						|
                # the traceback isn't necessary.
 | 
						|
                want = want.split('\n')[-2] + '\n'
 | 
						|
                exc_type, exc_val = sys.exc_info()[:2]
 | 
						|
                got = traceback.format_exception_only(exc_type, exc_val)[-1]
 | 
						|
                state = OK
 | 
						|
            else:
 | 
						|
                # unexpected exception
 | 
						|
                stderr.clear()
 | 
						|
                traceback.print_exc(file=stderr)
 | 
						|
                state = BOOM
 | 
						|
 | 
						|
        if state == OK:
 | 
						|
            if got == want:
 | 
						|
                if verbose:
 | 
						|
                    out("ok\n")
 | 
						|
                continue
 | 
						|
            state = FAIL
 | 
						|
 | 
						|
        assert state in (FAIL, BOOM)
 | 
						|
        failures = failures + 1
 | 
						|
        out("*" * 65 + "\n")
 | 
						|
        _tag_out(out, ("Failure in example", source))
 | 
						|
        out("from line #" + `lineno` + " of " + name + "\n")
 | 
						|
        if state == FAIL:
 | 
						|
            _tag_out(out, ("Expected", want or NADA), ("Got", got))
 | 
						|
        else:
 | 
						|
            assert state == BOOM
 | 
						|
            _tag_out(out, ("Exception raised", stderr.get()))
 | 
						|
 | 
						|
    return failures, len(examples)
 | 
						|
 | 
						|
# Get the future-flags associated with the future features that have been
 | 
						|
# imported into globs.
 | 
						|
 | 
						|
def _extract_future_flags(globs):
 | 
						|
    flags = 0
 | 
						|
    for fname in __future__.all_feature_names:
 | 
						|
        feature = globs.get(fname, None)
 | 
						|
        if feature is getattr(__future__, fname):
 | 
						|
            flags |= feature.compiler_flag
 | 
						|
    return flags
 | 
						|
 | 
						|
# Run list of examples, in a shallow copy of context (dict) globs.
 | 
						|
# Return (#failures, #tries).
 | 
						|
 | 
						|
def _run_examples(examples, globs, verbose, name, compileflags):
 | 
						|
    import sys
 | 
						|
    saveout = sys.stdout
 | 
						|
    globs = globs.copy()
 | 
						|
    try:
 | 
						|
        sys.stdout = fakeout = _SpoofOut()
 | 
						|
        x = _run_examples_inner(saveout.write, fakeout, examples,
 | 
						|
                                globs, verbose, name, compileflags)
 | 
						|
    finally:
 | 
						|
        sys.stdout = saveout
 | 
						|
        # While Python gc can clean up most cycles on its own, it doesn't
 | 
						|
        # chase frame objects.  This is especially irksome when running
 | 
						|
        # generator tests that raise exceptions, because a named generator-
 | 
						|
        # iterator gets an entry in globs, and the generator-iterator
 | 
						|
        # object's frame's traceback info points back to globs.  This is
 | 
						|
        # easy to break just by clearing the namespace.  This can also
 | 
						|
        # help to break other kinds of cycles, and even for cycles that
 | 
						|
        # gc can break itself it's better to break them ASAP.
 | 
						|
        globs.clear()
 | 
						|
    return x
 | 
						|
 | 
						|
def run_docstring_examples(f, globs, verbose=0, name="NoName",
 | 
						|
                           compileflags=None):
 | 
						|
    """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__.
 | 
						|
 | 
						|
    Use (a shallow copy of) dict globs as the globals for execution.
 | 
						|
    Return (#failures, #tries).
 | 
						|
 | 
						|
    If optional arg verbose is true, print stuff even if there are no
 | 
						|
    failures.
 | 
						|
    Use string name in failure msgs.
 | 
						|
    """
 | 
						|
 | 
						|
    try:
 | 
						|
        doc = f.__doc__
 | 
						|
        if not doc:
 | 
						|
            # docstring empty or None
 | 
						|
            return 0, 0
 | 
						|
        # just in case CT invents a doc object that has to be forced
 | 
						|
        # to look like a string <0.9 wink>
 | 
						|
        doc = str(doc)
 | 
						|
    except KeyboardInterrupt:
 | 
						|
        raise
 | 
						|
    except:
 | 
						|
        return 0, 0
 | 
						|
 | 
						|
    e = _extract_examples(doc)
 | 
						|
    if not e:
 | 
						|
        return 0, 0
 | 
						|
    if compileflags is None:
 | 
						|
        compileflags = _extract_future_flags(globs)
 | 
						|
    return _run_examples(e, globs, verbose, name, compileflags)
 | 
						|
 | 
						|
def is_private(prefix, base):
 | 
						|
    """prefix, base -> true iff name prefix + "." + base is "private".
 | 
						|
 | 
						|
    Prefix may be an empty string, and base does not contain a period.
 | 
						|
    Prefix is ignored (although functions you write conforming to this
 | 
						|
    protocol may make use of it).
 | 
						|
    Return true iff base begins with an (at least one) underscore, but
 | 
						|
    does not both begin and end with (at least) two underscores.
 | 
						|
 | 
						|
    >>> is_private("a.b", "my_func")
 | 
						|
    False
 | 
						|
    >>> is_private("____", "_my_func")
 | 
						|
    True
 | 
						|
    >>> is_private("someclass", "__init__")
 | 
						|
    False
 | 
						|
    >>> is_private("sometypo", "__init_")
 | 
						|
    True
 | 
						|
    >>> is_private("x.y.z", "_")
 | 
						|
    True
 | 
						|
    >>> is_private("_x.y.z", "__")
 | 
						|
    False
 | 
						|
    >>> is_private("", "")  # senseless but consistent
 | 
						|
    False
 | 
						|
    """
 | 
						|
 | 
						|
    return base[:1] == "_" and not base[:2] == "__" == base[-2:]
 | 
						|
 | 
						|
# Determine if a class of function was defined in the given module.
 | 
						|
 | 
						|
def _from_module(module, object):
 | 
						|
    if _isfunction(object):
 | 
						|
        return module.__dict__ is object.func_globals
 | 
						|
    if _isclass(object):
 | 
						|
        return module.__name__ == object.__module__
 | 
						|
    raise ValueError("object must be a class or function")
 | 
						|
 | 
						|
class Tester:
 | 
						|
    """Class Tester -- runs docstring examples and accumulates stats.
 | 
						|
 | 
						|
In normal use, function doctest.testmod() hides all this from you,
 | 
						|
so use that if you can.  Create your own instances of Tester to do
 | 
						|
fancier things.
 | 
						|
 | 
						|
Methods:
 | 
						|
    runstring(s, name)
 | 
						|
        Search string s for examples to run; use name for logging.
 | 
						|
        Return (#failures, #tries).
 | 
						|
 | 
						|
    rundoc(object, name=None)
 | 
						|
        Search object.__doc__ for examples to run; use name (or
 | 
						|
        object.__name__) for logging.  Return (#failures, #tries).
 | 
						|
 | 
						|
    rundict(d, name, module=None)
 | 
						|
        Search for examples in docstrings in all of d.values(); use name
 | 
						|
        for logging.  Exclude functions and classes not defined in module
 | 
						|
        if specified.  Return (#failures, #tries).
 | 
						|
 | 
						|
    run__test__(d, name)
 | 
						|
        Treat dict d like module.__test__.  Return (#failures, #tries).
 | 
						|
 | 
						|
    summarize(verbose=None)
 | 
						|
        Display summary of testing results, to stdout.  Return
 | 
						|
        (#failures, #tries).
 | 
						|
 | 
						|
    merge(other)
 | 
						|
        Merge in the test results from Tester instance "other".
 | 
						|
 | 
						|
>>> from doctest import Tester
 | 
						|
>>> t = Tester(globs={'x': 42}, verbose=0)
 | 
						|
>>> t.runstring(r'''
 | 
						|
...      >>> x = x * 2
 | 
						|
...      >>> print x
 | 
						|
...      42
 | 
						|
... ''', 'XYZ')
 | 
						|
*****************************************************************
 | 
						|
Failure in example: print x
 | 
						|
from line #2 of XYZ
 | 
						|
Expected: 42
 | 
						|
Got: 84
 | 
						|
(1, 2)
 | 
						|
>>> t.runstring(">>> x = x * 2\\n>>> print x\\n84\\n", 'example2')
 | 
						|
(0, 2)
 | 
						|
>>> t.summarize()
 | 
						|
*****************************************************************
 | 
						|
1 items had failures:
 | 
						|
   1 of   2 in XYZ
 | 
						|
***Test Failed*** 1 failures.
 | 
						|
(1, 4)
 | 
						|
>>> t.summarize(verbose=1)
 | 
						|
1 items passed all tests:
 | 
						|
   2 tests in example2
 | 
						|
*****************************************************************
 | 
						|
1 items had failures:
 | 
						|
   1 of   2 in XYZ
 | 
						|
4 tests in 2 items.
 | 
						|
3 passed and 1 failed.
 | 
						|
***Test Failed*** 1 failures.
 | 
						|
(1, 4)
 | 
						|
>>>
 | 
						|
"""
 | 
						|
 | 
						|
    def __init__(self, mod=None, globs=None, verbose=None,
 | 
						|
                 isprivate=None):
 | 
						|
        """mod=None, globs=None, verbose=None, isprivate=None
 | 
						|
 | 
						|
See doctest.__doc__ for an overview.
 | 
						|
 | 
						|
Optional keyword arg "mod" is a module, whose globals are used for
 | 
						|
executing examples.  If not specified, globs must be specified.
 | 
						|
 | 
						|
Optional keyword arg "globs" gives a dict to be used as the globals
 | 
						|
when executing examples; if not specified, use the globals from
 | 
						|
module mod.
 | 
						|
 | 
						|
In either case, a copy of the dict is used for each docstring
 | 
						|
examined.
 | 
						|
 | 
						|
Optional keyword arg "verbose" prints lots of stuff if true, only
 | 
						|
failures if false; by default, it's true iff "-v" is in sys.argv.
 | 
						|
 | 
						|
Optional keyword arg "isprivate" specifies a function used to determine
 | 
						|
whether a name is private.  The default function is doctest.is_private;
 | 
						|
see its docs for details.
 | 
						|
"""
 | 
						|
 | 
						|
        if mod is None and globs is None:
 | 
						|
            raise TypeError("Tester.__init__: must specify mod or globs")
 | 
						|
        if mod is not None and not _ismodule(mod):
 | 
						|
            raise TypeError("Tester.__init__: mod must be a module; " +
 | 
						|
                            `mod`)
 | 
						|
        if globs is None:
 | 
						|
            globs = mod.__dict__
 | 
						|
        self.globs = globs
 | 
						|
 | 
						|
        if verbose is None:
 | 
						|
            import sys
 | 
						|
            verbose = "-v" in sys.argv
 | 
						|
        self.verbose = verbose
 | 
						|
 | 
						|
        if isprivate is None:
 | 
						|
            isprivate = is_private
 | 
						|
        self.isprivate = isprivate
 | 
						|
 | 
						|
        self.name2ft = {}   # map name to (#failures, #trials) pair
 | 
						|
 | 
						|
        self.compileflags = _extract_future_flags(globs)
 | 
						|
 | 
						|
    def runstring(self, s, name):
 | 
						|
        """
 | 
						|
        s, name -> search string s for examples to run, logging as name.
 | 
						|
 | 
						|
        Use string name as the key for logging the outcome.
 | 
						|
        Return (#failures, #examples).
 | 
						|
 | 
						|
        >>> t = Tester(globs={}, verbose=1)
 | 
						|
        >>> test = r'''
 | 
						|
        ...    # just an example
 | 
						|
        ...    >>> x = 1 + 2
 | 
						|
        ...    >>> x
 | 
						|
        ...    3
 | 
						|
        ... '''
 | 
						|
        >>> t.runstring(test, "Example")
 | 
						|
        Running string Example
 | 
						|
        Trying: x = 1 + 2
 | 
						|
        Expecting: nothing
 | 
						|
        ok
 | 
						|
        Trying: x
 | 
						|
        Expecting: 3
 | 
						|
        ok
 | 
						|
        0 of 2 examples failed in string Example
 | 
						|
        (0, 2)
 | 
						|
        """
 | 
						|
 | 
						|
        if self.verbose:
 | 
						|
            print "Running string", name
 | 
						|
        f = t = 0
 | 
						|
        e = _extract_examples(s)
 | 
						|
        if e:
 | 
						|
            f, t = _run_examples(e, self.globs, self.verbose, name,
 | 
						|
                                 self.compileflags)
 | 
						|
        if self.verbose:
 | 
						|
            print f, "of", t, "examples failed in string", name
 | 
						|
        self.__record_outcome(name, f, t)
 | 
						|
        return f, t
 | 
						|
 | 
						|
    def rundoc(self, object, name=None):
 | 
						|
        """
 | 
						|
        object, name=None -> search object.__doc__ for examples to run.
 | 
						|
 | 
						|
        Use optional string name as the key for logging the outcome;
 | 
						|
        by default use object.__name__.
 | 
						|
        Return (#failures, #examples).
 | 
						|
        If object is a class object, search recursively for method
 | 
						|
        docstrings too.
 | 
						|
        object.__doc__ is examined regardless of name, but if object is
 | 
						|
        a class, whether private names reached from object are searched
 | 
						|
        depends on the constructor's "isprivate" argument.
 | 
						|
 | 
						|
        >>> t = Tester(globs={}, verbose=0)
 | 
						|
        >>> def _f():
 | 
						|
        ...     '''Trivial docstring example.
 | 
						|
        ...     >>> assert 2 == 2
 | 
						|
        ...     '''
 | 
						|
        ...     return 32
 | 
						|
        ...
 | 
						|
        >>> t.rundoc(_f)  # expect 0 failures in 1 example
 | 
						|
        (0, 1)
 | 
						|
        """
 | 
						|
 | 
						|
        if name is None:
 | 
						|
            try:
 | 
						|
                name = object.__name__
 | 
						|
            except AttributeError:
 | 
						|
                raise ValueError("Tester.rundoc: name must be given "
 | 
						|
                    "when object.__name__ doesn't exist; " + `object`)
 | 
						|
        if self.verbose:
 | 
						|
            print "Running", name + ".__doc__"
 | 
						|
        f, t = run_docstring_examples(object, self.globs, self.verbose, name,
 | 
						|
                                      self.compileflags)
 | 
						|
        if self.verbose:
 | 
						|
            print f, "of", t, "examples failed in", name + ".__doc__"
 | 
						|
        self.__record_outcome(name, f, t)
 | 
						|
        if _isclass(object):
 | 
						|
            # In 2.2, class and static methods complicate life.  Build
 | 
						|
            # a dict "that works", by hook or by crook.
 | 
						|
            d = {}
 | 
						|
            for tag, kind, homecls, value in _classify_class_attrs(object):
 | 
						|
 | 
						|
                if homecls is not object:
 | 
						|
                    # Only look at names defined immediately by the class.
 | 
						|
                    continue
 | 
						|
 | 
						|
                elif self.isprivate(name, tag):
 | 
						|
                    continue
 | 
						|
 | 
						|
                elif kind == "method":
 | 
						|
                    # value is already a function
 | 
						|
                    d[tag] = value
 | 
						|
 | 
						|
                elif kind == "static method":
 | 
						|
                    # value isn't a function, but getattr reveals one
 | 
						|
                    d[tag] = getattr(object, tag)
 | 
						|
 | 
						|
                elif kind == "class method":
 | 
						|
                    # Hmm.  A classmethod object doesn't seem to reveal
 | 
						|
                    # enough.  But getattr turns it into a bound method,
 | 
						|
                    # and from there .im_func retrieves the underlying
 | 
						|
                    # function.
 | 
						|
                    d[tag] = getattr(object, tag).im_func
 | 
						|
 | 
						|
                elif kind == "property":
 | 
						|
                    # The methods implementing the property have their
 | 
						|
                    # own docstrings -- but the property may have one too.
 | 
						|
                    if value.__doc__ is not None:
 | 
						|
                        d[tag] = str(value.__doc__)
 | 
						|
 | 
						|
                elif kind == "data":
 | 
						|
                    # Grab nested classes.
 | 
						|
                    if _isclass(value):
 | 
						|
                        d[tag] = value
 | 
						|
 | 
						|
                else:
 | 
						|
                    raise ValueError("teach doctest about %r" % kind)
 | 
						|
 | 
						|
            f2, t2 = self.run__test__(d, name)
 | 
						|
            f += f2
 | 
						|
            t += t2
 | 
						|
 | 
						|
        return f, t
 | 
						|
 | 
						|
    def rundict(self, d, name, module=None):
 | 
						|
        """
 | 
						|
        d, name, module=None -> search for docstring examples in d.values().
 | 
						|
 | 
						|
        For k, v in d.items() such that v is a function or class,
 | 
						|
        do self.rundoc(v, name + "." + k).  Whether this includes
 | 
						|
        objects with private names depends on the constructor's
 | 
						|
        "isprivate" argument.  If module is specified, functions and
 | 
						|
        classes that are not defined in module are excluded.
 | 
						|
        Return aggregate (#failures, #examples).
 | 
						|
 | 
						|
        Build and populate two modules with sample functions to test that
 | 
						|
        exclusion of external functions and classes works.
 | 
						|
 | 
						|
        >>> import new
 | 
						|
        >>> m1 = new.module('_m1')
 | 
						|
        >>> m2 = new.module('_m2')
 | 
						|
        >>> test_data = \"""
 | 
						|
        ... def _f():
 | 
						|
        ...     '''>>> assert 1 == 1
 | 
						|
        ...     '''
 | 
						|
        ... def g():
 | 
						|
        ...    '''>>> assert 2 != 1
 | 
						|
        ...    '''
 | 
						|
        ... class H:
 | 
						|
        ...    '''>>> assert 2 > 1
 | 
						|
        ...    '''
 | 
						|
        ...    def bar(self):
 | 
						|
        ...        '''>>> assert 1 < 2
 | 
						|
        ...        '''
 | 
						|
        ... \"""
 | 
						|
        >>> exec test_data in m1.__dict__
 | 
						|
        >>> exec test_data in m2.__dict__
 | 
						|
        >>> m1.__dict__.update({"f2": m2._f, "g2": m2.g, "h2": m2.H})
 | 
						|
 | 
						|
        Tests that objects outside m1 are excluded:
 | 
						|
 | 
						|
        >>> t = Tester(globs={}, verbose=0)
 | 
						|
        >>> t.rundict(m1.__dict__, "rundict_test", m1)  # _f, f2 and g2 and h2 skipped
 | 
						|
        (0, 3)
 | 
						|
 | 
						|
        Again, but with a custom isprivate function allowing _f:
 | 
						|
 | 
						|
        >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0)
 | 
						|
        >>> t.rundict(m1.__dict__, "rundict_test_pvt", m1)  # Only f2, g2 and h2 skipped
 | 
						|
        (0, 4)
 | 
						|
 | 
						|
        And once more, not excluding stuff outside m1:
 | 
						|
 | 
						|
        >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0)
 | 
						|
        >>> t.rundict(m1.__dict__, "rundict_test_pvt")  # None are skipped.
 | 
						|
        (0, 8)
 | 
						|
 | 
						|
        The exclusion of objects from outside the designated module is
 | 
						|
        meant to be invoked automagically by testmod.
 | 
						|
 | 
						|
        >>> testmod(m1)
 | 
						|
        (0, 3)
 | 
						|
 | 
						|
        """
 | 
						|
 | 
						|
        if not hasattr(d, "items"):
 | 
						|
            raise TypeError("Tester.rundict: d must support .items(); " +
 | 
						|
                            `d`)
 | 
						|
        f = t = 0
 | 
						|
        # Run the tests by alpha order of names, for consistency in
 | 
						|
        # verbose-mode output.
 | 
						|
        names = d.keys()
 | 
						|
        names.sort()
 | 
						|
        for thisname in names:
 | 
						|
            value = d[thisname]
 | 
						|
            if _isfunction(value) or _isclass(value):
 | 
						|
                if module and not _from_module(module, value):
 | 
						|
                    continue
 | 
						|
                f2, t2 = self.__runone(value, name + "." + thisname)
 | 
						|
                f = f + f2
 | 
						|
                t = t + t2
 | 
						|
        return f, t
 | 
						|
 | 
						|
    def run__test__(self, d, name):
 | 
						|
        """d, name -> Treat dict d like module.__test__.
 | 
						|
 | 
						|
        Return (#failures, #tries).
 | 
						|
        See testmod.__doc__ for details.
 | 
						|
        """
 | 
						|
 | 
						|
        failures = tries = 0
 | 
						|
        prefix = name + "."
 | 
						|
        savepvt = self.isprivate
 | 
						|
        try:
 | 
						|
            self.isprivate = lambda *args: 0
 | 
						|
            # Run the tests by alpha order of names, for consistency in
 | 
						|
            # verbose-mode output.
 | 
						|
            keys = d.keys()
 | 
						|
            keys.sort()
 | 
						|
            for k in keys:
 | 
						|
                v = d[k]
 | 
						|
                thisname = prefix + k
 | 
						|
                if type(v) in _StringTypes:
 | 
						|
                    f, t = self.runstring(v, thisname)
 | 
						|
                elif _isfunction(v) or _isclass(v):
 | 
						|
                    f, t = self.rundoc(v, thisname)
 | 
						|
                else:
 | 
						|
                    raise TypeError("Tester.run__test__: values in "
 | 
						|
                            "dict must be strings, functions "
 | 
						|
                            "or classes; " + `v`)
 | 
						|
                failures = failures + f
 | 
						|
                tries = tries + t
 | 
						|
        finally:
 | 
						|
            self.isprivate = savepvt
 | 
						|
        return failures, tries
 | 
						|
 | 
						|
    def summarize(self, verbose=None):
 | 
						|
        """
 | 
						|
        verbose=None -> summarize results, return (#failures, #tests).
 | 
						|
 | 
						|
        Print summary of test results to stdout.
 | 
						|
        Optional arg 'verbose' controls how wordy this is.  By
 | 
						|
        default, use the verbose setting established by the
 | 
						|
        constructor.
 | 
						|
        """
 | 
						|
 | 
						|
        if verbose is None:
 | 
						|
            verbose = self.verbose
 | 
						|
        notests = []
 | 
						|
        passed = []
 | 
						|
        failed = []
 | 
						|
        totalt = totalf = 0
 | 
						|
        for x in self.name2ft.items():
 | 
						|
            name, (f, t) = x
 | 
						|
            assert f <= t
 | 
						|
            totalt = totalt + t
 | 
						|
            totalf = totalf + f
 | 
						|
            if t == 0:
 | 
						|
                notests.append(name)
 | 
						|
            elif f == 0:
 | 
						|
                passed.append( (name, t) )
 | 
						|
            else:
 | 
						|
                failed.append(x)
 | 
						|
        if verbose:
 | 
						|
            if notests:
 | 
						|
                print len(notests), "items had no tests:"
 | 
						|
                notests.sort()
 | 
						|
                for thing in notests:
 | 
						|
                    print "   ", thing
 | 
						|
            if passed:
 | 
						|
                print len(passed), "items passed all tests:"
 | 
						|
                passed.sort()
 | 
						|
                for thing, count in passed:
 | 
						|
                    print " %3d tests in %s" % (count, thing)
 | 
						|
        if failed:
 | 
						|
            print "*" * 65
 | 
						|
            print len(failed), "items had failures:"
 | 
						|
            failed.sort()
 | 
						|
            for thing, (f, t) in failed:
 | 
						|
                print " %3d of %3d in %s" % (f, t, thing)
 | 
						|
        if verbose:
 | 
						|
            print totalt, "tests in", len(self.name2ft), "items."
 | 
						|
            print totalt - totalf, "passed and", totalf, "failed."
 | 
						|
        if totalf:
 | 
						|
            print "***Test Failed***", totalf, "failures."
 | 
						|
        elif verbose:
 | 
						|
            print "Test passed."
 | 
						|
        return totalf, totalt
 | 
						|
 | 
						|
    def merge(self, other):
 | 
						|
        """
 | 
						|
        other -> merge in test results from the other Tester instance.
 | 
						|
 | 
						|
        If self and other both have a test result for something
 | 
						|
        with the same name, the (#failures, #tests) results are
 | 
						|
        summed, and a warning is printed to stdout.
 | 
						|
 | 
						|
        >>> from doctest import Tester
 | 
						|
        >>> t1 = Tester(globs={}, verbose=0)
 | 
						|
        >>> t1.runstring('''
 | 
						|
        ... >>> x = 12
 | 
						|
        ... >>> print x
 | 
						|
        ... 12
 | 
						|
        ... ''', "t1example")
 | 
						|
        (0, 2)
 | 
						|
        >>>
 | 
						|
        >>> t2 = Tester(globs={}, verbose=0)
 | 
						|
        >>> t2.runstring('''
 | 
						|
        ... >>> x = 13
 | 
						|
        ... >>> print x
 | 
						|
        ... 13
 | 
						|
        ... ''', "t2example")
 | 
						|
        (0, 2)
 | 
						|
        >>> common = ">>> assert 1 + 2 == 3\\n"
 | 
						|
        >>> t1.runstring(common, "common")
 | 
						|
        (0, 1)
 | 
						|
        >>> t2.runstring(common, "common")
 | 
						|
        (0, 1)
 | 
						|
        >>> t1.merge(t2)
 | 
						|
        *** Tester.merge: 'common' in both testers; summing outcomes.
 | 
						|
        >>> t1.summarize(1)
 | 
						|
        3 items passed all tests:
 | 
						|
           2 tests in common
 | 
						|
           2 tests in t1example
 | 
						|
           2 tests in t2example
 | 
						|
        6 tests in 3 items.
 | 
						|
        6 passed and 0 failed.
 | 
						|
        Test passed.
 | 
						|
        (0, 6)
 | 
						|
        >>>
 | 
						|
        """
 | 
						|
 | 
						|
        d = self.name2ft
 | 
						|
        for name, (f, t) in other.name2ft.items():
 | 
						|
            if name in d:
 | 
						|
                print "*** Tester.merge: '" + name + "' in both" \
 | 
						|
                    " testers; summing outcomes."
 | 
						|
                f2, t2 = d[name]
 | 
						|
                f = f + f2
 | 
						|
                t = t + t2
 | 
						|
            d[name] = f, t
 | 
						|
 | 
						|
    def __record_outcome(self, name, f, t):
 | 
						|
        if name in self.name2ft:
 | 
						|
            print "*** Warning: '" + name + "' was tested before;", \
 | 
						|
                "summing outcomes."
 | 
						|
            f2, t2 = self.name2ft[name]
 | 
						|
            f = f + f2
 | 
						|
            t = t + t2
 | 
						|
        self.name2ft[name] = f, t
 | 
						|
 | 
						|
    def __runone(self, target, name):
 | 
						|
        if "." in name:
 | 
						|
            i = name.rindex(".")
 | 
						|
            prefix, base = name[:i], name[i+1:]
 | 
						|
        else:
 | 
						|
            prefix, base = "", base
 | 
						|
        if self.isprivate(prefix, base):
 | 
						|
            return 0, 0
 | 
						|
        return self.rundoc(target, name)
 | 
						|
 | 
						|
master = None
 | 
						|
 | 
						|
def testmod(m, name=None, globs=None, verbose=None, isprivate=None,
 | 
						|
               report=1):
 | 
						|
    """m, name=None, globs=None, verbose=None, isprivate=None, report=1
 | 
						|
 | 
						|
    Test examples in docstrings in functions and classes reachable from
 | 
						|
    module m, starting with m.__doc__.  Private names are skipped.
 | 
						|
 | 
						|
    Also test examples reachable from dict m.__test__ if it exists and is
 | 
						|
    not None.  m.__dict__ maps names to functions, classes and strings;
 | 
						|
    function and class docstrings are tested even if the name is private;
 | 
						|
    strings are tested directly, as if they were docstrings.
 | 
						|
 | 
						|
    Return (#failures, #tests).
 | 
						|
 | 
						|
    See doctest.__doc__ for an overview.
 | 
						|
 | 
						|
    Optional keyword arg "name" gives the name of the module; by default
 | 
						|
    use m.__name__.
 | 
						|
 | 
						|
    Optional keyword arg "globs" gives a dict to be used as the globals
 | 
						|
    when executing examples; by default, use m.__dict__.  A copy of this
 | 
						|
    dict is actually used for each docstring, so that each docstring's
 | 
						|
    examples start with a clean slate.
 | 
						|
 | 
						|
    Optional keyword arg "verbose" prints lots of stuff if true, prints
 | 
						|
    only failures if false; by default, it's true iff "-v" is in sys.argv.
 | 
						|
 | 
						|
    Optional keyword arg "isprivate" specifies a function used to
 | 
						|
    determine whether a name is private.  The default function is
 | 
						|
    doctest.is_private; see its docs for details.
 | 
						|
 | 
						|
    Optional keyword arg "report" prints a summary at the end when true,
 | 
						|
    else prints nothing at the end.  In verbose mode, the summary is
 | 
						|
    detailed, else very brief (in fact, empty if all tests passed).
 | 
						|
 | 
						|
    Advanced tomfoolery:  testmod runs methods of a local instance of
 | 
						|
    class doctest.Tester, then merges the results into (or creates)
 | 
						|
    global Tester instance doctest.master.  Methods of doctest.master
 | 
						|
    can be called directly too, if you want to do something unusual.
 | 
						|
    Passing report=0 to testmod is especially useful then, to delay
 | 
						|
    displaying a summary.  Invoke doctest.master.summarize(verbose)
 | 
						|
    when you're done fiddling.
 | 
						|
    """
 | 
						|
 | 
						|
    global master
 | 
						|
 | 
						|
    if not _ismodule(m):
 | 
						|
        raise TypeError("testmod: module required; " + `m`)
 | 
						|
    if name is None:
 | 
						|
        name = m.__name__
 | 
						|
    tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate)
 | 
						|
    failures, tries = tester.rundoc(m, name)
 | 
						|
    f, t = tester.rundict(m.__dict__, name, m)
 | 
						|
    failures = failures + f
 | 
						|
    tries = tries + t
 | 
						|
    if hasattr(m, "__test__"):
 | 
						|
        testdict = m.__test__
 | 
						|
        if testdict:
 | 
						|
            if not hasattr(testdict, "items"):
 | 
						|
                raise TypeError("testmod: module.__test__ must support "
 | 
						|
                                ".items(); " + `testdict`)
 | 
						|
            f, t = tester.run__test__(testdict, name + ".__test__")
 | 
						|
            failures = failures + f
 | 
						|
            tries = tries + t
 | 
						|
    if report:
 | 
						|
        tester.summarize()
 | 
						|
    if master is None:
 | 
						|
        master = tester
 | 
						|
    else:
 | 
						|
        master.merge(tester)
 | 
						|
    return failures, tries
 | 
						|
 | 
						|
class _TestClass:
 | 
						|
    """
 | 
						|
    A pointless class, for sanity-checking of docstring testing.
 | 
						|
 | 
						|
    Methods:
 | 
						|
        square()
 | 
						|
        get()
 | 
						|
 | 
						|
    >>> _TestClass(13).get() + _TestClass(-12).get()
 | 
						|
    1
 | 
						|
    >>> hex(_TestClass(13).square().get())
 | 
						|
    '0xa9'
 | 
						|
    """
 | 
						|
 | 
						|
    def __init__(self, val):
 | 
						|
        """val -> _TestClass object with associated value val.
 | 
						|
 | 
						|
        >>> t = _TestClass(123)
 | 
						|
        >>> print t.get()
 | 
						|
        123
 | 
						|
        """
 | 
						|
 | 
						|
        self.val = val
 | 
						|
 | 
						|
    def square(self):
 | 
						|
        """square() -> square TestClass's associated value
 | 
						|
 | 
						|
        >>> _TestClass(13).square().get()
 | 
						|
        169
 | 
						|
        """
 | 
						|
 | 
						|
        self.val = self.val ** 2
 | 
						|
        return self
 | 
						|
 | 
						|
    def get(self):
 | 
						|
        """get() -> return TestClass's associated value.
 | 
						|
 | 
						|
        >>> x = _TestClass(-42)
 | 
						|
        >>> print x.get()
 | 
						|
        -42
 | 
						|
        """
 | 
						|
 | 
						|
        return self.val
 | 
						|
 | 
						|
__test__ = {"_TestClass": _TestClass,
 | 
						|
            "string": r"""
 | 
						|
                      Example of a string object, searched as-is.
 | 
						|
                      >>> x = 1; y = 2
 | 
						|
                      >>> x + y, x * y
 | 
						|
                      (3, 2)
 | 
						|
                      """
 | 
						|
           }
 | 
						|
 | 
						|
def _test():
 | 
						|
    import doctest
 | 
						|
    return doctest.testmod(doctest)
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    _test()
 |