Edward Loper's cool and massive refactoring of doctest.py, merged from
the tim-doctest-merge-24a2 tag on the the tim-doctest-branch branch.
We did development on the branch in case it wouldn't land in time for
2.4a2, but the branch looked good:  Edward's tests passed there, ditto
Python's tests, and ditto the Zope3 tests.  Together, those hit doctest
heavily.
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index fd3426c..68ac44c 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -1,3 +1,1003 @@
-import doctest
+"""
+Test script for doctest.
+"""
+
 from test import test_support
-test_support.run_doctest(doctest)
+import doctest
+
+######################################################################
+## Sample Objects (used by test cases)
+######################################################################
+
+def sample_func(v):
+    """
+    >>> print sample_func(22)
+    44
+    """
+    return v+v
+
+class SampleClass:
+    """
+    >>> print 1
+    1
+    """
+    def __init__(self, val):
+        """
+        >>> print SampleClass(12).get()
+        12
+        """
+        self.val = val
+
+    def double(self):
+        """
+        >>> print SampleClass(12).double().get()
+        24
+        """
+        return SampleClass(self.val + self.val)
+
+    def get(self):
+        """
+        >>> print SampleClass(-5).get()
+        -5
+        """
+        return self.val
+
+    def a_staticmethod(v):
+        """
+        >>> print SampleClass.a_staticmethod(10)
+        11
+        """
+        return v+1
+    a_staticmethod = staticmethod(a_staticmethod)
+
+    def a_classmethod(cls, v):
+        """
+        >>> print SampleClass.a_classmethod(10)
+        12
+        >>> print SampleClass(0).a_classmethod(10)
+        12
+        """
+        return v+2
+    a_classmethod = classmethod(a_classmethod)
+
+    a_property = property(get, doc="""
+        >>> print SampleClass(22).a_property
+        22
+        """)
+
+    class NestedClass:
+        """
+        >>> x = SampleClass.NestedClass(5)
+        >>> y = x.square()
+        >>> print y.get()
+        25
+        """
+        def __init__(self, val=0):
+            """
+            >>> print SampleClass.NestedClass().get()
+            0
+            """
+            self.val = val
+        def square(self):
+            return SampleClass.NestedClass(self.val*self.val)
+        def get(self):
+            return self.val
+
+class SampleNewStyleClass(object):
+    r"""
+    >>> print '1\n2\n3'
+    1
+    2
+    3
+    """
+    def __init__(self, val):
+        """
+        >>> print SampleNewStyleClass(12).get()
+        12
+        """
+        self.val = val
+
+    def double(self):
+        """
+        >>> print SampleNewStyleClass(12).double().get()
+        24
+        """
+        return SampleNewStyleClass(self.val + self.val)
+
+    def get(self):
+        """
+        >>> print SampleNewStyleClass(-5).get()
+        -5
+        """
+        return self.val
+
+######################################################################
+## Test Cases
+######################################################################
+
+def test_Example(): r"""
+Unit tests for the `Example` class.
+
+Example is a simple container class that holds a source code string,
+an expected output string, and a line number (within the docstring):
+
+    >>> example = doctest.Example('print 1', '1\n', 0)
+    >>> (example.source, example.want, example.lineno)
+    ('print 1', '1\n', 0)
+
+The `source` string should end in a newline iff the source spans more
+than one line:
+
+    >>> # Source spans a single line: no terminating newline.
+    >>> e = doctest.Example('print 1', '1\n', 0)
+    >>> e = doctest.Example('print 1\n', '1\n', 0)
+    Traceback (most recent call last):
+    AssertionError
+
+    >>> # Source spans multiple lines: require terminating newline.
+    >>> e = doctest.Example('print 1;\nprint 2\n', '1\n2\n', 0)
+    >>> e = doctest.Example('print 1;\nprint 2', '1\n2\n', 0)
+    Traceback (most recent call last):
+    AssertionError
+
+The `want` string should be terminated by a newline, unless it's the
+empty string:
+
+    >>> e = doctest.Example('print 1', '1\n', 0)
+    >>> e = doctest.Example('print 1', '1', 0)
+    Traceback (most recent call last):
+    AssertionError
+    >>> e = doctest.Example('print', '', 0)
+"""
+
+def test_DocTest(): r"""
+Unit tests for the `DocTest` class.
+
+DocTest is a collection of examples, extracted from a docstring, along
+with information about where the docstring comes from (a name,
+filename, and line number).  The docstring is parsed by the `DocTest`
+constructor:
+
+    >>> docstring = '''
+    ...     >>> print 12
+    ...     12
+    ...
+    ... Non-example text.
+    ...
+    ...     >>> print 'another\example'
+    ...     another
+    ...     example
+    ... '''
+    >>> globs = {} # globals to run the test in.
+    >>> test = doctest.DocTest(docstring, globs, 'some_test', 'some_file', 20)
+    >>> print test
+    <DocTest some_test from some_file:20 (2 examples)>
+    >>> len(test.examples)
+    2
+    >>> e1, e2 = test.examples
+    >>> (e1.source, e1.want, e1.lineno)
+    ('print 12', '12\n', 1)
+    >>> (e2.source, e2.want, e2.lineno)
+    ("print 'another\\example'", 'another\nexample\n', 6)
+
+Source information (name, filename, and line number) is available as
+attributes on the doctest object:
+
+    >>> (test.name, test.filename, test.lineno)
+    ('some_test', 'some_file', 20)
+
+The line number of an example within its containing file is found by
+adding the line number of the example and the line number of its
+containing test:
+
+    >>> test.lineno + e1.lineno
+    21
+    >>> test.lineno + e2.lineno
+    26
+
+If the docstring contains inconsistant leading whitespace in the
+expected output of an example, then `DocTest` will raise a ValueError:
+
+    >>> docstring = r'''
+    ...       >>> print 'bad\nindentation'
+    ...       bad
+    ...     indentation
+    ...     '''
+    >>> doctest.DocTest(docstring, globs, 'some_test', 'filename', 0)
+    Traceback (most recent call last):
+    ValueError: line 3 of the docstring for some_test has inconsistent leading whitespace: '    indentation'
+
+If the docstring contains inconsistent leading whitespace on
+continuation lines, then `DocTest` will raise a ValueError:
+
+    >>> docstring = r'''
+    ...       >>> print ('bad indentation',
+    ...     ...          2)
+    ...       ('bad', 'indentation')
+    ...     '''
+    >>> doctest.DocTest(docstring, globs, 'some_test', 'filename', 0)
+    Traceback (most recent call last):
+    ValueError: line 2 of the docstring for some_test has inconsistent leading whitespace: '    ...          2)'
+
+If there's no blank space after a PS1 prompt ('>>>'), then `DocTest`
+will raise a ValueError:
+
+    >>> docstring = '>>>print 1\n1'
+    >>> doctest.DocTest(docstring, globs, 'some_test', 'filename', 0)
+    Traceback (most recent call last):
+    ValueError: line 0 of the docstring for some_test lacks blank after >>>: '>>>print 1'
+"""
+
+# [XX] test that it's getting line numbers right.
+def test_DocTestFinder(): r"""
+Unit tests for the `DocTestFinder` class.
+
+DocTestFinder is used to extract DocTests from an object's docstring
+and the docstrings of its contained objects.  It can be used with
+modules, functions, classes, methods, staticmethods, classmethods, and
+properties.
+
+Finding Tests in Functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+For a function whose docstring contains examples, DocTestFinder.find()
+will return a single test (for that function's docstring):
+
+    >>> # Allow ellipsis in the following examples (since the filename
+    >>> # and line number in the traceback can vary):
+    >>> doctest: +ELLIPSIS
+
+    >>> finder = doctest.DocTestFinder()
+    >>> tests = finder.find(sample_func)
+    >>> print tests
+    [<DocTest sample_func from ...:12 (1 example)>]
+    >>> e = tests[0].examples[0]
+    >>> print (e.source, e.want, e.lineno)
+    ('print sample_func(22)', '44\n', 1)
+
+    >>> doctest: -ELLIPSIS # Turn ellipsis back off
+
+If an object has no docstring, then a test is not created for it:
+
+    >>> def no_docstring(v):
+    ...     pass
+    >>> finder.find(no_docstring)
+    []
+
+If the function has a docstring with no examples, then a test with no
+examples is returned.  (This lets `DocTestRunner` collect statistics
+about which functions have no tests -- but is that useful?  And should
+an empty test also be created when there's no docstring?)
+
+    >>> def no_examples(v):
+    ...     ''' no doctest examples '''
+    >>> finder.find(no_examples)
+    [<DocTest no_examples from None:1 (no examples)>]
+
+Finding Tests in Classes
+~~~~~~~~~~~~~~~~~~~~~~~~
+For a class, DocTestFinder will create a test for the class's
+docstring, and will recursively explore its contents, including
+methods, classmethods, staticmethods, properties, and nested classes.
+
+    >>> finder = doctest.DocTestFinder()
+    >>> tests = finder.find(SampleClass)
+    >>> tests.sort()
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  SampleClass
+     3  SampleClass.NestedClass
+     1  SampleClass.NestedClass.__init__
+     1  SampleClass.__init__
+     2  SampleClass.a_classmethod
+     1  SampleClass.a_property
+     1  SampleClass.a_staticmethod
+     1  SampleClass.double
+     1  SampleClass.get
+
+New-style classes are also supported:
+
+    >>> tests = finder.find(SampleNewStyleClass)
+    >>> tests.sort()
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  SampleNewStyleClass
+     1  SampleNewStyleClass.__init__
+     1  SampleNewStyleClass.double
+     1  SampleNewStyleClass.get
+
+Finding Tests in Modules
+~~~~~~~~~~~~~~~~~~~~~~~~
+For a module, DocTestFinder will create a test for the class's
+docstring, and will recursively explore its contents, including
+functions, classes, and the `__test__` dictionary, if it exists:
+
+    >>> # A module
+    >>> import new
+    >>> m = new.module('some_module')
+    >>> def triple(val):
+    ...     '''
+    ...     >>> print tripple(11)
+    ...     33
+    ...     '''
+    ...     return val*3
+    >>> m.__dict__.update({
+    ...     'sample_func': sample_func,
+    ...     'SampleClass': SampleClass,
+    ...     '__doc__': '''
+    ...         Module docstring.
+    ...             >>> print 'module'
+    ...             module
+    ...         ''',
+    ...     '__test__': {
+    ...         'd': '>>> print 6\n6\n>>> print 7\n7\n',
+    ...         'c': triple}})
+
+    >>> finder = doctest.DocTestFinder()
+    >>> # Use module=test.test_doctest, to prevent doctest from
+    >>> # ignoring the objects since they weren't defined in m.
+    >>> import test.test_doctest
+    >>> tests = finder.find(m, module=test.test_doctest)
+    >>> tests.sort()
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  some_module
+     1  some_module.SampleClass
+     3  some_module.SampleClass.NestedClass
+     1  some_module.SampleClass.NestedClass.__init__
+     1  some_module.SampleClass.__init__
+     2  some_module.SampleClass.a_classmethod
+     1  some_module.SampleClass.a_property
+     1  some_module.SampleClass.a_staticmethod
+     1  some_module.SampleClass.double
+     1  some_module.SampleClass.get
+     1  some_module.c
+     2  some_module.d
+     1  some_module.sample_func
+
+Duplicate Removal
+~~~~~~~~~~~~~~~~~
+If a single object is listed twice (under different names), then tests
+will only be generated for it once:
+
+    >>> class TwoNames:
+    ...     '''f() and g() are two names for the same method'''
+    ...
+    ...     def f(self):
+    ...         '''
+    ...         >>> print TwoNames().f()
+    ...         f
+    ...         '''
+    ...         return 'f'
+    ...
+    ...     g = f # define an alias for f.
+
+    >>> finder = doctest.DocTestFinder()
+    >>> tests = finder.find(TwoNames, ignore_imports=False)
+    >>> tests.sort()
+    >>> print len(tests)
+    2
+    >>> print tests[0].name
+    TwoNames
+    >>> print tests[1].name in ('TwoNames.f', 'TwoNames.g')
+    True
+
+Filter Functions
+~~~~~~~~~~~~~~~~
+Two filter functions can be used to restrict which objects get
+examined: a name-based filter and an object-based filter.
+
+    >>> def namefilter(prefix, base):
+    ...     return base.startswith('a_')
+    >>> tests = doctest.DocTestFinder(namefilter=namefilter).find(SampleClass)
+    >>> tests.sort()
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  SampleClass
+     3  SampleClass.NestedClass
+     1  SampleClass.NestedClass.__init__
+     1  SampleClass.__init__
+     1  SampleClass.double
+     1  SampleClass.get
+
+    >>> def objfilter(obj):
+    ...     return isinstance(obj, (staticmethod, classmethod))
+    >>> tests = doctest.DocTestFinder(objfilter=objfilter).find(SampleClass)
+    >>> tests.sort()
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  SampleClass
+     3  SampleClass.NestedClass
+     1  SampleClass.NestedClass.__init__
+     1  SampleClass.__init__
+     1  SampleClass.a_property
+     1  SampleClass.double
+     1  SampleClass.get
+
+If a given object is filtered out, then none of the objects that it
+contains will be added either:
+
+    >>> def namefilter(prefix, base):
+    ...     return base == 'NestedClass'
+    >>> tests = doctest.DocTestFinder(namefilter=namefilter).find(SampleClass)
+    >>> tests.sort()
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  SampleClass
+     1  SampleClass.__init__
+     2  SampleClass.a_classmethod
+     1  SampleClass.a_property
+     1  SampleClass.a_staticmethod
+     1  SampleClass.double
+     1  SampleClass.get
+
+The filter functions apply to contained objects, and *not* to the
+object explicitly passed to DocTestFinder:
+
+    >>> def namefilter(prefix, base):
+    ...     return base == 'SampleClass'
+    >>> tests = doctest.DocTestFinder(namefilter=namefilter).find(SampleClass)
+    >>> len(tests)
+    9
+
+Turning off Recursion
+~~~~~~~~~~~~~~~~~~~~~
+DocTestFinder can be told not to look for tests in contained objects
+using the `recurse` flag:
+
+    >>> tests = doctest.DocTestFinder(recurse=False).find(SampleClass)
+    >>> tests.sort()
+    >>> for t in tests:
+    ...     print '%2s  %s' % (len(t.examples), t.name)
+     1  SampleClass
+"""
+
+class test_DocTestRunner:
+    def basics(): r"""
+Unit tests for the `DocTestRunner` class.
+
+DocTestRunner is used to run DocTest test cases, and to accumulate
+statistics.  Here's a simple DocTest case we can use:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print x
+    ...     12
+    ...     >>> x/2
+    ...     6
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+
+The main DocTestRunner interface is the `run` method, which runs a
+given DocTest case in a given namespace (globs).  It returns a tuple
+`(f,t)`, where `f` is the number of failed tests and `t` is the number
+of tried tests.
+
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 3)
+
+If any example produces incorrect output, then the test runner reports
+the failure and proceeds to the next example:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print x
+    ...     14
+    ...     >>> x/2
+    ...     6
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=True).run(test)
+    Trying: x = 12
+    Expecting: nothing
+    ok
+    Trying: print x
+    Expecting: 14
+    **********************************************************************
+    Failure in example: print x
+    from line #2 of f
+    Expected: 14
+    Got: 12
+    Trying: x/2
+    Expecting: 6
+    ok
+    (1, 3)
+"""
+    def verbose_flag(): r"""
+The `verbose` flag makes the test runner generate more detailed
+output:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print x
+    ...     12
+    ...     >>> x/2
+    ...     6
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+
+    >>> doctest.DocTestRunner(verbose=True).run(test)
+    Trying: x = 12
+    Expecting: nothing
+    ok
+    Trying: print x
+    Expecting: 12
+    ok
+    Trying: x/2
+    Expecting: 6
+    ok
+    (0, 3)
+
+If the `verbose` flag is unspecified, then the output will be verbose
+iff `-v` appears in sys.argv:
+
+    >>> # Save the real sys.argv list.
+    >>> old_argv = sys.argv
+
+    >>> # If -v does not appear in sys.argv, then output isn't verbose.
+    >>> sys.argv = ['test']
+    >>> doctest.DocTestRunner().run(test)
+    (0, 3)
+
+    >>> # If -v does appear in sys.argv, then output is verbose.
+    >>> sys.argv = ['test', '-v']
+    >>> doctest.DocTestRunner().run(test)
+    Trying: x = 12
+    Expecting: nothing
+    ok
+    Trying: print x
+    Expecting: 12
+    ok
+    Trying: x/2
+    Expecting: 6
+    ok
+    (0, 3)
+
+    >>> # Restore sys.argv
+    >>> sys.argv = old_argv
+
+In the remaining examples, the test runner's verbosity will be
+explicitly set, to ensure that the test behavior is consistent.
+    """
+    def exceptions(): r"""
+Tests of `DocTestRunner`'s exception handling.
+
+An expected exception is specified with a traceback message.  The
+lines between the first line and the type/value may be omitted or
+replaced with any other string:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print x/0
+    ...     Traceback (most recent call last):
+    ...     ZeroDivisionError: integer division or modulo by zero
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 2)
+
+An example may generate output before it raises an exception; if it
+does, then the output must match the expected output:
+
+    >>> def f(x):
+    ...     '''
+    ...     >>> x = 12
+    ...     >>> print 'pre-exception output', x/0
+    ...     pre-exception output
+    ...     Traceback (most recent call last):
+    ...     ZeroDivisionError: integer division or modulo by zero
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 2)
+
+Exception messages may contain newlines:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> raise ValueError, 'multi\nline\nmessage'
+    ...     Traceback (most recent call last):
+    ...     ValueError: multi
+    ...     line
+    ...     message
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+If an exception is expected, but an exception with the wrong type or
+message is raised, then it is reported as a failure:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> raise ValueError, 'message'
+    ...     Traceback (most recent call last):
+    ...     ValueError: wrong message
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    **********************************************************************
+    Failure in example: raise ValueError, 'message'
+    from line #1 of f
+    Expected:
+        Traceback (most recent call last):
+        ValueError: wrong message
+    Got:
+        Traceback (most recent call last):
+        ValueError: message
+    (1, 1)
+
+If an exception is raised but not expected, then it is reported as an
+unexpected exception:
+
+    >>> # Allow ellipsis in the following examples (since the filename
+    >>> # and line number in the traceback can vary):
+    >>> doctest: +ELLIPSIS
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> 1/0
+    ...     0
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    **********************************************************************
+    Failure in example: 1/0
+    from line #1 of f
+    Exception raised:
+        Traceback (most recent call last):
+          ...
+        ZeroDivisionError: integer division or modulo by zero
+    (1, 1)
+
+    >>> doctest: -ELLIPSIS # Turn ellipsis back off:
+"""
+    def optionflags(): r"""
+Tests of `DocTestRunner`'s option flag handling.
+
+Several option flags can be used to customize the behavior of the test
+runner.  These are defined as module constants in doctest, and passed
+to the DocTestRunner constructor (multiple constants should be or-ed
+together).
+
+The DONT_ACCEPT_TRUE_FOR_1 flag disables matches between True/False
+and 1/0:
+
+    >>> def f(x):
+    ...     '>>> True\n1\n'
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.DONT_ACCEPT_TRUE_FOR_1
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    **********************************************************************
+    Failure in example: True
+    from line #0 of f
+    Expected: 1
+    Got: True
+    (1, 1)
+
+The DONT_ACCEPT_BLANKLINE flag disables the match between blank lines
+and the '<BLANKLINE>' marker:
+
+    >>> def f(x):
+    ...     '>>> print "a\\n\\nb"\na\n<BLANKLINE>\nb\n'
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    (0, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.DONT_ACCEPT_BLANKLINE
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    **********************************************************************
+    Failure in example: print "a\n\nb"
+    from line #0 of f
+    Expected:
+        a
+        <BLANKLINE>
+        b
+    Got:
+        a
+    <BLANKLINE>
+        b
+    (1, 1)
+
+The NORMALIZE_WHITESPACE flag causes all sequences of whitespace to be
+treated as equal:
+
+    >>> def f(x):
+    ...     '>>> print 1, 2, 3\n  1   2\n 3'
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    **********************************************************************
+    Failure in example: print 1, 2, 3
+    from line #0 of f
+    Expected:
+          1   2
+         3
+    Got: 1 2 3
+    (1, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.NORMALIZE_WHITESPACE
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    (0, 1)
+
+The ELLIPSIS flag causes ellipsis marker ("...") in the expected
+output to match any substring in the actual output:
+
+    >>> def f(x):
+    ...     '>>> print range(15)\n[0, 1, 2, ..., 14]\n'
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    **********************************************************************
+    Failure in example: print range(15)
+    from line #0 of f
+    Expected: [0, 1, 2, ..., 14]
+    Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
+    (1, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.ELLIPSIS
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    (0, 1)
+
+The UNIFIED_DIFF flag causes failures that involve multi-line expected
+and actual outputs to be displayed using a unified diff:
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> print '\n'.join('abcdefg')
+    ...     a
+    ...     B
+    ...     c
+    ...     d
+    ...     f
+    ...     g
+    ...     h
+    ...     '''
+
+    >>> # Without the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    **********************************************************************
+    Failure in example: print '\n'.join('abcdefg')
+    from line #1 of f
+    Expected:
+        a
+        B
+        c
+        d
+        f
+        g
+        h
+    Got:
+        a
+        b
+        c
+        d
+        e
+        f
+        g
+    (1, 1)
+
+    >>> # With the flag:
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.UNIFIED_DIFF
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    **********************************************************************
+    Failure in example: print '\n'.join('abcdefg')
+    from line #1 of f
+    Differences (unified diff):
+        --- Expected
+        +++ Got
+        @@ -1,8 +1,8 @@
+         a
+        -B
+        +b
+         c
+         d
+        +e
+         f
+         g
+        -h
+    <BLANKLINE>
+    (1, 1)
+
+The CONTEXT_DIFF flag causes failures that involve multi-line expected
+and actual outputs to be displayed using a context diff:
+
+    >>> # Reuse f() from the UNIFIED_DIFF example, above.
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.CONTEXT_DIFF
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    **********************************************************************
+    Failure in example: print '\n'.join('abcdefg')
+    from line #1 of f
+    Differences (context diff):
+        *** Expected
+        --- Got
+        ***************
+        *** 1,8 ****
+          a
+        ! B
+          c
+          d
+          f
+          g
+        - h
+    <BLANKLINE>
+        --- 1,8 ----
+          a
+        ! b
+          c
+          d
+        + e
+          f
+          g
+    <BLANKLINE>
+    (1, 1)
+"""
+    def option_directives(): r"""
+Tests of `DocTestRunner`'s option directive mechanism.
+
+Option directives can be used to turn option flags on or off from
+within a DocTest case.  The following example shows how a flag can be
+turned on and off.  Note that comments on the same line as the option
+directive are ignored.
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)       # Should fail: no ellipsis
+    ...     [0, 1, ..., 9]
+    ...
+    ...     >>> doctest: +ELLIPSIS    # turn ellipsis on.
+    ...     >>> print range(10)       # Should succeed
+    ...     [0, 1, ..., 9]
+    ...
+    ...     >>> doctest: -ELLIPSIS    # turn ellipsis back off.
+    ...     >>> print range(10)       # Should fail: no ellipsis
+    ...     [0, 1, ..., 9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    **********************************************************************
+    Failure in example: print range(10)       # Should fail: no ellipsis
+    from line #1 of f
+    Expected: [0, 1, ..., 9]
+    Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    **********************************************************************
+    Failure in example: print range(10)       # Should fail: no ellipsis
+    from line #9 of f
+    Expected: [0, 1, ..., 9]
+    Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    (2, 3)
+
+Multiple flags can be toggled by a single option directive:
+
+    >>> def f(x): r'''
+    ...     >>> print range(10)       # Should fail
+    ...     [0, 1,  ...,   9]
+    ...     >>> doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+    ...     >>> print range(10)       # Should succeed
+    ...     [0, 1,  ...,   9]
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> doctest.DocTestRunner(verbose=False).run(test)
+    **********************************************************************
+    Failure in example: print range(10)       # Should fail
+    from line #1 of f
+    Expected: [0, 1,  ...,   9]
+    Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    (1, 2)
+"""
+
+def test_testsource(): r"""
+Unit tests for `testsource()`.
+
+The testsource() function takes a module and a name, finds the (first)
+test with that name in that module, and converts it to an
+
+    >>> import test.test_doctest
+    >>> name = 'test.test_doctest.sample_func'
+    >>> print doctest.testsource(test.test_doctest, name)
+    print sample_func(22)
+    # Expected:
+    #     44
+
+    >>> name = 'test.test_doctest.SampleNewStyleClass'
+    >>> print doctest.testsource(test.test_doctest, name)
+    print '1\n2\n3'
+    # Expected:
+    #     1
+    #     2
+    #     3
+
+    >>> name = 'test.test_doctest.SampleClass.a_classmethod'
+    >>> print doctest.testsource(test.test_doctest, name)
+    print SampleClass.a_classmethod(10)
+    # Expected:
+    #     12
+    print SampleClass(0).a_classmethod(10)
+    # Expected:
+    #     12
+"""
+
+def test_debug(): r"""
+
+Create a docstring that we want to debug:
+
+    >>> s = '''
+    ...     >>> x = 12
+    ...     >>> print x
+    ...     12
+    ...     '''
+
+Create some fake stdin input, to feed to the debugger:
+
+    >>> import tempfile
+    >>> fake_stdin = tempfile.TemporaryFile(mode='w+')
+    >>> fake_stdin.write('\n'.join(['next', 'print x', 'continue', '']))
+    >>> fake_stdin.seek(0)
+    >>> real_stdin = sys.stdin
+    >>> sys.stdin = fake_stdin
+
+Run the debugger on the docstring, and then restore sys.stdin.
+
+    >>> doctest: +NORMALIZE_WHITESPACE
+    >>> try:
+    ...     doctest.debug_src(s)
+    ... finally:
+    ...      sys.stdin = real_stdin
+    ...      fake_stdin.close()
+    > <string>(1)?()
+    (Pdb) 12
+    --Return--
+    > <string>(1)?()->None
+    (Pdb) 12
+    (Pdb)
+
+"""
+
+######################################################################
+## Main
+######################################################################
+
+def test_main():
+    # Check the doctest cases in doctest itself:
+    test_support.run_doctest(doctest, verbosity=True)
+    # Check the doctest cases defined here:
+    from test import test_doctest
+    test_support.run_doctest(test_doctest, verbosity=True)
+
+import trace, sys, re, StringIO
+def test_coverage(coverdir):
+    tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,],
+                         trace=0, count=1)
+    tracer.run('reload(doctest); test_main()')
+    r = tracer.results()
+    print 'Writing coverage results...'
+    r.write_results(show_missing=True, summary=True,
+                    coverdir=coverdir)
+
+if __name__ == '__main__':
+    if '-c' in sys.argv:
+        test_coverage('/tmp/doctest.cover')
+    else:
+        test_main()