doctest-- The Little Module That Could --finally makes it to the Big Show <wink>.
diff --git a/Lib/doctest.py b/Lib/doctest.py
new file mode 100644
index 0000000..1b06990
--- /dev/null
+++ b/Lib/doctest.py
@@ -0,0 +1,1101 @@
+# Module doctest version 0.9.6
+# 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.
+
++ C.__doc__ for all classes C in M.__dict__.values(), except those with
+  private names.
+
++ 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).
+
+Warning:  imports can cause trouble; e.g., if you do
+
+from XYZ import XYZclass
+
+then XYZclass is a name in M.__dict__ too, and doctest has no way to know
+that XYZclass wasn't *defined* in M.  So it may try to execute the examples
+in XYZclass's docstring, and those in turn may require a different set of
+globals to work correctly.  I prefer to do "import *"- friendly imports,
+a la
+
+import XYY
+_XYZclass = XYZ.XYZclass
+del XYZ
+
+or (Python 2.0)
+
+from XYZ import XYZclass as _XYZclass
+
+and then the leading underscore stops testmod from going nuts.  You may
+prefer the method in the next section.
+
+
+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/0
+    Traceback (innermost last):
+      File "<stdin>", line 1, in ?
+    ZeroDivisionError: integer division or modulo by zero
+    >>>
+
+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/0
+Expecting:
+Traceback (innermost last):
+  File "<stdin>", line 1, in ?
+ZeroDivisionError: integer division or modulo by zero
+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
+   7 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
+53 tests in 17 items.
+53 passed and 0 failed.
+Test passed.
+"""
+
+# 0,0,1    06-Mar-1999
+#    initial version posted
+# 0,0,2    06-Mar-1999
+#    loosened parsing:
+#        cater to stinkin' tabs
+#        don't insist on a blank after PS2 prefix
+#            so trailing "... " line from a compound stmt no longer
+#            breaks if the file gets whitespace-trimmed
+#    better error msgs for inconsistent leading whitespace
+# 0,9,1    08-Mar-1999
+#    exposed the Tester class and added client methods
+#        plus docstring examples of their use (eww - head-twisting!)
+#    fixed logic error in reporting total # of tests & failures
+#    added __test__ support to testmod (a pale reflection of Christian
+#        Tismer's vision ...)
+#    removed the "deep" argument; fiddle __test__ instead
+#    simplified endcase logic for extracting tests, and running them.
+#        before, if no output was expected but some was produced
+#        anyway via an eval'ed result, the discrepancy wasn't caught
+#    made TestClass private and used __test__ to get at it
+#    many doc updates
+#    speed _SpoofOut for long expected outputs
+# 0,9,2    09-Mar-1999
+#    throw out comments from examples, enabling use of the much simpler
+#        exec compile(... "single") ...
+#        for simulating the runtime; that barfs on comment-only lines
+#    used the traceback module to do a much better job of reporting
+#        exceptions
+#    run __doc__ values thru str(), "just in case"
+#    privateness of names now determined by an overridable "isprivate"
+#        function
+#    by default a name now considered to be private iff it begins with
+#        an underscore but doesn't both begin & end with two of 'em; so
+#        e.g. Class.__init__ etc are searched now -- as they always
+#        should have been
+# 0,9,3    18-Mar-1999
+#    added .flush stub to _SpoofOut (JPython buglet diagnosed by
+#        Hugh Emberson)
+#    repaired ridiculous docs about backslashes in examples
+#    minor internal changes
+#    changed source to Unix line-end conventions
+#    moved __test__ logic into new Tester.run__test__ method
+# 0,9,4    27-Mar-1999
+#    report item name and line # in failing examples
+# 0,9,5    29-Jun-1999
+#    allow straightforward exceptions in examples - thanks to Mark Hammond!
+# 0,9,6    16-Jan-2001
+#    fiddling for changes in Python 2.0:  some of the embedded docstring
+#        examples no longer worked *exactly* as advertised, due to minor
+#        language changes, and running doctest on itself pointed that out.
+#        Hard to think of a better example of why this is useful <wink>.
+
+__version__ = 0, 9, 6
+
+import types
+_FunctionType = types.FunctionType
+_ClassType    = types.ClassType
+_ModuleType   = types.ModuleType
+_StringType   = types.StringType
+del types
+
+import string
+_string_find = string.find
+_string_join = string.join
+_string_split = string.split
+_string_rindex = string.rindex
+del string
+
+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
+
+# 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 = _string_split(s, "\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 = _string_join(source, "\n") + "\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 = _string_join(expect, "\n") + "\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):
+        return _string_join(self.buf, "")
+    def clear(self):
+        self.buf = []
+    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 \
+                        _string_find(msg, "\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):
+    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") in globs
+            got = fakeout.get()
+            state = OK
+        except:
+            # See whether the exception was expected.
+            if _string_find(want, "Traceback (innermost last):\n") == 0:
+                # Only compare exception type and value - the rest of
+                # the traceback isn't necessary.
+                want = _string_split(want, '\n')[-2] + '\n'
+                exc_type, exc_val, exc_tb = sys.exc_info()
+                got = traceback.format_exception_only(exc_type, exc_val)[0]
+                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)
+
+# Run list of examples, in context globs.  Return (#failures, #tries).
+
+def _run_examples(examples, globs, verbose, name):
+    import sys
+    saveout = sys.stdout
+    try:
+        sys.stdout = fakeout = _SpoofOut()
+        x = _run_examples_inner(saveout.write, fakeout, examples,
+                                globs, verbose, name)
+    finally:
+        sys.stdout = saveout
+    return x
+
+def run_docstring_examples(f, globs, verbose=0, name="NoName"):
+    """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__.
+
+    Use 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:
+        return 0, 0
+
+    e = _extract_examples(doc)
+    if not e:
+        return 0, 0
+    return _run_examples(e, globs, verbose, name)
+
+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")
+    0
+    >>> is_private("____", "_my_func")
+    1
+    >>> is_private("someclass", "__init__")
+    0
+    >>> is_private("sometypo", "__init_")
+    1
+    >>> is_private("x.y.z", "_")
+    1
+    >>> is_private("_x.y.z", "__")
+    0
+    >>> is_private("", "")  # senseless but consistent
+    0
+    """
+
+    return base[:1] == "_" and not base[:2] == "__" == base[-2:]
+
+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)
+        Search for examples in docstrings in all of d.values(); use name
+        for logging.  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 type(mod) is not _ModuleType:
+            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
+
+    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.copy(), self.verbose, name)
+        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.copy(),
+                                      self.verbose, name)
+        if self.verbose:
+            print f, "of", t, "examples failed in", name + ".__doc__"
+        self.__record_outcome(name, f, t)
+        if type(object) is _ClassType:
+            f2, t2 = self.rundict(object.__dict__, name)
+            f = f + f2
+            t = t + t2
+        return f, t
+
+    def rundict(self, d, name):
+        """
+        d. name -> search for docstring examples in all of 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.
+        Return aggregate (#failures, #examples).
+
+        >>> def _f():
+        ...    '''>>> assert 1 == 1
+        ...    '''
+        >>> def g():
+        ...    '''>>> assert 2 != 1
+        ...    '''
+        >>> d = {"_f": _f, "g": g}
+        >>> t = Tester(globs={}, verbose=0)
+        >>> t.rundict(d, "rundict_test")  # _f is skipped
+        (0, 1)
+        >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0)
+        >>> t.rundict(d, "rundict_test_pvt")  # both are searched
+        (0, 2)
+        """
+
+        if not hasattr(d, "items"):
+            raise TypeError("Tester.rundict: d must support .items(); " +
+                            `d`)
+        f = t = 0
+        for thisname, value in d.items():
+            if type(value) in (_FunctionType, _ClassType):
+                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
+            for k, v in d.items():
+                thisname = prefix + k
+                if type(v) is _StringType:
+                    f, t = self.runstring(v, thisname)
+                elif type(v) in (_FunctionType, _ClassType):
+                    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 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 d.has_key(name):
+                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 self.name2ft.has_key(name):
+            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 = _string_rindex(name, ".")
+            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 type(m) is not _ModuleType:
+        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)
+    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()