1823b8294SYaroslav Brustinov# Module doctest.
2823b8294SYaroslav Brustinov# Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org).
3823b8294SYaroslav Brustinov# Major enhancements and refactoring by:
4823b8294SYaroslav Brustinov#     Jim Fulton
5823b8294SYaroslav Brustinov#     Edward Loper
6823b8294SYaroslav Brustinov
7823b8294SYaroslav Brustinov# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
8823b8294SYaroslav Brustinov#
9823b8294SYaroslav Brustinov# Modified for inclusion in nose to provide support for DocFileTest in
10823b8294SYaroslav Brustinov# python 2.3:
11823b8294SYaroslav Brustinov#
12823b8294SYaroslav Brustinov# - all doctests removed from module (they fail under 2.3 and 2.5)
13823b8294SYaroslav Brustinov# - now handles the $py.class extension when ran under Jython
14823b8294SYaroslav Brustinov
15823b8294SYaroslav Brustinovr"""Module doctest -- a framework for running examples in docstrings.
16823b8294SYaroslav Brustinov
17823b8294SYaroslav BrustinovIn simplest use, end each module M to be tested with:
18823b8294SYaroslav Brustinov
19823b8294SYaroslav Brustinovdef _test():
20823b8294SYaroslav Brustinov    import doctest
21823b8294SYaroslav Brustinov    doctest.testmod()
22823b8294SYaroslav Brustinov
23823b8294SYaroslav Brustinovif __name__ == "__main__":
24823b8294SYaroslav Brustinov    _test()
25823b8294SYaroslav Brustinov
26823b8294SYaroslav BrustinovThen running the module as a script will cause the examples in the
27823b8294SYaroslav Brustinovdocstrings to get executed and verified:
28823b8294SYaroslav Brustinov
29823b8294SYaroslav Brustinovpython M.py
30823b8294SYaroslav Brustinov
31823b8294SYaroslav BrustinovThis won't display anything unless an example fails, in which case the
32823b8294SYaroslav Brustinovfailing example(s) and the cause(s) of the failure(s) are printed to stdout
33823b8294SYaroslav Brustinov(why not stderr? because stderr is a lame hack <0.2 wink>), and the final
34823b8294SYaroslav Brustinovline of output is "Test failed.".
35823b8294SYaroslav Brustinov
36823b8294SYaroslav BrustinovRun it with the -v switch instead:
37823b8294SYaroslav Brustinov
38823b8294SYaroslav Brustinovpython M.py -v
39823b8294SYaroslav Brustinov
40823b8294SYaroslav Brustinovand a detailed report of all examples tried is printed to stdout, along
41823b8294SYaroslav Brustinovwith assorted summaries at the end.
42823b8294SYaroslav Brustinov
43823b8294SYaroslav BrustinovYou can force verbose mode by passing "verbose=True" to testmod, or prohibit
44823b8294SYaroslav Brustinovit by passing "verbose=False".  In either of those cases, sys.argv is not
45823b8294SYaroslav Brustinovexamined by testmod.
46823b8294SYaroslav Brustinov
47823b8294SYaroslav BrustinovThere are a variety of other ways to run doctests, including integration
48823b8294SYaroslav Brustinovwith the unittest framework, and support for running non-Python text
49823b8294SYaroslav Brustinovfiles containing doctests.  There are also many ways to override parts
50823b8294SYaroslav Brustinovof doctest's default behaviors.  See the Library Reference Manual for
51823b8294SYaroslav Brustinovdetails.
52823b8294SYaroslav Brustinov"""
53823b8294SYaroslav Brustinov
54823b8294SYaroslav Brustinov__docformat__ = 'reStructuredText en'
55823b8294SYaroslav Brustinov
56823b8294SYaroslav Brustinov__all__ = [
57823b8294SYaroslav Brustinov    # 0, Option Flags
58823b8294SYaroslav Brustinov    'register_optionflag',
59823b8294SYaroslav Brustinov    'DONT_ACCEPT_TRUE_FOR_1',
60823b8294SYaroslav Brustinov    'DONT_ACCEPT_BLANKLINE',
61823b8294SYaroslav Brustinov    'NORMALIZE_WHITESPACE',
62823b8294SYaroslav Brustinov    'ELLIPSIS',
63823b8294SYaroslav Brustinov    'IGNORE_EXCEPTION_DETAIL',
64823b8294SYaroslav Brustinov    'COMPARISON_FLAGS',
65823b8294SYaroslav Brustinov    'REPORT_UDIFF',
66823b8294SYaroslav Brustinov    'REPORT_CDIFF',
67823b8294SYaroslav Brustinov    'REPORT_NDIFF',
68823b8294SYaroslav Brustinov    'REPORT_ONLY_FIRST_FAILURE',
69823b8294SYaroslav Brustinov    'REPORTING_FLAGS',
70823b8294SYaroslav Brustinov    # 1. Utility Functions
71823b8294SYaroslav Brustinov    'is_private',
72823b8294SYaroslav Brustinov    # 2. Example & DocTest
73823b8294SYaroslav Brustinov    'Example',
74823b8294SYaroslav Brustinov    'DocTest',
75823b8294SYaroslav Brustinov    # 3. Doctest Parser
76823b8294SYaroslav Brustinov    'DocTestParser',
77823b8294SYaroslav Brustinov    # 4. Doctest Finder
78823b8294SYaroslav Brustinov    'DocTestFinder',
79823b8294SYaroslav Brustinov    # 5. Doctest Runner
80823b8294SYaroslav Brustinov    'DocTestRunner',
81823b8294SYaroslav Brustinov    'OutputChecker',
82823b8294SYaroslav Brustinov    'DocTestFailure',
83823b8294SYaroslav Brustinov    'UnexpectedException',
84823b8294SYaroslav Brustinov    'DebugRunner',
85823b8294SYaroslav Brustinov    # 6. Test Functions
86823b8294SYaroslav Brustinov    'testmod',
87823b8294SYaroslav Brustinov    'testfile',
88823b8294SYaroslav Brustinov    'run_docstring_examples',
89823b8294SYaroslav Brustinov    # 7. Tester
90823b8294SYaroslav Brustinov    'Tester',
91823b8294SYaroslav Brustinov    # 8. Unittest Support
92823b8294SYaroslav Brustinov    'DocTestSuite',
93823b8294SYaroslav Brustinov    'DocFileSuite',
94823b8294SYaroslav Brustinov    'set_unittest_reportflags',
95823b8294SYaroslav Brustinov    # 9. Debugging Support
96823b8294SYaroslav Brustinov    'script_from_examples',
97823b8294SYaroslav Brustinov    'testsource',
98823b8294SYaroslav Brustinov    'debug_src',
99823b8294SYaroslav Brustinov    'debug',
100823b8294SYaroslav Brustinov]
101823b8294SYaroslav Brustinov
102823b8294SYaroslav Brustinovimport __future__
103823b8294SYaroslav Brustinov
104823b8294SYaroslav Brustinovimport sys, traceback, inspect, linecache, os, re
105823b8294SYaroslav Brustinovimport unittest, difflib, pdb, tempfile
106823b8294SYaroslav Brustinovimport warnings
107823b8294SYaroslav Brustinovfrom StringIO import StringIO
108823b8294SYaroslav Brustinov
109823b8294SYaroslav Brustinov# Don't whine about the deprecated is_private function in this
110823b8294SYaroslav Brustinov# module's tests.
111823b8294SYaroslav Brustinovwarnings.filterwarnings("ignore", "is_private", DeprecationWarning,
112823b8294SYaroslav Brustinov                        __name__, 0)
113823b8294SYaroslav Brustinov
114823b8294SYaroslav Brustinov# There are 4 basic classes:
115823b8294SYaroslav Brustinov#  - Example: a <source, want> pair, plus an intra-docstring line number.
116823b8294SYaroslav Brustinov#  - DocTest: a collection of examples, parsed from a docstring, plus
117823b8294SYaroslav Brustinov#    info about where the docstring came from (name, filename, lineno).
118823b8294SYaroslav Brustinov#  - DocTestFinder: extracts DocTests from a given object's docstring and
119823b8294SYaroslav Brustinov#    its contained objects' docstrings.
120823b8294SYaroslav Brustinov#  - DocTestRunner: runs DocTest cases, and accumulates statistics.
121823b8294SYaroslav Brustinov#
122823b8294SYaroslav Brustinov# So the basic picture is:
123823b8294SYaroslav Brustinov#
124823b8294SYaroslav Brustinov#                             list of:
125823b8294SYaroslav Brustinov# +------+                   +---------+                   +-------+
126823b8294SYaroslav Brustinov# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results|
127823b8294SYaroslav Brustinov# +------+                   +---------+                   +-------+
128823b8294SYaroslav Brustinov#                            | Example |
129823b8294SYaroslav Brustinov#                            |   ...   |
130823b8294SYaroslav Brustinov#                            | Example |
131823b8294SYaroslav Brustinov#                            +---------+
132823b8294SYaroslav Brustinov
133823b8294SYaroslav Brustinov# Option constants.
134823b8294SYaroslav Brustinov
135823b8294SYaroslav BrustinovOPTIONFLAGS_BY_NAME = {}
136823b8294SYaroslav Brustinovdef register_optionflag(name):
137823b8294SYaroslav Brustinov    # Create a new flag unless `name` is already known.
138823b8294SYaroslav Brustinov    return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME))
139823b8294SYaroslav Brustinov
140823b8294SYaroslav BrustinovDONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1')
141823b8294SYaroslav BrustinovDONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE')
142823b8294SYaroslav BrustinovNORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE')
143823b8294SYaroslav BrustinovELLIPSIS = register_optionflag('ELLIPSIS')
144823b8294SYaroslav BrustinovIGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL')
145823b8294SYaroslav Brustinov
146823b8294SYaroslav BrustinovCOMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 |
147823b8294SYaroslav Brustinov                    DONT_ACCEPT_BLANKLINE |
148823b8294SYaroslav Brustinov                    NORMALIZE_WHITESPACE |
149823b8294SYaroslav Brustinov                    ELLIPSIS |
150823b8294SYaroslav Brustinov                    IGNORE_EXCEPTION_DETAIL)
151823b8294SYaroslav Brustinov
152823b8294SYaroslav BrustinovREPORT_UDIFF = register_optionflag('REPORT_UDIFF')
153823b8294SYaroslav BrustinovREPORT_CDIFF = register_optionflag('REPORT_CDIFF')
154823b8294SYaroslav BrustinovREPORT_NDIFF = register_optionflag('REPORT_NDIFF')
155823b8294SYaroslav BrustinovREPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE')
156823b8294SYaroslav Brustinov
157823b8294SYaroslav BrustinovREPORTING_FLAGS = (REPORT_UDIFF |
158823b8294SYaroslav Brustinov                   REPORT_CDIFF |
159823b8294SYaroslav Brustinov                   REPORT_NDIFF |
160823b8294SYaroslav Brustinov                   REPORT_ONLY_FIRST_FAILURE)
161823b8294SYaroslav Brustinov
162823b8294SYaroslav Brustinov# Special string markers for use in `want` strings:
163823b8294SYaroslav BrustinovBLANKLINE_MARKER = '<BLANKLINE>'
164823b8294SYaroslav BrustinovELLIPSIS_MARKER = '...'
165823b8294SYaroslav Brustinov
166823b8294SYaroslav Brustinov######################################################################
167823b8294SYaroslav Brustinov## Table of Contents
168823b8294SYaroslav Brustinov######################################################################
169823b8294SYaroslav Brustinov#  1. Utility Functions
170823b8294SYaroslav Brustinov#  2. Example & DocTest -- store test cases
171823b8294SYaroslav Brustinov#  3. DocTest Parser -- extracts examples from strings
172823b8294SYaroslav Brustinov#  4. DocTest Finder -- extracts test cases from objects
173823b8294SYaroslav Brustinov#  5. DocTest Runner -- runs test cases
174823b8294SYaroslav Brustinov#  6. Test Functions -- convenient wrappers for testing
175823b8294SYaroslav Brustinov#  7. Tester Class -- for backwards compatibility
176823b8294SYaroslav Brustinov#  8. Unittest Support
177823b8294SYaroslav Brustinov#  9. Debugging Support
178823b8294SYaroslav Brustinov# 10. Example Usage
179823b8294SYaroslav Brustinov
180823b8294SYaroslav Brustinov######################################################################
181823b8294SYaroslav Brustinov## 1. Utility Functions
182823b8294SYaroslav Brustinov######################################################################
183823b8294SYaroslav Brustinov
184823b8294SYaroslav Brustinovdef is_private(prefix, base):
185823b8294SYaroslav Brustinov    """prefix, base -> true iff name prefix + "." + base is "private".
186823b8294SYaroslav Brustinov
187823b8294SYaroslav Brustinov    Prefix may be an empty string, and base does not contain a period.
188823b8294SYaroslav Brustinov    Prefix is ignored (although functions you write conforming to this
189823b8294SYaroslav Brustinov    protocol may make use of it).
190823b8294SYaroslav Brustinov    Return true iff base begins with an (at least one) underscore, but
191823b8294SYaroslav Brustinov    does not both begin and end with (at least) two underscores.
192823b8294SYaroslav Brustinov    """
193823b8294SYaroslav Brustinov    warnings.warn("is_private is deprecated; it wasn't useful; "
194823b8294SYaroslav Brustinov                  "examine DocTestFinder.find() lists instead",
195823b8294SYaroslav Brustinov                  DeprecationWarning, stacklevel=2)
196823b8294SYaroslav Brustinov    return base[:1] == "_" and not base[:2] == "__" == base[-2:]
197823b8294SYaroslav Brustinov
198823b8294SYaroslav Brustinovdef _extract_future_flags(globs):
199823b8294SYaroslav Brustinov    """
200823b8294SYaroslav Brustinov    Return the compiler-flags associated with the future features that
201823b8294SYaroslav Brustinov    have been imported into the given namespace (globs).
202823b8294SYaroslav Brustinov    """
203823b8294SYaroslav Brustinov    flags = 0
204823b8294SYaroslav Brustinov    for fname in __future__.all_feature_names:
205823b8294SYaroslav Brustinov        feature = globs.get(fname, None)
206823b8294SYaroslav Brustinov        if feature is getattr(__future__, fname):
207823b8294SYaroslav Brustinov            flags |= feature.compiler_flag
208823b8294SYaroslav Brustinov    return flags
209823b8294SYaroslav Brustinov
210823b8294SYaroslav Brustinovdef _normalize_module(module, depth=2):
211823b8294SYaroslav Brustinov    """
212823b8294SYaroslav Brustinov    Return the module specified by `module`.  In particular:
213823b8294SYaroslav Brustinov      - If `module` is a module, then return module.
214823b8294SYaroslav Brustinov      - If `module` is a string, then import and return the
215823b8294SYaroslav Brustinov        module with that name.
216823b8294SYaroslav Brustinov      - If `module` is None, then return the calling module.
217823b8294SYaroslav Brustinov        The calling module is assumed to be the module of
218823b8294SYaroslav Brustinov        the stack frame at the given depth in the call stack.
219823b8294SYaroslav Brustinov    """
220823b8294SYaroslav Brustinov    if inspect.ismodule(module):
221823b8294SYaroslav Brustinov        return module
222823b8294SYaroslav Brustinov    elif isinstance(module, (str, unicode)):
223823b8294SYaroslav Brustinov        return __import__(module, globals(), locals(), ["*"])
224823b8294SYaroslav Brustinov    elif module is None:
225823b8294SYaroslav Brustinov        return sys.modules[sys._getframe(depth).f_globals['__name__']]
226823b8294SYaroslav Brustinov    else:
227823b8294SYaroslav Brustinov        raise TypeError("Expected a module, string, or None")
228823b8294SYaroslav Brustinov
229823b8294SYaroslav Brustinovdef _indent(s, indent=4):
230823b8294SYaroslav Brustinov    """
231823b8294SYaroslav Brustinov    Add the given number of space characters to the beginning every
232823b8294SYaroslav Brustinov    non-blank line in `s`, and return the result.
233823b8294SYaroslav Brustinov    """
234823b8294SYaroslav Brustinov    # This regexp matches the start of non-blank lines:
235823b8294SYaroslav Brustinov    return re.sub('(?m)^(?!$)', indent*' ', s)
236823b8294SYaroslav Brustinov
237823b8294SYaroslav Brustinovdef _exception_traceback(exc_info):
238823b8294SYaroslav Brustinov    """
239823b8294SYaroslav Brustinov    Return a string containing a traceback message for the given
240823b8294SYaroslav Brustinov    exc_info tuple (as returned by sys.exc_info()).
241823b8294SYaroslav Brustinov    """
242823b8294SYaroslav Brustinov    # Get a traceback message.
243823b8294SYaroslav Brustinov    excout = StringIO()
244823b8294SYaroslav Brustinov    exc_type, exc_val, exc_tb = exc_info
245823b8294SYaroslav Brustinov    traceback.print_exception(exc_type, exc_val, exc_tb, file=excout)
246823b8294SYaroslav Brustinov    return excout.getvalue()
247823b8294SYaroslav Brustinov
248823b8294SYaroslav Brustinov# Override some StringIO methods.
249823b8294SYaroslav Brustinovclass _SpoofOut(StringIO):
250823b8294SYaroslav Brustinov    def getvalue(self):
251823b8294SYaroslav Brustinov        result = StringIO.getvalue(self)
252823b8294SYaroslav Brustinov        # If anything at all was written, make sure there's a trailing
253823b8294SYaroslav Brustinov        # newline.  There's no way for the expected output to indicate
254823b8294SYaroslav Brustinov        # that a trailing newline is missing.
255823b8294SYaroslav Brustinov        if result and not result.endswith("\n"):
256823b8294SYaroslav Brustinov            result += "\n"
257823b8294SYaroslav Brustinov        # Prevent softspace from screwing up the next test case, in
258823b8294SYaroslav Brustinov        # case they used print with a trailing comma in an example.
259823b8294SYaroslav Brustinov        if hasattr(self, "softspace"):
260823b8294SYaroslav Brustinov            del self.softspace
261823b8294SYaroslav Brustinov        return result
262823b8294SYaroslav Brustinov
263823b8294SYaroslav Brustinov    def truncate(self,   size=None):
264823b8294SYaroslav Brustinov        StringIO.truncate(self, size)
265823b8294SYaroslav Brustinov        if hasattr(self, "softspace"):
266823b8294SYaroslav Brustinov            del self.softspace
267823b8294SYaroslav Brustinov
268823b8294SYaroslav Brustinov# Worst-case linear-time ellipsis matching.
269823b8294SYaroslav Brustinovdef _ellipsis_match(want, got):
270823b8294SYaroslav Brustinov    if ELLIPSIS_MARKER not in want:
271823b8294SYaroslav Brustinov        return want == got
272823b8294SYaroslav Brustinov
273823b8294SYaroslav Brustinov    # Find "the real" strings.
274823b8294SYaroslav Brustinov    ws = want.split(ELLIPSIS_MARKER)
275823b8294SYaroslav Brustinov    assert len(ws) >= 2
276823b8294SYaroslav Brustinov
277823b8294SYaroslav Brustinov    # Deal with exact matches possibly needed at one or both ends.
278823b8294SYaroslav Brustinov    startpos, endpos = 0, len(got)
279823b8294SYaroslav Brustinov    w = ws[0]
280823b8294SYaroslav Brustinov    if w:   # starts with exact match
281823b8294SYaroslav Brustinov        if got.startswith(w):
282823b8294SYaroslav Brustinov            startpos = len(w)
283823b8294SYaroslav Brustinov            del ws[0]
284823b8294SYaroslav Brustinov        else:
285823b8294SYaroslav Brustinov            return False
286823b8294SYaroslav Brustinov    w = ws[-1]
287823b8294SYaroslav Brustinov    if w:   # ends with exact match
288823b8294SYaroslav Brustinov        if got.endswith(w):
289823b8294SYaroslav Brustinov            endpos -= len(w)
290823b8294SYaroslav Brustinov            del ws[-1]
291823b8294SYaroslav Brustinov        else:
292823b8294SYaroslav Brustinov            return False
293823b8294SYaroslav Brustinov
294823b8294SYaroslav Brustinov    if startpos > endpos:
295823b8294SYaroslav Brustinov        # Exact end matches required more characters than we have, as in
296823b8294SYaroslav Brustinov        # _ellipsis_match('aa...aa', 'aaa')
297823b8294SYaroslav Brustinov        return False
298823b8294SYaroslav Brustinov
299823b8294SYaroslav Brustinov    # For the rest, we only need to find the leftmost non-overlapping
300823b8294SYaroslav Brustinov    # match for each piece.  If there's no overall match that way alone,
301823b8294SYaroslav Brustinov    # there's no overall match period.
302823b8294SYaroslav Brustinov    for w in ws:
303823b8294SYaroslav Brustinov        # w may be '' at times, if there are consecutive ellipses, or
304823b8294SYaroslav Brustinov        # due to an ellipsis at the start or end of `want`.  That's OK.
305823b8294SYaroslav Brustinov        # Search for an empty string succeeds, and doesn't change startpos.
306823b8294SYaroslav Brustinov        startpos = got.find(w, startpos, endpos)
307823b8294SYaroslav Brustinov        if startpos < 0:
308823b8294SYaroslav Brustinov            return False
309823b8294SYaroslav Brustinov        startpos += len(w)
310823b8294SYaroslav Brustinov
311823b8294SYaroslav Brustinov    return True
312823b8294SYaroslav Brustinov
313823b8294SYaroslav Brustinovdef _comment_line(line):
314823b8294SYaroslav Brustinov    "Return a commented form of the given line"
315823b8294SYaroslav Brustinov    line = line.rstrip()
316823b8294SYaroslav Brustinov    if line:
317823b8294SYaroslav Brustinov        return '# '+line
318823b8294SYaroslav Brustinov    else:
319823b8294SYaroslav Brustinov        return '#'
320823b8294SYaroslav Brustinov
321823b8294SYaroslav Brustinovclass _OutputRedirectingPdb(pdb.Pdb):
322823b8294SYaroslav Brustinov    """
323823b8294SYaroslav Brustinov    A specialized version of the python debugger that redirects stdout
324823b8294SYaroslav Brustinov    to a given stream when interacting with the user.  Stdout is *not*
325823b8294SYaroslav Brustinov    redirected when traced code is executed.
326823b8294SYaroslav Brustinov    """
327823b8294SYaroslav Brustinov    def __init__(self, out):
328823b8294SYaroslav Brustinov        self.__out = out
329823b8294SYaroslav Brustinov        pdb.Pdb.__init__(self)
330823b8294SYaroslav Brustinov
331823b8294SYaroslav Brustinov    def trace_dispatch(self, *args):
332823b8294SYaroslav Brustinov        # Redirect stdout to the given stream.
333823b8294SYaroslav Brustinov        save_stdout = sys.stdout
334823b8294SYaroslav Brustinov        sys.stdout = self.__out
335823b8294SYaroslav Brustinov        # Call Pdb's trace dispatch method.
336823b8294SYaroslav Brustinov        try:
337823b8294SYaroslav Brustinov            return pdb.Pdb.trace_dispatch(self, *args)
338823b8294SYaroslav Brustinov        finally:
339823b8294SYaroslav Brustinov            sys.stdout = save_stdout
340823b8294SYaroslav Brustinov
341823b8294SYaroslav Brustinov# [XX] Normalize with respect to os.path.pardir?
342823b8294SYaroslav Brustinovdef _module_relative_path(module, path):
343823b8294SYaroslav Brustinov    if not inspect.ismodule(module):
344823b8294SYaroslav Brustinov        raise TypeError, 'Expected a module: %r' % module
345823b8294SYaroslav Brustinov    if path.startswith('/'):
346823b8294SYaroslav Brustinov        raise ValueError, 'Module-relative files may not have absolute paths'
347823b8294SYaroslav Brustinov
348823b8294SYaroslav Brustinov    # Find the base directory for the path.
349823b8294SYaroslav Brustinov    if hasattr(module, '__file__'):
350823b8294SYaroslav Brustinov        # A normal module/package
351823b8294SYaroslav Brustinov        basedir = os.path.split(module.__file__)[0]
352823b8294SYaroslav Brustinov    elif module.__name__ == '__main__':
353823b8294SYaroslav Brustinov        # An interactive session.
354823b8294SYaroslav Brustinov        if len(sys.argv)>0 and sys.argv[0] != '':
355823b8294SYaroslav Brustinov            basedir = os.path.split(sys.argv[0])[0]
356823b8294SYaroslav Brustinov        else:
357823b8294SYaroslav Brustinov            basedir = os.curdir
358823b8294SYaroslav Brustinov    else:
359823b8294SYaroslav Brustinov        # A module w/o __file__ (this includes builtins)
360823b8294SYaroslav Brustinov        raise ValueError("Can't resolve paths relative to the module " +
361823b8294SYaroslav Brustinov                         module + " (it has no __file__)")
362823b8294SYaroslav Brustinov
363823b8294SYaroslav Brustinov    # Combine the base directory and the path.
364823b8294SYaroslav Brustinov    return os.path.join(basedir, *(path.split('/')))
365823b8294SYaroslav Brustinov
366823b8294SYaroslav Brustinov######################################################################
367823b8294SYaroslav Brustinov## 2. Example & DocTest
368823b8294SYaroslav Brustinov######################################################################
369823b8294SYaroslav Brustinov## - An "example" is a <source, want> pair, where "source" is a
370823b8294SYaroslav Brustinov##   fragment of source code, and "want" is the expected output for
371823b8294SYaroslav Brustinov##   "source."  The Example class also includes information about
372823b8294SYaroslav Brustinov##   where the example was extracted from.
373823b8294SYaroslav Brustinov##
374823b8294SYaroslav Brustinov## - A "doctest" is a collection of examples, typically extracted from
375823b8294SYaroslav Brustinov##   a string (such as an object's docstring).  The DocTest class also
376823b8294SYaroslav Brustinov##   includes information about where the string was extracted from.
377823b8294SYaroslav Brustinov
378823b8294SYaroslav Brustinovclass Example:
379823b8294SYaroslav Brustinov    """
380823b8294SYaroslav Brustinov    A single doctest example, consisting of source code and expected
381823b8294SYaroslav Brustinov    output.  `Example` defines the following attributes:
382823b8294SYaroslav Brustinov
383823b8294SYaroslav Brustinov      - source: A single Python statement, always ending with a newline.
384823b8294SYaroslav Brustinov        The constructor adds a newline if needed.
385823b8294SYaroslav Brustinov
386823b8294SYaroslav Brustinov      - want: The expected output from running the source code (either
387823b8294SYaroslav Brustinov        from stdout, or a traceback in case of exception).  `want` ends
388823b8294SYaroslav Brustinov        with a newline unless it's empty, in which case it's an empty
389823b8294SYaroslav Brustinov        string.  The constructor adds a newline if needed.
390823b8294SYaroslav Brustinov
391823b8294SYaroslav Brustinov      - exc_msg: The exception message generated by the example, if
392823b8294SYaroslav Brustinov        the example is expected to generate an exception; or `None` if
393823b8294SYaroslav Brustinov        it is not expected to generate an exception.  This exception
394823b8294SYaroslav Brustinov        message is compared against the return value of
395823b8294SYaroslav Brustinov        `traceback.format_exception_only()`.  `exc_msg` ends with a
396823b8294SYaroslav Brustinov        newline unless it's `None`.  The constructor adds a newline
397823b8294SYaroslav Brustinov        if needed.
398823b8294SYaroslav Brustinov
399823b8294SYaroslav Brustinov      - lineno: The line number within the DocTest string containing
400823b8294SYaroslav Brustinov        this Example where the Example begins.  This line number is
401823b8294SYaroslav Brustinov        zero-based, with respect to the beginning of the DocTest.
402823b8294SYaroslav Brustinov
403823b8294SYaroslav Brustinov      - indent: The example's indentation in the DocTest string.
404823b8294SYaroslav Brustinov        I.e., the number of space characters that preceed the
405823b8294SYaroslav Brustinov        example's first prompt.
406823b8294SYaroslav Brustinov
407823b8294SYaroslav Brustinov      - options: A dictionary mapping from option flags to True or
408823b8294SYaroslav Brustinov        False, which is used to override default options for this
409823b8294SYaroslav Brustinov        example.  Any option flags not contained in this dictionary
410823b8294SYaroslav Brustinov        are left at their default value (as specified by the
411823b8294SYaroslav Brustinov        DocTestRunner's optionflags).  By default, no options are set.
412823b8294SYaroslav Brustinov    """
413823b8294SYaroslav Brustinov    def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
414823b8294SYaroslav Brustinov                 options=None):
415823b8294SYaroslav Brustinov        # Normalize inputs.
416823b8294SYaroslav Brustinov        if not source.endswith('\n'):
417823b8294SYaroslav Brustinov            source += '\n'
418823b8294SYaroslav Brustinov        if want and not want.endswith('\n'):
419823b8294SYaroslav Brustinov            want += '\n'
420823b8294SYaroslav Brustinov        if exc_msg is not None and not exc_msg.endswith('\n'):
421823b8294SYaroslav Brustinov            exc_msg += '\n'
422823b8294SYaroslav Brustinov        # Store properties.
423823b8294SYaroslav Brustinov        self.source = source
424823b8294SYaroslav Brustinov        self.want = want
425823b8294SYaroslav Brustinov        self.lineno = lineno
426823b8294SYaroslav Brustinov        self.indent = indent
427823b8294SYaroslav Brustinov        if options is None: options = {}
428823b8294SYaroslav Brustinov        self.options = options
429823b8294SYaroslav Brustinov        self.exc_msg = exc_msg
430823b8294SYaroslav Brustinov
431823b8294SYaroslav Brustinovclass DocTest:
432823b8294SYaroslav Brustinov    """
433823b8294SYaroslav Brustinov    A collection of doctest examples that should be run in a single
434823b8294SYaroslav Brustinov    namespace.  Each `DocTest` defines the following attributes:
435823b8294SYaroslav Brustinov
436823b8294SYaroslav Brustinov      - examples: the list of examples.
437823b8294SYaroslav Brustinov
438823b8294SYaroslav Brustinov      - globs: The namespace (aka globals) that the examples should
439823b8294SYaroslav Brustinov        be run in.
440823b8294SYaroslav Brustinov
441823b8294SYaroslav Brustinov      - name: A name identifying the DocTest (typically, the name of
442823b8294SYaroslav Brustinov        the object whose docstring this DocTest was extracted from).
443823b8294SYaroslav Brustinov
444823b8294SYaroslav Brustinov      - filename: The name of the file that this DocTest was extracted
445823b8294SYaroslav Brustinov        from, or `None` if the filename is unknown.
446823b8294SYaroslav Brustinov
447823b8294SYaroslav Brustinov      - lineno: The line number within filename where this DocTest
448823b8294SYaroslav Brustinov        begins, or `None` if the line number is unavailable.  This
449823b8294SYaroslav Brustinov        line number is zero-based, with respect to the beginning of
450823b8294SYaroslav Brustinov        the file.
451823b8294SYaroslav Brustinov
452823b8294SYaroslav Brustinov      - docstring: The string that the examples were extracted from,
453823b8294SYaroslav Brustinov        or `None` if the string is unavailable.
454823b8294SYaroslav Brustinov    """
455823b8294SYaroslav Brustinov    def __init__(self, examples, globs, name, filename, lineno, docstring):
456823b8294SYaroslav Brustinov        """
457823b8294SYaroslav Brustinov        Create a new DocTest containing the given examples.  The
458823b8294SYaroslav Brustinov        DocTest's globals are initialized with a copy of `globs`.
459823b8294SYaroslav Brustinov        """
460823b8294SYaroslav Brustinov        assert not isinstance(examples, basestring), \
461823b8294SYaroslav Brustinov               "DocTest no longer accepts str; use DocTestParser instead"
462823b8294SYaroslav Brustinov        self.examples = examples
463823b8294SYaroslav Brustinov        self.docstring = docstring
464823b8294SYaroslav Brustinov        self.globs = globs.copy()
465823b8294SYaroslav Brustinov        self.name = name
466823b8294SYaroslav Brustinov        self.filename = filename
467823b8294SYaroslav Brustinov        self.lineno = lineno
468823b8294SYaroslav Brustinov
469823b8294SYaroslav Brustinov    def __repr__(self):
470823b8294SYaroslav Brustinov        if len(self.examples) == 0:
471823b8294SYaroslav Brustinov            examples = 'no examples'
472823b8294SYaroslav Brustinov        elif len(self.examples) == 1:
473823b8294SYaroslav Brustinov            examples = '1 example'
474823b8294SYaroslav Brustinov        else:
475823b8294SYaroslav Brustinov            examples = '%d examples' % len(self.examples)
476823b8294SYaroslav Brustinov        return ('<DocTest %s from %s:%s (%s)>' %
477823b8294SYaroslav Brustinov                (self.name, self.filename, self.lineno, examples))
478823b8294SYaroslav Brustinov
479823b8294SYaroslav Brustinov
480823b8294SYaroslav Brustinov    # This lets us sort tests by name:
481823b8294SYaroslav Brustinov    def __cmp__(self, other):
482823b8294SYaroslav Brustinov        if not isinstance(other, DocTest):
483823b8294SYaroslav Brustinov            return -1
484823b8294SYaroslav Brustinov        return cmp((self.name, self.filename, self.lineno, id(self)),
485823b8294SYaroslav Brustinov                   (other.name, other.filename, other.lineno, id(other)))
486823b8294SYaroslav Brustinov
487823b8294SYaroslav Brustinov######################################################################
488823b8294SYaroslav Brustinov## 3. DocTestParser
489823b8294SYaroslav Brustinov######################################################################
490823b8294SYaroslav Brustinov
491823b8294SYaroslav Brustinovclass DocTestParser:
492823b8294SYaroslav Brustinov    """
493823b8294SYaroslav Brustinov    A class used to parse strings containing doctest examples.
494823b8294SYaroslav Brustinov    """
495823b8294SYaroslav Brustinov    # This regular expression is used to find doctest examples in a
496823b8294SYaroslav Brustinov    # string.  It defines three groups: `source` is the source code
497823b8294SYaroslav Brustinov    # (including leading indentation and prompts); `indent` is the
498823b8294SYaroslav Brustinov    # indentation of the first (PS1) line of the source code; and
499823b8294SYaroslav Brustinov    # `want` is the expected output (including leading indentation).
500823b8294SYaroslav Brustinov    _EXAMPLE_RE = re.compile(r'''
501823b8294SYaroslav Brustinov        # Source consists of a PS1 line followed by zero or more PS2 lines.
502823b8294SYaroslav Brustinov        (?P<source>
503823b8294SYaroslav Brustinov            (?:^(?P<indent> [ ]*) >>>    .*)    # PS1 line
504823b8294SYaroslav Brustinov            (?:\n           [ ]*  \.\.\. .*)*)  # PS2 lines
505823b8294SYaroslav Brustinov        \n?
506823b8294SYaroslav Brustinov        # Want consists of any non-blank lines that do not start with PS1.
507823b8294SYaroslav Brustinov        (?P<want> (?:(?![ ]*$)    # Not a blank line
508823b8294SYaroslav Brustinov                     (?![ ]*>>>)  # Not a line starting with PS1
509823b8294SYaroslav Brustinov                     .*$\n?       # But any other line
510823b8294SYaroslav Brustinov                  )*)
511823b8294SYaroslav Brustinov        ''', re.MULTILINE | re.VERBOSE)
512823b8294SYaroslav Brustinov
513823b8294SYaroslav Brustinov    # A regular expression for handling `want` strings that contain
514823b8294SYaroslav Brustinov    # expected exceptions.  It divides `want` into three pieces:
515823b8294SYaroslav Brustinov    #    - the traceback header line (`hdr`)
516823b8294SYaroslav Brustinov    #    - the traceback stack (`stack`)
517823b8294SYaroslav Brustinov    #    - the exception message (`msg`), as generated by
518823b8294SYaroslav Brustinov    #      traceback.format_exception_only()
519823b8294SYaroslav Brustinov    # `msg` may have multiple lines.  We assume/require that the
520823b8294SYaroslav Brustinov    # exception message is the first non-indented line starting with a word
521823b8294SYaroslav Brustinov    # character following the traceback header line.
522823b8294SYaroslav Brustinov    _EXCEPTION_RE = re.compile(r"""
523823b8294SYaroslav Brustinov        # Grab the traceback header.  Different versions of Python have
524823b8294SYaroslav Brustinov        # said different things on the first traceback line.
525823b8294SYaroslav Brustinov        ^(?P<hdr> Traceback\ \(
526823b8294SYaroslav Brustinov            (?: most\ recent\ call\ last
527823b8294SYaroslav Brustinov            |   innermost\ last
528823b8294SYaroslav Brustinov            ) \) :
529823b8294SYaroslav Brustinov        )
530823b8294SYaroslav Brustinov        \s* $                # toss trailing whitespace on the header.
531823b8294SYaroslav Brustinov        (?P<stack> .*?)      # don't blink: absorb stuff until...
532823b8294SYaroslav Brustinov        ^ (?P<msg> \w+ .*)   #     a line *starts* with alphanum.
533823b8294SYaroslav Brustinov        """, re.VERBOSE | re.MULTILINE | re.DOTALL)
534823b8294SYaroslav Brustinov
535823b8294SYaroslav Brustinov    # A callable returning a true value iff its argument is a blank line
536823b8294SYaroslav Brustinov    # or contains a single comment.
537823b8294SYaroslav Brustinov    _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match
538823b8294SYaroslav Brustinov
539823b8294SYaroslav Brustinov    def parse(self, string, name='<string>'):
540823b8294SYaroslav Brustinov        """
541823b8294SYaroslav Brustinov        Divide the given string into examples and intervening text,
542823b8294SYaroslav Brustinov        and return them as a list of alternating Examples and strings.
543823b8294SYaroslav Brustinov        Line numbers for the Examples are 0-based.  The optional
544823b8294SYaroslav Brustinov        argument `name` is a name identifying this string, and is only
545823b8294SYaroslav Brustinov        used for error messages.
546823b8294SYaroslav Brustinov        """
547823b8294SYaroslav Brustinov        string = string.expandtabs()
548823b8294SYaroslav Brustinov        # If all lines begin with the same indentation, then strip it.
549823b8294SYaroslav Brustinov        min_indent = self._min_indent(string)
550823b8294SYaroslav Brustinov        if min_indent > 0:
551823b8294SYaroslav Brustinov            string = '\n'.join([l[min_indent:] for l in string.split('\n')])
552823b8294SYaroslav Brustinov
553823b8294SYaroslav Brustinov        output = []
554823b8294SYaroslav Brustinov        charno, lineno = 0, 0
555823b8294SYaroslav Brustinov        # Find all doctest examples in the string:
556823b8294SYaroslav Brustinov        for m in self._EXAMPLE_RE.finditer(string):
557823b8294SYaroslav Brustinov            # Add the pre-example text to `output`.
558823b8294SYaroslav Brustinov            output.append(string[charno:m.start()])
559823b8294SYaroslav Brustinov            # Update lineno (lines before this example)
560823b8294SYaroslav Brustinov            lineno += string.count('\n', charno, m.start())
561823b8294SYaroslav Brustinov            # Extract info from the regexp match.
562823b8294SYaroslav Brustinov            (source, options, want, exc_msg) = \
563823b8294SYaroslav Brustinov                     self._parse_example(m, name, lineno)
564823b8294SYaroslav Brustinov            # Create an Example, and add it to the list.
565823b8294SYaroslav Brustinov            if not self._IS_BLANK_OR_COMMENT(source):
566823b8294SYaroslav Brustinov                output.append( Example(source, want, exc_msg,
567823b8294SYaroslav Brustinov                                    lineno=lineno,
568823b8294SYaroslav Brustinov                                    indent=min_indent+len(m.group('indent')),
569823b8294SYaroslav Brustinov                                    options=options) )
570823b8294SYaroslav Brustinov            # Update lineno (lines inside this example)
571823b8294SYaroslav Brustinov            lineno += string.count('\n', m.start(), m.end())
572823b8294SYaroslav Brustinov            # Update charno.
573823b8294SYaroslav Brustinov            charno = m.end()
574823b8294SYaroslav Brustinov        # Add any remaining post-example text to `output`.
575823b8294SYaroslav Brustinov        output.append(string[charno:])
576823b8294SYaroslav Brustinov        return output
577823b8294SYaroslav Brustinov
578823b8294SYaroslav Brustinov    def get_doctest(self, string, globs, name, filename, lineno):
579823b8294SYaroslav Brustinov        """
580823b8294SYaroslav Brustinov        Extract all doctest examples from the given string, and
581823b8294SYaroslav Brustinov        collect them into a `DocTest` object.
582823b8294SYaroslav Brustinov
583823b8294SYaroslav Brustinov        `globs`, `name`, `filename`, and `lineno` are attributes for
584823b8294SYaroslav Brustinov        the new `DocTest` object.  See the documentation for `DocTest`
585823b8294SYaroslav Brustinov        for more information.
586823b8294SYaroslav Brustinov        """
587823b8294SYaroslav Brustinov        return DocTest(self.get_examples(string, name), globs,
588823b8294SYaroslav Brustinov                       name, filename, lineno, string)
589823b8294SYaroslav Brustinov
590823b8294SYaroslav Brustinov    def get_examples(self, string, name='<string>'):
591823b8294SYaroslav Brustinov        """
592823b8294SYaroslav Brustinov        Extract all doctest examples from the given string, and return
593823b8294SYaroslav Brustinov        them as a list of `Example` objects.  Line numbers are
594823b8294SYaroslav Brustinov        0-based, because it's most common in doctests that nothing
595823b8294SYaroslav Brustinov        interesting appears on the same line as opening triple-quote,
596823b8294SYaroslav Brustinov        and so the first interesting line is called \"line 1\" then.
597823b8294SYaroslav Brustinov
598823b8294SYaroslav Brustinov        The optional argument `name` is a name identifying this
599823b8294SYaroslav Brustinov        string, and is only used for error messages.
600823b8294SYaroslav Brustinov        """
601823b8294SYaroslav Brustinov        return [x for x in self.parse(string, name)
602823b8294SYaroslav Brustinov                if isinstance(x, Example)]
603823b8294SYaroslav Brustinov
604823b8294SYaroslav Brustinov    def _parse_example(self, m, name, lineno):
605823b8294SYaroslav Brustinov        """
606823b8294SYaroslav Brustinov        Given a regular expression match from `_EXAMPLE_RE` (`m`),
607823b8294SYaroslav Brustinov        return a pair `(source, want)`, where `source` is the matched
608823b8294SYaroslav Brustinov        example's source code (with prompts and indentation stripped);
609823b8294SYaroslav Brustinov        and `want` is the example's expected output (with indentation
610823b8294SYaroslav Brustinov        stripped).
611823b8294SYaroslav Brustinov
612823b8294SYaroslav Brustinov        `name` is the string's name, and `lineno` is the line number
613823b8294SYaroslav Brustinov        where the example starts; both are used for error messages.
614823b8294SYaroslav Brustinov        """
615823b8294SYaroslav Brustinov        # Get the example's indentation level.
616823b8294SYaroslav Brustinov        indent = len(m.group('indent'))
617823b8294SYaroslav Brustinov
618823b8294SYaroslav Brustinov        # Divide source into lines; check that they're properly
619823b8294SYaroslav Brustinov        # indented; and then strip their indentation & prompts.
620823b8294SYaroslav Brustinov        source_lines = m.group('source').split('\n')
621823b8294SYaroslav Brustinov        self._check_prompt_blank(source_lines, indent, name, lineno)
622823b8294SYaroslav Brustinov        self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno)
623823b8294SYaroslav Brustinov        source = '\n'.join([sl[indent+4:] for sl in source_lines])
624823b8294SYaroslav Brustinov
625823b8294SYaroslav Brustinov        # Divide want into lines; check that it's properly indented; and
626823b8294SYaroslav Brustinov        # then strip the indentation.  Spaces before the last newline should
627823b8294SYaroslav Brustinov        # be preserved, so plain rstrip() isn't good enough.
628823b8294SYaroslav Brustinov        want = m.group('want')
629823b8294SYaroslav Brustinov        want_lines = want.split('\n')
630823b8294SYaroslav Brustinov        if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
631823b8294SYaroslav Brustinov            del want_lines[-1]  # forget final newline & spaces after it
632823b8294SYaroslav Brustinov        self._check_prefix(want_lines, ' '*indent, name,
633823b8294SYaroslav Brustinov                           lineno + len(source_lines))
634823b8294SYaroslav Brustinov        want = '\n'.join([wl[indent:] for wl in want_lines])
635823b8294SYaroslav Brustinov
636823b8294SYaroslav Brustinov        # If `want` contains a traceback message, then extract it.
637823b8294SYaroslav Brustinov        m = self._EXCEPTION_RE.match(want)
638823b8294SYaroslav Brustinov        if m:
639823b8294SYaroslav Brustinov            exc_msg = m.group('msg')
640823b8294SYaroslav Brustinov        else:
641823b8294SYaroslav Brustinov            exc_msg = None
642823b8294SYaroslav Brustinov
643823b8294SYaroslav Brustinov        # Extract options from the source.
644823b8294SYaroslav Brustinov        options = self._find_options(source, name, lineno)
645823b8294SYaroslav Brustinov
646823b8294SYaroslav Brustinov        return source, options, want, exc_msg
647823b8294SYaroslav Brustinov
648823b8294SYaroslav Brustinov    # This regular expression looks for option directives in the
649823b8294SYaroslav Brustinov    # source code of an example.  Option directives are comments
650823b8294SYaroslav Brustinov    # starting with "doctest:".  Warning: this may give false
651823b8294SYaroslav Brustinov    # positives for string-literals that contain the string
652823b8294SYaroslav Brustinov    # "#doctest:".  Eliminating these false positives would require
653823b8294SYaroslav Brustinov    # actually parsing the string; but we limit them by ignoring any
654823b8294SYaroslav Brustinov    # line containing "#doctest:" that is *followed* by a quote mark.
655823b8294SYaroslav Brustinov    _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$',
656823b8294SYaroslav Brustinov                                      re.MULTILINE)
657823b8294SYaroslav Brustinov
658823b8294SYaroslav Brustinov    def _find_options(self, source, name, lineno):
659823b8294SYaroslav Brustinov        """
660823b8294SYaroslav Brustinov        Return a dictionary containing option overrides extracted from
661823b8294SYaroslav Brustinov        option directives in the given source string.
662823b8294SYaroslav Brustinov
663823b8294SYaroslav Brustinov        `name` is the string's name, and `lineno` is the line number
664823b8294SYaroslav Brustinov        where the example starts; both are used for error messages.
665823b8294SYaroslav Brustinov        """
666823b8294SYaroslav Brustinov        options = {}
667823b8294SYaroslav Brustinov        # (note: with the current regexp, this will match at most once:)
668823b8294SYaroslav Brustinov        for m in self._OPTION_DIRECTIVE_RE.finditer(source):
669823b8294SYaroslav Brustinov            option_strings = m.group(1).replace(',', ' ').split()
670823b8294SYaroslav Brustinov            for option in option_strings:
671823b8294SYaroslav Brustinov                if (option[0] not in '+-' or
672823b8294SYaroslav Brustinov                    option[1:] not in OPTIONFLAGS_BY_NAME):
673823b8294SYaroslav Brustinov                    raise ValueError('line %r of the doctest for %s '
674823b8294SYaroslav Brustinov                                     'has an invalid option: %r' %
675823b8294SYaroslav Brustinov                                     (lineno+1, name, option))
676823b8294SYaroslav Brustinov                flag = OPTIONFLAGS_BY_NAME[option[1:]]
677823b8294SYaroslav Brustinov                options[flag] = (option[0] == '+')
678823b8294SYaroslav Brustinov        if options and self._IS_BLANK_OR_COMMENT(source):
679823b8294SYaroslav Brustinov            raise ValueError('line %r of the doctest for %s has an option '
680823b8294SYaroslav Brustinov                             'directive on a line with no example: %r' %
681823b8294SYaroslav Brustinov                             (lineno, name, source))
682823b8294SYaroslav Brustinov        return options
683823b8294SYaroslav Brustinov
684823b8294SYaroslav Brustinov    # This regular expression finds the indentation of every non-blank
685823b8294SYaroslav Brustinov    # line in a string.
686823b8294SYaroslav Brustinov    _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE)
687823b8294SYaroslav Brustinov
688823b8294SYaroslav Brustinov    def _min_indent(self, s):
689823b8294SYaroslav Brustinov        "Return the minimum indentation of any non-blank line in `s`"
690823b8294SYaroslav Brustinov        indents = [len(indent) for indent in self._INDENT_RE.findall(s)]
691823b8294SYaroslav Brustinov        if len(indents) > 0:
692823b8294SYaroslav Brustinov            return min(indents)
693823b8294SYaroslav Brustinov        else:
694823b8294SYaroslav Brustinov            return 0
695823b8294SYaroslav Brustinov
696823b8294SYaroslav Brustinov    def _check_prompt_blank(self, lines, indent, name, lineno):
697823b8294SYaroslav Brustinov        """
698823b8294SYaroslav Brustinov        Given the lines of a source string (including prompts and
699823b8294SYaroslav Brustinov        leading indentation), check to make sure that every prompt is
700823b8294SYaroslav Brustinov        followed by a space character.  If any line is not followed by
701823b8294SYaroslav Brustinov        a space character, then raise ValueError.
702823b8294SYaroslav Brustinov        """
703823b8294SYaroslav Brustinov        for i, line in enumerate(lines):
704823b8294SYaroslav Brustinov            if len(line) >= indent+4 and line[indent+3] != ' ':
705823b8294SYaroslav Brustinov                raise ValueError('line %r of the docstring for %s '
706823b8294SYaroslav Brustinov                                 'lacks blank after %s: %r' %
707823b8294SYaroslav Brustinov                                 (lineno+i+1, name,
708823b8294SYaroslav Brustinov                                  line[indent:indent+3], line))
709823b8294SYaroslav Brustinov
710823b8294SYaroslav Brustinov    def _check_prefix(self, lines, prefix, name, lineno):
711823b8294SYaroslav Brustinov        """
712823b8294SYaroslav Brustinov        Check that every line in the given list starts with the given
713823b8294SYaroslav Brustinov        prefix; if any line does not, then raise a ValueError.
714823b8294SYaroslav Brustinov        """
715823b8294SYaroslav Brustinov        for i, line in enumerate(lines):
716823b8294SYaroslav Brustinov            if line and not line.startswith(prefix):
717823b8294SYaroslav Brustinov                raise ValueError('line %r of the docstring for %s has '
718823b8294SYaroslav Brustinov                                 'inconsistent leading whitespace: %r' %
719823b8294SYaroslav Brustinov                                 (lineno+i+1, name, line))
720823b8294SYaroslav Brustinov
721823b8294SYaroslav Brustinov
722823b8294SYaroslav Brustinov######################################################################
723823b8294SYaroslav Brustinov## 4. DocTest Finder
724823b8294SYaroslav Brustinov######################################################################
725823b8294SYaroslav Brustinov
726823b8294SYaroslav Brustinovclass DocTestFinder:
727823b8294SYaroslav Brustinov    """
728823b8294SYaroslav Brustinov    A class used to extract the DocTests that are relevant to a given
729823b8294SYaroslav Brustinov    object, from its docstring and the docstrings of its contained
730823b8294SYaroslav Brustinov    objects.  Doctests can currently be extracted from the following
731823b8294SYaroslav Brustinov    object types: modules, functions, classes, methods, staticmethods,
732823b8294SYaroslav Brustinov    classmethods, and properties.
733823b8294SYaroslav Brustinov    """
734823b8294SYaroslav Brustinov
735823b8294SYaroslav Brustinov    def __init__(self, verbose=False, parser=DocTestParser(),
736823b8294SYaroslav Brustinov                 recurse=True, _namefilter=None, exclude_empty=True):
737823b8294SYaroslav Brustinov        """
738823b8294SYaroslav Brustinov        Create a new doctest finder.
739823b8294SYaroslav Brustinov
740823b8294SYaroslav Brustinov        The optional argument `parser` specifies a class or
741823b8294SYaroslav Brustinov        function that should be used to create new DocTest objects (or
742823b8294SYaroslav Brustinov        objects that implement the same interface as DocTest).  The
743823b8294SYaroslav Brustinov        signature for this factory function should match the signature
744823b8294SYaroslav Brustinov        of the DocTest constructor.
745823b8294SYaroslav Brustinov
746823b8294SYaroslav Brustinov        If the optional argument `recurse` is false, then `find` will
747823b8294SYaroslav Brustinov        only examine the given object, and not any contained objects.
748823b8294SYaroslav Brustinov
749823b8294SYaroslav Brustinov        If the optional argument `exclude_empty` is false, then `find`
750823b8294SYaroslav Brustinov        will include tests for objects with empty docstrings.
751823b8294SYaroslav Brustinov        """
752823b8294SYaroslav Brustinov        self._parser = parser
753823b8294SYaroslav Brustinov        self._verbose = verbose
754823b8294SYaroslav Brustinov        self._recurse = recurse
755823b8294SYaroslav Brustinov        self._exclude_empty = exclude_empty
756823b8294SYaroslav Brustinov        # _namefilter is undocumented, and exists only for temporary backward-
757823b8294SYaroslav Brustinov        # compatibility support of testmod's deprecated isprivate mess.
758823b8294SYaroslav Brustinov        self._namefilter = _namefilter
759823b8294SYaroslav Brustinov
760823b8294SYaroslav Brustinov    def find(self, obj, name=None, module=None, globs=None,
761823b8294SYaroslav Brustinov             extraglobs=None):
762823b8294SYaroslav Brustinov        """
763823b8294SYaroslav Brustinov        Return a list of the DocTests that are defined by the given
764823b8294SYaroslav Brustinov        object's docstring, or by any of its contained objects'
765823b8294SYaroslav Brustinov        docstrings.
766823b8294SYaroslav Brustinov
767823b8294SYaroslav Brustinov        The optional parameter `module` is the module that contains
768823b8294SYaroslav Brustinov        the given object.  If the module is not specified or is None, then
769823b8294SYaroslav Brustinov        the test finder will attempt to automatically determine the
770823b8294SYaroslav Brustinov        correct module.  The object's module is used:
771823b8294SYaroslav Brustinov
772823b8294SYaroslav Brustinov            - As a default namespace, if `globs` is not specified.
773823b8294SYaroslav Brustinov            - To prevent the DocTestFinder from extracting DocTests
774823b8294SYaroslav Brustinov              from objects that are imported from other modules.
775823b8294SYaroslav Brustinov            - To find the name of the file containing the object.
776823b8294SYaroslav Brustinov            - To help find the line number of the object within its
777823b8294SYaroslav Brustinov              file.
778823b8294SYaroslav Brustinov
779823b8294SYaroslav Brustinov        Contained objects whose module does not match `module` are ignored.
780823b8294SYaroslav Brustinov
781823b8294SYaroslav Brustinov        If `module` is False, no attempt to find the module will be made.
782823b8294SYaroslav Brustinov        This is obscure, of use mostly in tests:  if `module` is False, or
783823b8294SYaroslav Brustinov        is None but cannot be found automatically, then all objects are
784823b8294SYaroslav Brustinov        considered to belong to the (non-existent) module, so all contained
785823b8294SYaroslav Brustinov        objects will (recursively) be searched for doctests.
786823b8294SYaroslav Brustinov
787823b8294SYaroslav Brustinov        The globals for each DocTest is formed by combining `globs`
788823b8294SYaroslav Brustinov        and `extraglobs` (bindings in `extraglobs` override bindings
789823b8294SYaroslav Brustinov        in `globs`).  A new copy of the globals dictionary is created
790823b8294SYaroslav Brustinov        for each DocTest.  If `globs` is not specified, then it
791823b8294SYaroslav Brustinov        defaults to the module's `__dict__`, if specified, or {}
792823b8294SYaroslav Brustinov        otherwise.  If `extraglobs` is not specified, then it defaults
793823b8294SYaroslav Brustinov        to {}.
794823b8294SYaroslav Brustinov
795823b8294SYaroslav Brustinov        """
796823b8294SYaroslav Brustinov        # If name was not specified, then extract it from the object.
797823b8294SYaroslav Brustinov        if name is None:
798823b8294SYaroslav Brustinov            name = getattr(obj, '__name__', None)
799823b8294SYaroslav Brustinov            if name is None:
800823b8294SYaroslav Brustinov                raise ValueError("DocTestFinder.find: name must be given "
801823b8294SYaroslav Brustinov                        "when obj.__name__ doesn't exist: %r" %
802823b8294SYaroslav Brustinov                                 (type(obj),))
803823b8294SYaroslav Brustinov
804823b8294SYaroslav Brustinov        # Find the module that contains the given object (if obj is
805823b8294SYaroslav Brustinov        # a module, then module=obj.).  Note: this may fail, in which
806823b8294SYaroslav Brustinov        # case module will be None.
807823b8294SYaroslav Brustinov        if module is False:
808823b8294SYaroslav Brustinov            module = None
809823b8294SYaroslav Brustinov        elif module is None:
810823b8294SYaroslav Brustinov            module = inspect.getmodule(obj)
811823b8294SYaroslav Brustinov
812823b8294SYaroslav Brustinov        # Read the module's source code.  This is used by
813823b8294SYaroslav Brustinov        # DocTestFinder._find_lineno to find the line number for a
814823b8294SYaroslav Brustinov        # given object's docstring.
815823b8294SYaroslav Brustinov        try:
816823b8294SYaroslav Brustinov            file = inspect.getsourcefile(obj) or inspect.getfile(obj)
817823b8294SYaroslav Brustinov            source_lines = linecache.getlines(file)
818823b8294SYaroslav Brustinov            if not source_lines:
819823b8294SYaroslav Brustinov                source_lines = None
820823b8294SYaroslav Brustinov        except TypeError:
821823b8294SYaroslav Brustinov            source_lines = None
822823b8294SYaroslav Brustinov
823823b8294SYaroslav Brustinov        # Initialize globals, and merge in extraglobs.
824823b8294SYaroslav Brustinov        if globs is None:
825823b8294SYaroslav Brustinov            if module is None:
826823b8294SYaroslav Brustinov                globs = {}
827823b8294SYaroslav Brustinov            else:
828823b8294SYaroslav Brustinov                globs = module.__dict__.copy()
829823b8294SYaroslav Brustinov        else:
830823b8294SYaroslav Brustinov            globs = globs.copy()
831823b8294SYaroslav Brustinov        if extraglobs is not None:
832823b8294SYaroslav Brustinov            globs.update(extraglobs)
833823b8294SYaroslav Brustinov
834823b8294SYaroslav Brustinov        # Recursively expore `obj`, extracting DocTests.
835823b8294SYaroslav Brustinov        tests = []
836823b8294SYaroslav Brustinov        self._find(tests, obj, name, module, source_lines, globs, {})
837823b8294SYaroslav Brustinov        # Sort the tests by alpha order of names, for consistency in
838823b8294SYaroslav Brustinov        # verbose-mode output.  This was a feature of doctest in Pythons
839823b8294SYaroslav Brustinov        # <= 2.3 that got lost by accident in 2.4.  It was repaired in
840823b8294SYaroslav Brustinov        # 2.4.4 and 2.5.
841823b8294SYaroslav Brustinov        tests.sort()
842823b8294SYaroslav Brustinov        return tests
843823b8294SYaroslav Brustinov
844823b8294SYaroslav Brustinov    def _filter(self, obj, prefix, base):
845823b8294SYaroslav Brustinov        """
846823b8294SYaroslav Brustinov        Return true if the given object should not be examined.
847823b8294SYaroslav Brustinov        """
848823b8294SYaroslav Brustinov        return (self._namefilter is not None and
849823b8294SYaroslav Brustinov                self._namefilter(prefix, base))
850823b8294SYaroslav Brustinov
851823b8294SYaroslav Brustinov    def _from_module(self, module, object):
852823b8294SYaroslav Brustinov        """
853823b8294SYaroslav Brustinov        Return true if the given object is defined in the given
854823b8294SYaroslav Brustinov        module.
855823b8294SYaroslav Brustinov        """
856823b8294SYaroslav Brustinov        if module is None:
857823b8294SYaroslav Brustinov            return True
858823b8294SYaroslav Brustinov        elif inspect.isfunction(object):
859823b8294SYaroslav Brustinov            return module.__dict__ is object.func_globals
860823b8294SYaroslav Brustinov        elif inspect.isclass(object):
861823b8294SYaroslav Brustinov            # Some jython classes don't set __module__
862823b8294SYaroslav Brustinov            return module.__name__ == getattr(object, '__module__', None)
863823b8294SYaroslav Brustinov        elif inspect.getmodule(object) is not None:
864823b8294SYaroslav Brustinov            return module is inspect.getmodule(object)
865823b8294SYaroslav Brustinov        elif hasattr(object, '__module__'):
866823b8294SYaroslav Brustinov            return module.__name__ == object.__module__
867823b8294SYaroslav Brustinov        elif isinstance(object, property):
868823b8294SYaroslav Brustinov            return True # [XX] no way not be sure.
869823b8294SYaroslav Brustinov        else:
870823b8294SYaroslav Brustinov            raise ValueError("object must be a class or function")
871823b8294SYaroslav Brustinov
872823b8294SYaroslav Brustinov    def _find(self, tests, obj, name, module, source_lines, globs, seen):
873823b8294SYaroslav Brustinov        """
874823b8294SYaroslav Brustinov        Find tests for the given object and any contained objects, and
875823b8294SYaroslav Brustinov        add them to `tests`.
876823b8294SYaroslav Brustinov        """
877823b8294SYaroslav Brustinov        if self._verbose:
878823b8294SYaroslav Brustinov            print 'Finding tests in %s' % name
879823b8294SYaroslav Brustinov
880823b8294SYaroslav Brustinov        # If we've already processed this object, then ignore it.
881823b8294SYaroslav Brustinov        if id(obj) in seen:
882823b8294SYaroslav Brustinov            return
883823b8294SYaroslav Brustinov        seen[id(obj)] = 1
884823b8294SYaroslav Brustinov
885823b8294SYaroslav Brustinov        # Find a test for this object, and add it to the list of tests.
886823b8294SYaroslav Brustinov        test = self._get_test(obj, name, module, globs, source_lines)
887823b8294SYaroslav Brustinov        if test is not None:
888823b8294SYaroslav Brustinov            tests.append(test)
889823b8294SYaroslav Brustinov
890823b8294SYaroslav Brustinov        # Look for tests in a module's contained objects.
891823b8294SYaroslav Brustinov        if inspect.ismodule(obj) and self._recurse:
892823b8294SYaroslav Brustinov            for valname, val in obj.__dict__.items():
893823b8294SYaroslav Brustinov                # Check if this contained object should be ignored.
894823b8294SYaroslav Brustinov                if self._filter(val, name, valname):
895823b8294SYaroslav Brustinov                    continue
896823b8294SYaroslav Brustinov                valname = '%s.%s' % (name, valname)
897823b8294SYaroslav Brustinov                # Recurse to functions & classes.
898823b8294SYaroslav Brustinov                if ((inspect.isfunction(val) or inspect.isclass(val)) and
899823b8294SYaroslav Brustinov                    self._from_module(module, val)):
900823b8294SYaroslav Brustinov                    self._find(tests, val, valname, module, source_lines,
901823b8294SYaroslav Brustinov                               globs, seen)
902823b8294SYaroslav Brustinov
903823b8294SYaroslav Brustinov        # Look for tests in a module's __test__ dictionary.
904823b8294SYaroslav Brustinov        if inspect.ismodule(obj) and self._recurse:
905823b8294SYaroslav Brustinov            for valname, val in getattr(obj, '__test__', {}).items():
906823b8294SYaroslav Brustinov                if not isinstance(valname, basestring):
907823b8294SYaroslav Brustinov                    raise ValueError("DocTestFinder.find: __test__ keys "
908823b8294SYaroslav Brustinov                                     "must be strings: %r" %
909823b8294SYaroslav Brustinov                                     (type(valname),))
910823b8294SYaroslav Brustinov                if not (inspect.isfunction(val) or inspect.isclass(val) or
911823b8294SYaroslav Brustinov                        inspect.ismethod(val) or inspect.ismodule(val) or
912823b8294SYaroslav Brustinov                        isinstance(val, basestring)):
913823b8294SYaroslav Brustinov                    raise ValueError("DocTestFinder.find: __test__ values "
914823b8294SYaroslav Brustinov                                     "must be strings, functions, methods, "
915823b8294SYaroslav Brustinov                                     "classes, or modules: %r" %
916823b8294SYaroslav Brustinov                                     (type(val),))
917823b8294SYaroslav Brustinov                valname = '%s.__test__.%s' % (name, valname)
918823b8294SYaroslav Brustinov                self._find(tests, val, valname, module, source_lines,
919823b8294SYaroslav Brustinov                           globs, seen)
920823b8294SYaroslav Brustinov
921823b8294SYaroslav Brustinov        # Look for tests in a class's contained objects.
922823b8294SYaroslav Brustinov        if inspect.isclass(obj) and self._recurse:
923823b8294SYaroslav Brustinov            for valname, val in obj.__dict__.items():
924823b8294SYaroslav Brustinov                # Check if this contained object should be ignored.
925823b8294SYaroslav Brustinov                if self._filter(val, name, valname):
926823b8294SYaroslav Brustinov                    continue
927823b8294SYaroslav Brustinov                # Special handling for staticmethod/classmethod.
928823b8294SYaroslav Brustinov                if isinstance(val, staticmethod):
929823b8294SYaroslav Brustinov                    val = getattr(obj, valname)
930823b8294SYaroslav Brustinov                if isinstance(val, classmethod):
931823b8294SYaroslav Brustinov                    val = getattr(obj, valname).im_func
932823b8294SYaroslav Brustinov
933823b8294SYaroslav Brustinov                # Recurse to methods, properties, and nested classes.
934823b8294SYaroslav Brustinov                if ((inspect.isfunction(val) or inspect.isclass(val) or
935823b8294SYaroslav Brustinov                      isinstance(val, property)) and
936823b8294SYaroslav Brustinov                      self._from_module(module, val)):
937823b8294SYaroslav Brustinov                    valname = '%s.%s' % (name, valname)
938823b8294SYaroslav Brustinov                    self._find(tests, val, valname, module, source_lines,
939823b8294SYaroslav Brustinov                               globs, seen)
940823b8294SYaroslav Brustinov
941823b8294SYaroslav Brustinov    def _get_test(self, obj, name, module, globs, source_lines):
942823b8294SYaroslav Brustinov        """
943823b8294SYaroslav Brustinov        Return a DocTest for the given object, if it defines a docstring;
944823b8294SYaroslav Brustinov        otherwise, return None.
945823b8294SYaroslav Brustinov        """
946823b8294SYaroslav Brustinov        # Extract the object's docstring.  If it doesn't have one,
947823b8294SYaroslav Brustinov        # then return None (no test for this object).
948823b8294SYaroslav Brustinov        if isinstance(obj, basestring):
949823b8294SYaroslav Brustinov            docstring = obj
950823b8294SYaroslav Brustinov        else:
951823b8294SYaroslav Brustinov            try:
952823b8294SYaroslav Brustinov                if obj.__doc__ is None:
953823b8294SYaroslav Brustinov                    docstring = ''
954823b8294SYaroslav Brustinov                else:
955823b8294SYaroslav Brustinov                    docstring = obj.__doc__
956823b8294SYaroslav Brustinov                    if not isinstance(docstring, basestring):
957823b8294SYaroslav Brustinov                        docstring = str(docstring)
958823b8294SYaroslav Brustinov            except (TypeError, AttributeError):
959823b8294SYaroslav Brustinov                docstring = ''
960823b8294SYaroslav Brustinov
961823b8294SYaroslav Brustinov        # Find the docstring's location in the file.
962823b8294SYaroslav Brustinov        lineno = self._find_lineno(obj, source_lines)
963823b8294SYaroslav Brustinov
964823b8294SYaroslav Brustinov        # Don't bother if the docstring is empty.
965823b8294SYaroslav Brustinov        if self._exclude_empty and not docstring:
966823b8294SYaroslav Brustinov            return None
967823b8294SYaroslav Brustinov
968823b8294SYaroslav Brustinov        # Return a DocTest for this object.
969823b8294SYaroslav Brustinov        if module is None:
970823b8294SYaroslav Brustinov            filename = None
971823b8294SYaroslav Brustinov        else:
972823b8294SYaroslav Brustinov            filename = getattr(module, '__file__', module.__name__)
973823b8294SYaroslav Brustinov            if filename[-4:] in (".pyc", ".pyo"):
974823b8294SYaroslav Brustinov                filename = filename[:-1]
975823b8294SYaroslav Brustinov            elif sys.platform.startswith('java') and \
976823b8294SYaroslav Brustinov                    filename.endswith('$py.class'):
977823b8294SYaroslav Brustinov                filename = '%s.py' % filename[:-9]
978823b8294SYaroslav Brustinov        return self._parser.get_doctest(docstring, globs, name,
979823b8294SYaroslav Brustinov                                        filename, lineno)
980823b8294SYaroslav Brustinov
981823b8294SYaroslav Brustinov    def _find_lineno(self, obj, source_lines):
982823b8294SYaroslav Brustinov        """
983823b8294SYaroslav Brustinov        Return a line number of the given object's docstring.  Note:
984823b8294SYaroslav Brustinov        this method assumes that the object has a docstring.
985823b8294SYaroslav Brustinov        """
986823b8294SYaroslav Brustinov        lineno = None
987823b8294SYaroslav Brustinov
988823b8294SYaroslav Brustinov        # Find the line number for modules.
989823b8294SYaroslav Brustinov        if inspect.ismodule(obj):
990823b8294SYaroslav Brustinov            lineno = 0
991823b8294SYaroslav Brustinov
992823b8294SYaroslav Brustinov        # Find the line number for classes.
993823b8294SYaroslav Brustinov        # Note: this could be fooled if a class is defined multiple
994823b8294SYaroslav Brustinov        # times in a single file.
995823b8294SYaroslav Brustinov        if inspect.isclass(obj):
996823b8294SYaroslav Brustinov            if source_lines is None:
997823b8294SYaroslav Brustinov                return None
998823b8294SYaroslav Brustinov            pat = re.compile(r'^\s*class\s*%s\b' %
999823b8294SYaroslav Brustinov                             getattr(obj, '__name__', '-'))
1000823b8294SYaroslav Brustinov            for i, line in enumerate(source_lines):
1001823b8294SYaroslav Brustinov                if pat.match(line):
1002823b8294SYaroslav Brustinov                    lineno = i
1003823b8294SYaroslav Brustinov                    break
1004823b8294SYaroslav Brustinov
1005823b8294SYaroslav Brustinov        # Find the line number for functions & methods.
1006823b8294SYaroslav Brustinov        if inspect.ismethod(obj): obj = obj.im_func
1007823b8294SYaroslav Brustinov        if inspect.isfunction(obj): obj = obj.func_code
1008823b8294SYaroslav Brustinov        if inspect.istraceback(obj): obj = obj.tb_frame
1009823b8294SYaroslav Brustinov        if inspect.isframe(obj): obj = obj.f_code
1010823b8294SYaroslav Brustinov        if inspect.iscode(obj):
1011823b8294SYaroslav Brustinov            lineno = getattr(obj, 'co_firstlineno', None)-1
1012823b8294SYaroslav Brustinov
1013823b8294SYaroslav Brustinov        # Find the line number where the docstring starts.  Assume
1014823b8294SYaroslav Brustinov        # that it's the first line that begins with a quote mark.
1015823b8294SYaroslav Brustinov        # Note: this could be fooled by a multiline function
1016823b8294SYaroslav Brustinov        # signature, where a continuation line begins with a quote
1017823b8294SYaroslav Brustinov        # mark.
1018823b8294SYaroslav Brustinov        if lineno is not None:
1019823b8294SYaroslav Brustinov            if source_lines is None:
1020823b8294SYaroslav Brustinov                return lineno+1
1021823b8294SYaroslav Brustinov            pat = re.compile('(^|.*:)\s*\w*("|\')')
1022823b8294SYaroslav Brustinov            for lineno in range(lineno, len(source_lines)):
1023823b8294SYaroslav Brustinov                if pat.match(source_lines[lineno]):
1024823b8294SYaroslav Brustinov                    return lineno
1025823b8294SYaroslav Brustinov
1026823b8294SYaroslav Brustinov        # We couldn't find the line number.
1027823b8294SYaroslav Brustinov        return None
1028823b8294SYaroslav Brustinov
1029823b8294SYaroslav Brustinov######################################################################
1030823b8294SYaroslav Brustinov## 5. DocTest Runner
1031823b8294SYaroslav Brustinov######################################################################
1032823b8294SYaroslav Brustinov
1033823b8294SYaroslav Brustinovclass DocTestRunner:
1034823b8294SYaroslav Brustinov    # This divider string is used to separate failure messages, and to
1035823b8294SYaroslav Brustinov    # separate sections of the summary.
1036823b8294SYaroslav Brustinov    DIVIDER = "*" * 70
1037823b8294SYaroslav Brustinov
1038823b8294SYaroslav Brustinov    def __init__(self, checker=None, verbose=None, optionflags=0):
1039823b8294SYaroslav Brustinov        """
1040823b8294SYaroslav Brustinov        Create a new test runner.
1041823b8294SYaroslav Brustinov
1042823b8294SYaroslav Brustinov        Optional keyword arg `checker` is the `OutputChecker` that
1043823b8294SYaroslav Brustinov        should be used to compare the expected outputs and actual
1044823b8294SYaroslav Brustinov        outputs of doctest examples.
1045823b8294SYaroslav Brustinov
1046823b8294SYaroslav Brustinov        Optional keyword arg 'verbose' prints lots of stuff if true,
1047823b8294SYaroslav Brustinov        only failures if false; by default, it's true iff '-v' is in
1048823b8294SYaroslav Brustinov        sys.argv.
1049823b8294SYaroslav Brustinov
1050823b8294SYaroslav Brustinov        Optional argument `optionflags` can be used to control how the
1051823b8294SYaroslav Brustinov        test runner compares expected output to actual output, and how
1052823b8294SYaroslav Brustinov        it displays failures.  See the documentation for `testmod` for
1053823b8294SYaroslav Brustinov        more information.
1054823b8294SYaroslav Brustinov        """
1055823b8294SYaroslav Brustinov        self._checker = checker or OutputChecker()
1056823b8294SYaroslav Brustinov        if verbose is None:
1057823b8294SYaroslav Brustinov            verbose = '-v' in sys.argv
1058823b8294SYaroslav Brustinov        self._verbose = verbose
1059823b8294SYaroslav Brustinov        self.optionflags = optionflags
1060823b8294SYaroslav Brustinov        self.original_optionflags = optionflags
1061823b8294SYaroslav Brustinov
1062823b8294SYaroslav Brustinov        # Keep track of the examples we've run.
1063823b8294SYaroslav Brustinov        self.tries = 0
1064823b8294SYaroslav Brustinov        self.failures = 0
1065823b8294SYaroslav Brustinov        self._name2ft = {}
1066823b8294SYaroslav Brustinov
1067823b8294SYaroslav Brustinov        # Create a fake output target for capturing doctest output.
1068823b8294SYaroslav Brustinov        self._fakeout = _SpoofOut()
1069823b8294SYaroslav Brustinov
1070823b8294SYaroslav Brustinov    #/////////////////////////////////////////////////////////////////
1071823b8294SYaroslav Brustinov    # Reporting methods
1072823b8294SYaroslav Brustinov    #/////////////////////////////////////////////////////////////////
1073823b8294SYaroslav Brustinov
1074823b8294SYaroslav Brustinov    def report_start(self, out, test, example):
1075823b8294SYaroslav Brustinov        """
1076823b8294SYaroslav Brustinov        Report that the test runner is about to process the given
1077823b8294SYaroslav Brustinov        example.  (Only displays a message if verbose=True)
1078823b8294SYaroslav Brustinov        """
1079823b8294SYaroslav Brustinov        if self._verbose:
1080823b8294SYaroslav Brustinov            if example.want:
1081823b8294SYaroslav Brustinov                out('Trying:\n' + _indent(example.source) +
1082823b8294SYaroslav Brustinov                    'Expecting:\n' + _indent(example.want))
1083823b8294SYaroslav Brustinov            else:
1084823b8294SYaroslav Brustinov                out('Trying:\n' + _indent(example.source) +
1085823b8294SYaroslav Brustinov                    'Expecting nothing\n')
1086823b8294SYaroslav Brustinov
1087823b8294SYaroslav Brustinov    def report_success(self, out, test, example, got):
1088823b8294SYaroslav Brustinov        """
1089823b8294SYaroslav Brustinov        Report that the given example ran successfully.  (Only
1090823b8294SYaroslav Brustinov        displays a message if verbose=True)
1091823b8294SYaroslav Brustinov        """
1092823b8294SYaroslav Brustinov        if self._verbose:
1093823b8294SYaroslav Brustinov            out("ok\n")
1094823b8294SYaroslav Brustinov
1095823b8294SYaroslav Brustinov    def report_failure(self, out, test, example, got):
1096823b8294SYaroslav Brustinov        """
1097823b8294SYaroslav Brustinov        Report that the given example failed.
1098823b8294SYaroslav Brustinov        """
1099823b8294SYaroslav Brustinov        out(self._failure_header(test, example) +
1100823b8294SYaroslav Brustinov            self._checker.output_difference(example, got, self.optionflags))
1101823b8294SYaroslav Brustinov
1102823b8294SYaroslav Brustinov    def report_unexpected_exception(self, out, test, example, exc_info):
1103823b8294SYaroslav Brustinov        """
1104823b8294SYaroslav Brustinov        Report that the given example raised an unexpected exception.
1105823b8294SYaroslav Brustinov        """
1106823b8294SYaroslav Brustinov        out(self._failure_header(test, example) +
1107823b8294SYaroslav Brustinov            'Exception raised:\n' + _indent(_exception_traceback(exc_info)))
1108823b8294SYaroslav Brustinov
1109823b8294SYaroslav Brustinov    def _failure_header(self, test, example):
1110823b8294SYaroslav Brustinov        out = [self.DIVIDER]
1111823b8294SYaroslav Brustinov        if test.filename:
1112823b8294SYaroslav Brustinov            if test.lineno is not None and example.lineno is not None:
1113823b8294SYaroslav Brustinov                lineno = test.lineno + example.lineno + 1
1114823b8294SYaroslav Brustinov            else:
1115823b8294SYaroslav Brustinov                lineno = '?'
1116823b8294SYaroslav Brustinov            out.append('File "%s", line %s, in %s' %
1117823b8294SYaroslav Brustinov                       (test.filename, lineno, test.name))
1118823b8294SYaroslav Brustinov        else:
1119823b8294SYaroslav Brustinov            out.append('Line %s, in %s' % (example.lineno+1, test.name))
1120823b8294SYaroslav Brustinov        out.append('Failed example:')
1121823b8294SYaroslav Brustinov        source = example.source
1122823b8294SYaroslav Brustinov        out.append(_indent(source))
1123823b8294SYaroslav Brustinov        return '\n'.join(out)
1124823b8294SYaroslav Brustinov
1125823b8294SYaroslav Brustinov    #/////////////////////////////////////////////////////////////////
1126823b8294SYaroslav Brustinov    # DocTest Running
1127823b8294SYaroslav Brustinov    #/////////////////////////////////////////////////////////////////
1128823b8294SYaroslav Brustinov
1129823b8294SYaroslav Brustinov    def __run(self, test, compileflags, out):
1130823b8294SYaroslav Brustinov        """
1131823b8294SYaroslav Brustinov        Run the examples in `test`.  Write the outcome of each example
1132823b8294SYaroslav Brustinov        with one of the `DocTestRunner.report_*` methods, using the
1133823b8294SYaroslav Brustinov        writer function `out`.  `compileflags` is the set of compiler
1134823b8294SYaroslav Brustinov        flags that should be used to execute examples.  Return a tuple
1135823b8294SYaroslav Brustinov        `(f, t)`, where `t` is the number of examples tried, and `f`
1136823b8294SYaroslav Brustinov        is the number of examples that failed.  The examples are run
1137823b8294SYaroslav Brustinov        in the namespace `test.globs`.
1138823b8294SYaroslav Brustinov        """
1139823b8294SYaroslav Brustinov        # Keep track of the number of failures and tries.
1140823b8294SYaroslav Brustinov        failures = tries = 0
1141823b8294SYaroslav Brustinov
1142823b8294SYaroslav Brustinov        # Save the option flags (since option directives can be used
1143823b8294SYaroslav Brustinov        # to modify them).
1144823b8294SYaroslav Brustinov        original_optionflags = self.optionflags
1145823b8294SYaroslav Brustinov
1146823b8294SYaroslav Brustinov        SUCCESS, FAILURE, BOOM = range(3) # `outcome` state
1147823b8294SYaroslav Brustinov
1148823b8294SYaroslav Brustinov        check = self._checker.check_output
1149823b8294SYaroslav Brustinov
1150823b8294SYaroslav Brustinov        # Process each example.
1151823b8294SYaroslav Brustinov        for examplenum, example in enumerate(test.examples):
1152823b8294SYaroslav Brustinov
1153823b8294SYaroslav Brustinov            # If REPORT_ONLY_FIRST_FAILURE is set, then supress
1154823b8294SYaroslav Brustinov            # reporting after the first failure.
1155823b8294SYaroslav Brustinov            quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and
1156823b8294SYaroslav Brustinov                     failures > 0)
1157823b8294SYaroslav Brustinov
1158823b8294SYaroslav Brustinov            # Merge in the example's options.
1159823b8294SYaroslav Brustinov            self.optionflags = original_optionflags
1160823b8294SYaroslav Brustinov            if example.options:
1161823b8294SYaroslav Brustinov                for (optionflag, val) in example.options.items():
1162823b8294SYaroslav Brustinov                    if val:
1163823b8294SYaroslav Brustinov                        self.optionflags |= optionflag
1164823b8294SYaroslav Brustinov                    else:
1165823b8294SYaroslav Brustinov                        self.optionflags &= ~optionflag
1166823b8294SYaroslav Brustinov
1167823b8294SYaroslav Brustinov            # Record that we started this example.
1168823b8294SYaroslav Brustinov            tries += 1
1169823b8294SYaroslav Brustinov            if not quiet:
1170823b8294SYaroslav Brustinov                self.report_start(out, test, example)
1171823b8294SYaroslav Brustinov
1172823b8294SYaroslav Brustinov            # Use a special filename for compile(), so we can retrieve
1173823b8294SYaroslav Brustinov            # the source code during interactive debugging (see
1174823b8294SYaroslav Brustinov            # __patched_linecache_getlines).
1175823b8294SYaroslav Brustinov            filename = '<doctest %s[%d]>' % (test.name, examplenum)
1176823b8294SYaroslav Brustinov
1177823b8294SYaroslav Brustinov            # Run the example in the given context (globs), and record
1178823b8294SYaroslav Brustinov            # any exception that gets raised.  (But don't intercept
1179823b8294SYaroslav Brustinov            # keyboard interrupts.)
1180823b8294SYaroslav Brustinov            try:
1181823b8294SYaroslav Brustinov                # Don't blink!  This is where the user's code gets run.
1182823b8294SYaroslav Brustinov                exec compile(example.source, filename, "single",
1183823b8294SYaroslav Brustinov                             compileflags, 1) in test.globs
1184823b8294SYaroslav Brustinov                self.debugger.set_continue() # ==== Example Finished ====
1185823b8294SYaroslav Brustinov                exception = None
1186823b8294SYaroslav Brustinov            except KeyboardInterrupt:
1187823b8294SYaroslav Brustinov                raise
1188823b8294SYaroslav Brustinov            except:
1189823b8294SYaroslav Brustinov                exception = sys.exc_info()
1190823b8294SYaroslav Brustinov                self.debugger.set_continue() # ==== Example Finished ====
1191823b8294SYaroslav Brustinov
1192823b8294SYaroslav Brustinov            got = self._fakeout.getvalue()  # the actual output
1193823b8294SYaroslav Brustinov            self._fakeout.truncate(0)
1194823b8294SYaroslav Brustinov            outcome = FAILURE   # guilty until proved innocent or insane
1195823b8294SYaroslav Brustinov
1196823b8294SYaroslav Brustinov            # If the example executed without raising any exceptions,
1197823b8294SYaroslav Brustinov            # verify its output.
1198823b8294SYaroslav Brustinov            if exception is None:
1199823b8294SYaroslav Brustinov                if check(example.want, got, self.optionflags):
1200823b8294SYaroslav Brustinov                    outcome = SUCCESS
1201823b8294SYaroslav Brustinov
1202823b8294SYaroslav Brustinov            # The example raised an exception:  check if it was expected.
1203823b8294SYaroslav Brustinov            else:
1204823b8294SYaroslav Brustinov                exc_info = sys.exc_info()
1205823b8294SYaroslav Brustinov                exc_msg = traceback.format_exception_only(*exc_info[:2])[-1]
1206823b8294SYaroslav Brustinov                if not quiet:
1207823b8294SYaroslav Brustinov                    got += _exception_traceback(exc_info)
1208823b8294SYaroslav Brustinov
1209823b8294SYaroslav Brustinov                # If `example.exc_msg` is None, then we weren't expecting
1210823b8294SYaroslav Brustinov                # an exception.
1211823b8294SYaroslav Brustinov                if example.exc_msg is None:
1212823b8294SYaroslav Brustinov                    outcome = BOOM
1213823b8294SYaroslav Brustinov
1214823b8294SYaroslav Brustinov                # We expected an exception:  see whether it matches.
1215823b8294SYaroslav Brustinov                elif check(example.exc_msg, exc_msg, self.optionflags):
1216823b8294SYaroslav Brustinov                    outcome = SUCCESS
1217823b8294SYaroslav Brustinov
1218823b8294SYaroslav Brustinov                # Another chance if they didn't care about the detail.
1219823b8294SYaroslav Brustinov                elif self.optionflags & IGNORE_EXCEPTION_DETAIL:
1220823b8294SYaroslav Brustinov                    m1 = re.match(r'[^:]*:', example.exc_msg)
1221823b8294SYaroslav Brustinov                    m2 = re.match(r'[^:]*:', exc_msg)
1222823b8294SYaroslav Brustinov                    if m1 and m2 and check(m1.group(0), m2.group(0),
1223823b8294SYaroslav Brustinov                                           self.optionflags):
1224823b8294SYaroslav Brustinov                        outcome = SUCCESS
1225823b8294SYaroslav Brustinov
1226823b8294SYaroslav Brustinov            # Report the outcome.
1227823b8294SYaroslav Brustinov            if outcome is SUCCESS:
1228823b8294SYaroslav Brustinov                if not quiet:
1229823b8294SYaroslav Brustinov                    self.report_success(out, test, example, got)
1230823b8294SYaroslav Brustinov            elif outcome is FAILURE:
1231823b8294SYaroslav Brustinov                if not quiet:
1232823b8294SYaroslav Brustinov                    self.report_failure(out, test, example, got)
1233823b8294SYaroslav Brustinov                failures += 1
1234823b8294SYaroslav Brustinov            elif outcome is BOOM:
1235823b8294SYaroslav Brustinov                if not quiet:
1236823b8294SYaroslav Brustinov                    self.report_unexpected_exception(out, test, example,
1237823b8294SYaroslav Brustinov                                                     exc_info)
1238823b8294SYaroslav Brustinov                failures += 1
1239823b8294SYaroslav Brustinov            else:
1240823b8294SYaroslav Brustinov                assert False, ("unknown outcome", outcome)
1241823b8294SYaroslav Brustinov
1242823b8294SYaroslav Brustinov        # Restore the option flags (in case they were modified)
1243823b8294SYaroslav Brustinov        self.optionflags = original_optionflags
1244823b8294SYaroslav Brustinov
1245823b8294SYaroslav Brustinov        # Record and return the number of failures and tries.
1246823b8294SYaroslav Brustinov        self.__record_outcome(test, failures, tries)
1247823b8294SYaroslav Brustinov        return failures, tries
1248823b8294SYaroslav Brustinov
1249823b8294SYaroslav Brustinov    def __record_outcome(self, test, f, t):
1250823b8294SYaroslav Brustinov        """
1251823b8294SYaroslav Brustinov        Record the fact that the given DocTest (`test`) generated `f`
1252823b8294SYaroslav Brustinov        failures out of `t` tried examples.
1253823b8294SYaroslav Brustinov        """
1254823b8294SYaroslav Brustinov        f2, t2 = self._name2ft.get(test.name, (0,0))
1255823b8294SYaroslav Brustinov        self._name2ft[test.name] = (f+f2, t+t2)
1256823b8294SYaroslav Brustinov        self.failures += f
1257823b8294SYaroslav Brustinov        self.tries += t
1258823b8294SYaroslav Brustinov
1259823b8294SYaroslav Brustinov    __LINECACHE_FILENAME_RE = re.compile(r'<doctest '
1260823b8294SYaroslav Brustinov                                         r'(?P<name>[\w\.]+)'
1261823b8294SYaroslav Brustinov                                         r'\[(?P<examplenum>\d+)\]>$')
1262823b8294SYaroslav Brustinov    def __patched_linecache_getlines(self, filename):
1263823b8294SYaroslav Brustinov        m = self.__LINECACHE_FILENAME_RE.match(filename)
1264823b8294SYaroslav Brustinov        if m and m.group('name') == self.test.name:
1265823b8294SYaroslav Brustinov            example = self.test.examples[int(m.group('examplenum'))]
1266823b8294SYaroslav Brustinov            return example.source.splitlines(True)
1267823b8294SYaroslav Brustinov        else:
1268823b8294SYaroslav Brustinov            return self.save_linecache_getlines(filename)
1269823b8294SYaroslav Brustinov
1270823b8294SYaroslav Brustinov    def run(self, test, compileflags=None, out=None, clear_globs=True):
1271823b8294SYaroslav Brustinov        """
1272823b8294SYaroslav Brustinov        Run the examples in `test`, and display the results using the
1273823b8294SYaroslav Brustinov        writer function `out`.
1274823b8294SYaroslav Brustinov
1275823b8294SYaroslav Brustinov        The examples are run in the namespace `test.globs`.  If
1276823b8294SYaroslav Brustinov        `clear_globs` is true (the default), then this namespace will
1277823b8294SYaroslav Brustinov        be cleared after the test runs, to help with garbage
1278823b8294SYaroslav Brustinov        collection.  If you would like to examine the namespace after
1279823b8294SYaroslav Brustinov        the test completes, then use `clear_globs=False`.
1280823b8294SYaroslav Brustinov
1281823b8294SYaroslav Brustinov        `compileflags` gives the set of flags that should be used by
1282823b8294SYaroslav Brustinov        the Python compiler when running the examples.  If not
1283823b8294SYaroslav Brustinov        specified, then it will default to the set of future-import
1284823b8294SYaroslav Brustinov        flags that apply to `globs`.
1285823b8294SYaroslav Brustinov
1286823b8294SYaroslav Brustinov        The output of each example is checked using
1287823b8294SYaroslav Brustinov        `DocTestRunner.check_output`, and the results are formatted by
1288823b8294SYaroslav Brustinov        the `DocTestRunner.report_*` methods.
1289823b8294SYaroslav Brustinov        """
1290823b8294SYaroslav Brustinov        self.test = test
1291823b8294SYaroslav Brustinov
1292823b8294SYaroslav Brustinov        if compileflags is None:
1293823b8294SYaroslav Brustinov            compileflags = _extract_future_flags(test.globs)
1294823b8294SYaroslav Brustinov
1295823b8294SYaroslav Brustinov        save_stdout = sys.stdout
1296823b8294SYaroslav Brustinov        if out is None:
1297823b8294SYaroslav Brustinov            out = save_stdout.write
1298823b8294SYaroslav Brustinov        sys.stdout = self._fakeout
1299823b8294SYaroslav Brustinov
1300823b8294SYaroslav Brustinov        # Patch pdb.set_trace to restore sys.stdout during interactive
1301823b8294SYaroslav Brustinov        # debugging (so it's not still redirected to self._fakeout).
1302823b8294SYaroslav Brustinov        # Note that the interactive output will go to *our*
1303823b8294SYaroslav Brustinov        # save_stdout, even if that's not the real sys.stdout; this
1304823b8294SYaroslav Brustinov        # allows us to write test cases for the set_trace behavior.
1305823b8294SYaroslav Brustinov        save_set_trace = pdb.set_trace
1306823b8294SYaroslav Brustinov        self.debugger = _OutputRedirectingPdb(save_stdout)
1307823b8294SYaroslav Brustinov        self.debugger.reset()
1308823b8294SYaroslav Brustinov        pdb.set_trace = self.debugger.set_trace
1309823b8294SYaroslav Brustinov
1310823b8294SYaroslav Brustinov        # Patch linecache.getlines, so we can see the example's source
1311823b8294SYaroslav Brustinov        # when we're inside the debugger.
1312823b8294SYaroslav Brustinov        self.save_linecache_getlines = linecache.getlines
1313823b8294SYaroslav Brustinov        linecache.getlines = self.__patched_linecache_getlines
1314823b8294SYaroslav Brustinov
1315823b8294SYaroslav Brustinov        try:
1316823b8294SYaroslav Brustinov            return self.__run(test, compileflags, out)
1317823b8294SYaroslav Brustinov        finally:
1318823b8294SYaroslav Brustinov            sys.stdout = save_stdout
1319823b8294SYaroslav Brustinov            pdb.set_trace = save_set_trace
1320823b8294SYaroslav Brustinov            linecache.getlines = self.save_linecache_getlines
1321823b8294SYaroslav Brustinov            if clear_globs:
1322823b8294SYaroslav Brustinov                test.globs.clear()
1323823b8294SYaroslav Brustinov
1324823b8294SYaroslav Brustinov    #/////////////////////////////////////////////////////////////////
1325823b8294SYaroslav Brustinov    # Summarization
1326823b8294SYaroslav Brustinov    #/////////////////////////////////////////////////////////////////
1327823b8294SYaroslav Brustinov    def summarize(self, verbose=None):
1328823b8294SYaroslav Brustinov        """
1329823b8294SYaroslav Brustinov        Print a summary of all the test cases that have been run by
1330823b8294SYaroslav Brustinov        this DocTestRunner, and return a tuple `(f, t)`, where `f` is
1331823b8294SYaroslav Brustinov        the total number of failed examples, and `t` is the total
1332823b8294SYaroslav Brustinov        number of tried examples.
1333823b8294SYaroslav Brustinov
1334823b8294SYaroslav Brustinov        The optional `verbose` argument controls how detailed the
1335823b8294SYaroslav Brustinov        summary is.  If the verbosity is not specified, then the
1336823b8294SYaroslav Brustinov        DocTestRunner's verbosity is used.
1337823b8294SYaroslav Brustinov        """
1338823b8294SYaroslav Brustinov        if verbose is None:
1339823b8294SYaroslav Brustinov            verbose = self._verbose
1340823b8294SYaroslav Brustinov        notests = []
1341823b8294SYaroslav Brustinov        passed = []
1342823b8294SYaroslav Brustinov        failed = []
1343823b8294SYaroslav Brustinov        totalt = totalf = 0
1344823b8294SYaroslav Brustinov        for x in self._name2ft.items():
1345823b8294SYaroslav Brustinov            name, (f, t) = x
1346823b8294SYaroslav Brustinov            assert f <= t
1347823b8294SYaroslav Brustinov            totalt += t
1348823b8294SYaroslav Brustinov            totalf += f
1349823b8294SYaroslav Brustinov            if t == 0:
1350823b8294SYaroslav Brustinov                notests.append(name)
1351823b8294SYaroslav Brustinov            elif f == 0:
1352823b8294SYaroslav Brustinov                passed.append( (name, t) )
1353823b8294SYaroslav Brustinov            else:
1354823b8294SYaroslav Brustinov                failed.append(x)
1355823b8294SYaroslav Brustinov        if verbose:
1356823b8294SYaroslav Brustinov            if notests:
1357823b8294SYaroslav Brustinov                print len(notests), "items had no tests:"
1358823b8294SYaroslav Brustinov                notests.sort()
1359823b8294SYaroslav Brustinov                for thing in notests:
1360823b8294SYaroslav Brustinov                    print "   ", thing
1361823b8294SYaroslav Brustinov            if passed:
1362823b8294SYaroslav Brustinov                print len(passed), "items passed all tests:"
1363823b8294SYaroslav Brustinov                passed.sort()
1364823b8294SYaroslav Brustinov                for thing, count in passed:
1365823b8294SYaroslav Brustinov                    print " %3d tests in %s" % (count, thing)
1366823b8294SYaroslav Brustinov        if failed:
1367823b8294SYaroslav Brustinov            print self.DIVIDER
1368823b8294SYaroslav Brustinov            print len(failed), "items had failures:"
1369823b8294SYaroslav Brustinov            failed.sort()
1370823b8294SYaroslav Brustinov            for thing, (f, t) in failed:
1371823b8294SYaroslav Brustinov                print " %3d of %3d in %s" % (f, t, thing)
1372823b8294SYaroslav Brustinov        if verbose:
1373823b8294SYaroslav Brustinov            print totalt, "tests in", len(self._name2ft), "items."
1374823b8294SYaroslav Brustinov            print totalt - totalf, "passed and", totalf, "failed."
1375823b8294SYaroslav Brustinov        if totalf:
1376823b8294SYaroslav Brustinov            print "***Test Failed***", totalf, "failures."
1377823b8294SYaroslav Brustinov        elif verbose:
1378823b8294SYaroslav Brustinov            print "Test passed."
1379823b8294SYaroslav Brustinov        return totalf, totalt
1380823b8294SYaroslav Brustinov
1381823b8294SYaroslav Brustinov    #/////////////////////////////////////////////////////////////////
1382823b8294SYaroslav Brustinov    # Backward compatibility cruft to maintain doctest.master.
1383823b8294SYaroslav Brustinov    #/////////////////////////////////////////////////////////////////
1384823b8294SYaroslav Brustinov    def merge(self, other):
1385823b8294SYaroslav Brustinov        d = self._name2ft
1386823b8294SYaroslav Brustinov        for name, (f, t) in other._name2ft.items():
1387823b8294SYaroslav Brustinov            if name in d:
1388823b8294SYaroslav Brustinov                print "*** DocTestRunner.merge: '" + name + "' in both" \
1389823b8294SYaroslav Brustinov                    " testers; summing outcomes."
1390823b8294SYaroslav Brustinov                f2, t2 = d[name]
1391823b8294SYaroslav Brustinov                f = f + f2
1392823b8294SYaroslav Brustinov                t = t + t2
1393823b8294SYaroslav Brustinov            d[name] = f, t
1394823b8294SYaroslav Brustinov
1395823b8294SYaroslav Brustinovclass OutputChecker:
1396823b8294SYaroslav Brustinov    """
1397823b8294SYaroslav Brustinov    A class used to check the whether the actual output from a doctest
1398823b8294SYaroslav Brustinov    example matches the expected output.  `OutputChecker` defines two
1399823b8294SYaroslav Brustinov    methods: `check_output`, which compares a given pair of outputs,
1400823b8294SYaroslav Brustinov    and returns true if they match; and `output_difference`, which
1401823b8294SYaroslav Brustinov    returns a string describing the differences between two outputs.
1402823b8294SYaroslav Brustinov    """
1403823b8294SYaroslav Brustinov    def check_output(self, want, got, optionflags):
1404823b8294SYaroslav Brustinov        """
1405823b8294SYaroslav Brustinov        Return True iff the actual output from an example (`got`)
1406823b8294SYaroslav Brustinov        matches the expected output (`want`).  These strings are
1407823b8294SYaroslav Brustinov        always considered to match if they are identical; but
1408823b8294SYaroslav Brustinov        depending on what option flags the test runner is using,
1409823b8294SYaroslav Brustinov        several non-exact match types are also possible.  See the
1410823b8294SYaroslav Brustinov        documentation for `TestRunner` for more information about
1411823b8294SYaroslav Brustinov        option flags.
1412823b8294SYaroslav Brustinov        """
1413823b8294SYaroslav Brustinov        # Handle the common case first, for efficiency:
1414823b8294SYaroslav Brustinov        # if they're string-identical, always return true.
1415823b8294SYaroslav Brustinov        if got == want:
1416823b8294SYaroslav Brustinov            return True
1417823b8294SYaroslav Brustinov
1418823b8294SYaroslav Brustinov        # The values True and False replaced 1 and 0 as the return
1419823b8294SYaroslav Brustinov        # value for boolean comparisons in Python 2.3.
1420823b8294SYaroslav Brustinov        if not (optionflags & DONT_ACCEPT_TRUE_FOR_1):
1421823b8294SYaroslav Brustinov            if (got,want) == ("True\n", "1\n"):
1422823b8294SYaroslav Brustinov                return True
1423823b8294SYaroslav Brustinov            if (got,want) == ("False\n", "0\n"):
1424823b8294SYaroslav Brustinov                return True
1425823b8294SYaroslav Brustinov
1426823b8294SYaroslav Brustinov        # <BLANKLINE> can be used as a special sequence to signify a
1427823b8294SYaroslav Brustinov        # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used.
1428823b8294SYaroslav Brustinov        if not (optionflags & DONT_ACCEPT_BLANKLINE):
1429823b8294SYaroslav Brustinov            # Replace <BLANKLINE> in want with a blank line.
1430823b8294SYaroslav Brustinov            want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER),
1431823b8294SYaroslav Brustinov                          '', want)
1432823b8294SYaroslav Brustinov            # If a line in got contains only spaces, then remove the
1433823b8294SYaroslav Brustinov            # spaces.
1434823b8294SYaroslav Brustinov            got = re.sub('(?m)^\s*?$', '', got)
1435823b8294SYaroslav Brustinov            if got == want:
1436823b8294SYaroslav Brustinov                return True
1437823b8294SYaroslav Brustinov
1438823b8294SYaroslav Brustinov        # This flag causes doctest to ignore any differences in the
1439823b8294SYaroslav Brustinov        # contents of whitespace strings.  Note that this can be used
1440823b8294SYaroslav Brustinov        # in conjunction with the ELLIPSIS flag.
1441823b8294SYaroslav Brustinov        if optionflags & NORMALIZE_WHITESPACE:
1442823b8294SYaroslav Brustinov            got = ' '.join(got.split())
1443823b8294SYaroslav Brustinov            want = ' '.join(want.split())
1444823b8294SYaroslav Brustinov            if got == want:
1445823b8294SYaroslav Brustinov                return True
1446823b8294SYaroslav Brustinov
1447823b8294SYaroslav Brustinov        # The ELLIPSIS flag says to let the sequence "..." in `want`
1448823b8294SYaroslav Brustinov        # match any substring in `got`.
1449823b8294SYaroslav Brustinov        if optionflags & ELLIPSIS:
1450823b8294SYaroslav Brustinov            if _ellipsis_match(want, got):
1451823b8294SYaroslav Brustinov                return True
1452823b8294SYaroslav Brustinov
1453823b8294SYaroslav Brustinov        # We didn't find any match; return false.
1454823b8294SYaroslav Brustinov        return False
1455823b8294SYaroslav Brustinov
1456823b8294SYaroslav Brustinov    # Should we do a fancy diff?
1457823b8294SYaroslav Brustinov    def _do_a_fancy_diff(self, want, got, optionflags):
1458823b8294SYaroslav Brustinov        # Not unless they asked for a fancy diff.
1459823b8294SYaroslav Brustinov        if not optionflags & (REPORT_UDIFF |
1460823b8294SYaroslav Brustinov                              REPORT_CDIFF |
1461823b8294SYaroslav Brustinov                              REPORT_NDIFF):
1462823b8294SYaroslav Brustinov            return False
1463823b8294SYaroslav Brustinov
1464823b8294SYaroslav Brustinov        # If expected output uses ellipsis, a meaningful fancy diff is
1465823b8294SYaroslav Brustinov        # too hard ... or maybe not.  In two real-life failures Tim saw,
1466823b8294SYaroslav Brustinov        # a diff was a major help anyway, so this is commented out.
1467823b8294SYaroslav Brustinov        # [todo] _ellipsis_match() knows which pieces do and don't match,
1468823b8294SYaroslav Brustinov        # and could be the basis for a kick-ass diff in this case.
1469823b8294SYaroslav Brustinov        ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want:
1470823b8294SYaroslav Brustinov        ##    return False
1471823b8294SYaroslav Brustinov
1472823b8294SYaroslav Brustinov        # ndiff does intraline difference marking, so can be useful even
1473823b8294SYaroslav Brustinov        # for 1-line differences.
1474823b8294SYaroslav Brustinov        if optionflags & REPORT_NDIFF:
1475823b8294SYaroslav Brustinov            return True
1476823b8294SYaroslav Brustinov
1477823b8294SYaroslav Brustinov        # The other diff types need at least a few lines to be helpful.
1478823b8294SYaroslav Brustinov        return want.count('\n') > 2 and got.count('\n') > 2
1479823b8294SYaroslav Brustinov
1480823b8294SYaroslav Brustinov    def output_difference(self, example, got, optionflags):
1481823b8294SYaroslav Brustinov        """
1482823b8294SYaroslav Brustinov        Return a string describing the differences between the
1483823b8294SYaroslav Brustinov        expected output for a given example (`example`) and the actual
1484823b8294SYaroslav Brustinov        output (`got`).  `optionflags` is the set of option flags used
1485823b8294SYaroslav Brustinov        to compare `want` and `got`.
1486823b8294SYaroslav Brustinov        """
1487823b8294SYaroslav Brustinov        want = example.want
1488823b8294SYaroslav Brustinov        # If <BLANKLINE>s are being used, then replace blank lines
1489823b8294SYaroslav Brustinov        # with <BLANKLINE> in the actual output string.
1490823b8294SYaroslav Brustinov        if not (optionflags & DONT_ACCEPT_BLANKLINE):
1491823b8294SYaroslav Brustinov            got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got)
1492823b8294SYaroslav Brustinov
1493823b8294SYaroslav Brustinov        # Check if we should use diff.
1494823b8294SYaroslav Brustinov        if self._do_a_fancy_diff(want, got, optionflags):
1495823b8294SYaroslav Brustinov            # Split want & got into lines.
1496823b8294SYaroslav Brustinov            want_lines = want.splitlines(True)  # True == keep line ends
1497823b8294SYaroslav Brustinov            got_lines = got.splitlines(True)
1498823b8294SYaroslav Brustinov            # Use difflib to find their differences.
1499823b8294SYaroslav Brustinov            if optionflags & REPORT_UDIFF:
1500823b8294SYaroslav Brustinov                diff = difflib.unified_diff(want_lines, got_lines, n=2)
1501823b8294SYaroslav Brustinov                diff = list(diff)[2:] # strip the diff header
1502823b8294SYaroslav Brustinov                kind = 'unified diff with -expected +actual'
1503823b8294SYaroslav Brustinov            elif optionflags & REPORT_CDIFF:
1504823b8294SYaroslav Brustinov                diff = difflib.context_diff(want_lines, got_lines, n=2)
1505823b8294SYaroslav Brustinov                diff = list(diff)[2:] # strip the diff header
1506823b8294SYaroslav Brustinov                kind = 'context diff with expected followed by actual'
1507823b8294SYaroslav Brustinov            elif optionflags & REPORT_NDIFF:
1508823b8294SYaroslav Brustinov                engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
1509823b8294SYaroslav Brustinov                diff = list(engine.compare(want_lines, got_lines))
1510823b8294SYaroslav Brustinov                kind = 'ndiff with -expected +actual'
1511823b8294SYaroslav Brustinov            else:
1512823b8294SYaroslav Brustinov                assert 0, 'Bad diff option'
1513823b8294SYaroslav Brustinov            # Remove trailing whitespace on diff output.
1514823b8294SYaroslav Brustinov            diff = [line.rstrip() + '\n' for line in diff]
1515823b8294SYaroslav Brustinov            return 'Differences (%s):\n' % kind + _indent(''.join(diff))
1516823b8294SYaroslav Brustinov
1517823b8294SYaroslav Brustinov        # If we're not using diff, then simply list the expected
1518823b8294SYaroslav Brustinov        # output followed by the actual output.
1519823b8294SYaroslav Brustinov        if want and got:
1520823b8294SYaroslav Brustinov            return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got))
1521823b8294SYaroslav Brustinov        elif want:
1522823b8294SYaroslav Brustinov            return 'Expected:\n%sGot nothing\n' % _indent(want)
1523823b8294SYaroslav Brustinov        elif got:
1524823b8294SYaroslav Brustinov            return 'Expected nothing\nGot:\n%s' % _indent(got)
1525823b8294SYaroslav Brustinov        else:
1526823b8294SYaroslav Brustinov            return 'Expected nothing\nGot nothing\n'
1527823b8294SYaroslav Brustinov
1528823b8294SYaroslav Brustinovclass DocTestFailure(Exception):
1529823b8294SYaroslav Brustinov    """A DocTest example has failed in debugging mode.
1530823b8294SYaroslav Brustinov
1531823b8294SYaroslav Brustinov    The exception instance has variables:
1532823b8294SYaroslav Brustinov
1533823b8294SYaroslav Brustinov    - test: the DocTest object being run
1534823b8294SYaroslav Brustinov
1535823b8294SYaroslav Brustinov    - excample: the Example object that failed
1536823b8294SYaroslav Brustinov
1537823b8294SYaroslav Brustinov    - got: the actual output
1538823b8294SYaroslav Brustinov    """
1539823b8294SYaroslav Brustinov    def __init__(self, test, example, got):
1540823b8294SYaroslav Brustinov        self.test = test
1541823b8294SYaroslav Brustinov        self.example = example
1542823b8294SYaroslav Brustinov        self.got = got
1543823b8294SYaroslav Brustinov
1544823b8294SYaroslav Brustinov    def __str__(self):
1545823b8294SYaroslav Brustinov        return str(self.test)
1546823b8294SYaroslav Brustinov
1547823b8294SYaroslav Brustinovclass UnexpectedException(Exception):
1548823b8294SYaroslav Brustinov    """A DocTest example has encountered an unexpected exception
1549823b8294SYaroslav Brustinov
1550823b8294SYaroslav Brustinov    The exception instance has variables:
1551823b8294SYaroslav Brustinov
1552823b8294SYaroslav Brustinov    - test: the DocTest object being run
1553823b8294SYaroslav Brustinov
1554823b8294SYaroslav Brustinov    - excample: the Example object that failed
1555823b8294SYaroslav Brustinov
1556823b8294SYaroslav Brustinov    - exc_info: the exception info
1557823b8294SYaroslav Brustinov    """
1558823b8294SYaroslav Brustinov    def __init__(self, test, example, exc_info):
1559823b8294SYaroslav Brustinov        self.test = test
1560823b8294SYaroslav Brustinov        self.example = example
1561823b8294SYaroslav Brustinov        self.exc_info = exc_info
1562823b8294SYaroslav Brustinov
1563823b8294SYaroslav Brustinov    def __str__(self):
1564823b8294SYaroslav Brustinov        return str(self.test)
1565823b8294SYaroslav Brustinov
1566823b8294SYaroslav Brustinovclass DebugRunner(DocTestRunner):
1567823b8294SYaroslav Brustinov
1568823b8294SYaroslav Brustinov    def run(self, test, compileflags=None, out=None, clear_globs=True):
1569823b8294SYaroslav Brustinov        r = DocTestRunner.run(self, test, compileflags, out, False)
1570823b8294SYaroslav Brustinov        if clear_globs:
1571823b8294SYaroslav Brustinov            test.globs.clear()
1572823b8294SYaroslav Brustinov        return r
1573823b8294SYaroslav Brustinov
1574823b8294SYaroslav Brustinov    def report_unexpected_exception(self, out, test, example, exc_info):
1575823b8294SYaroslav Brustinov        raise UnexpectedException(test, example, exc_info)
1576823b8294SYaroslav Brustinov
1577823b8294SYaroslav Brustinov    def report_failure(self, out, test, example, got):
1578823b8294SYaroslav Brustinov        raise DocTestFailure(test, example, got)
1579823b8294SYaroslav Brustinov
1580823b8294SYaroslav Brustinov######################################################################
1581823b8294SYaroslav Brustinov## 6. Test Functions
1582823b8294SYaroslav Brustinov######################################################################
1583823b8294SYaroslav Brustinov# These should be backwards compatible.
1584823b8294SYaroslav Brustinov
1585823b8294SYaroslav Brustinov# For backward compatibility, a global instance of a DocTestRunner
1586823b8294SYaroslav Brustinov# class, updated by testmod.
1587823b8294SYaroslav Brustinovmaster = None
1588823b8294SYaroslav Brustinov
1589823b8294SYaroslav Brustinovdef testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
1590823b8294SYaroslav Brustinov            report=True, optionflags=0, extraglobs=None,
1591823b8294SYaroslav Brustinov            raise_on_error=False, exclude_empty=False):
1592823b8294SYaroslav Brustinov    """m=None, name=None, globs=None, verbose=None, isprivate=None,
1593823b8294SYaroslav Brustinov       report=True, optionflags=0, extraglobs=None, raise_on_error=False,
1594823b8294SYaroslav Brustinov       exclude_empty=False
1595823b8294SYaroslav Brustinov
1596823b8294SYaroslav Brustinov    Test examples in docstrings in functions and classes reachable
1597823b8294SYaroslav Brustinov    from module m (or the current module if m is not supplied), starting
1598823b8294SYaroslav Brustinov    with m.__doc__.  Unless isprivate is specified, private names
1599823b8294SYaroslav Brustinov    are not skipped.
1600823b8294SYaroslav Brustinov
1601823b8294SYaroslav Brustinov    Also test examples reachable from dict m.__test__ if it exists and is
1602823b8294SYaroslav Brustinov    not None.  m.__test__ maps names to functions, classes and strings;
1603823b8294SYaroslav Brustinov    function and class docstrings are tested even if the name is private;
1604823b8294SYaroslav Brustinov    strings are tested directly, as if they were docstrings.
1605823b8294SYaroslav Brustinov
1606823b8294SYaroslav Brustinov    Return (#failures, #tests).
1607823b8294SYaroslav Brustinov
1608823b8294SYaroslav Brustinov    See doctest.__doc__ for an overview.
1609823b8294SYaroslav Brustinov
1610823b8294SYaroslav Brustinov    Optional keyword arg "name" gives the name of the module; by default
1611823b8294SYaroslav Brustinov    use m.__name__.
1612823b8294SYaroslav Brustinov
1613823b8294SYaroslav Brustinov    Optional keyword arg "globs" gives a dict to be used as the globals
1614823b8294SYaroslav Brustinov    when executing examples; by default, use m.__dict__.  A copy of this
1615823b8294SYaroslav Brustinov    dict is actually used for each docstring, so that each docstring's
1616823b8294SYaroslav Brustinov    examples start with a clean slate.
1617823b8294SYaroslav Brustinov
1618823b8294SYaroslav Brustinov    Optional keyword arg "extraglobs" gives a dictionary that should be
1619823b8294SYaroslav Brustinov    merged into the globals that are used to execute examples.  By
1620823b8294SYaroslav Brustinov    default, no extra globals are used.  This is new in 2.4.
1621823b8294SYaroslav Brustinov
1622823b8294SYaroslav Brustinov    Optional keyword arg "verbose" prints lots of stuff if true, prints
1623823b8294SYaroslav Brustinov    only failures if false; by default, it's true iff "-v" is in sys.argv.
1624823b8294SYaroslav Brustinov
1625823b8294SYaroslav Brustinov    Optional keyword arg "report" prints a summary at the end when true,
1626823b8294SYaroslav Brustinov    else prints nothing at the end.  In verbose mode, the summary is
1627823b8294SYaroslav Brustinov    detailed, else very brief (in fact, empty if all tests passed).
1628823b8294SYaroslav Brustinov
1629823b8294SYaroslav Brustinov    Optional keyword arg "optionflags" or's together module constants,
1630823b8294SYaroslav Brustinov    and defaults to 0.  This is new in 2.3.  Possible values (see the
1631823b8294SYaroslav Brustinov    docs for details):
1632823b8294SYaroslav Brustinov
1633823b8294SYaroslav Brustinov        DONT_ACCEPT_TRUE_FOR_1
1634823b8294SYaroslav Brustinov        DONT_ACCEPT_BLANKLINE
1635823b8294SYaroslav Brustinov        NORMALIZE_WHITESPACE
1636823b8294SYaroslav Brustinov        ELLIPSIS
1637823b8294SYaroslav Brustinov        IGNORE_EXCEPTION_DETAIL
1638823b8294SYaroslav Brustinov        REPORT_UDIFF
1639823b8294SYaroslav Brustinov        REPORT_CDIFF
1640823b8294SYaroslav Brustinov        REPORT_NDIFF
1641823b8294SYaroslav Brustinov        REPORT_ONLY_FIRST_FAILURE
1642823b8294SYaroslav Brustinov
1643823b8294SYaroslav Brustinov    Optional keyword arg "raise_on_error" raises an exception on the
1644823b8294SYaroslav Brustinov    first unexpected exception or failure. This allows failures to be
1645823b8294SYaroslav Brustinov    post-mortem debugged.
1646823b8294SYaroslav Brustinov
1647823b8294SYaroslav Brustinov    Deprecated in Python 2.4:
1648823b8294SYaroslav Brustinov    Optional keyword arg "isprivate" specifies a function used to
1649823b8294SYaroslav Brustinov    determine whether a name is private.  The default function is
1650823b8294SYaroslav Brustinov    treat all functions as public.  Optionally, "isprivate" can be
1651823b8294SYaroslav Brustinov    set to doctest.is_private to skip over functions marked as private
1652823b8294SYaroslav Brustinov    using the underscore naming convention; see its docs for details.
1653823b8294SYaroslav Brustinov
1654823b8294SYaroslav Brustinov    Advanced tomfoolery:  testmod runs methods of a local instance of
1655823b8294SYaroslav Brustinov    class doctest.Tester, then merges the results into (or creates)
1656823b8294SYaroslav Brustinov    global Tester instance doctest.master.  Methods of doctest.master
1657823b8294SYaroslav Brustinov    can be called directly too, if you want to do something unusual.
1658823b8294SYaroslav Brustinov    Passing report=0 to testmod is especially useful then, to delay
1659823b8294SYaroslav Brustinov    displaying a summary.  Invoke doctest.master.summarize(verbose)
1660823b8294SYaroslav Brustinov    when you're done fiddling.
1661823b8294SYaroslav Brustinov    """
1662823b8294SYaroslav Brustinov    global master
1663823b8294SYaroslav Brustinov
1664823b8294SYaroslav Brustinov    if isprivate is not None:
1665823b8294SYaroslav Brustinov        warnings.warn("the isprivate argument is deprecated; "
1666823b8294SYaroslav Brustinov                      "examine DocTestFinder.find() lists instead",
1667823b8294SYaroslav Brustinov                      DeprecationWarning)
1668823b8294SYaroslav Brustinov
1669823b8294SYaroslav Brustinov    # If no module was given, then use __main__.
1670823b8294SYaroslav Brustinov    if m is None:
1671823b8294SYaroslav Brustinov        # DWA - m will still be None if this wasn't invoked from the command
1672823b8294SYaroslav Brustinov        # line, in which case the following TypeError is about as good an error
1673823b8294SYaroslav Brustinov        # as we should expect
1674823b8294SYaroslav Brustinov        m = sys.modules.get('__main__')
1675823b8294SYaroslav Brustinov
1676823b8294SYaroslav Brustinov    # Check that we were actually given a module.
1677823b8294SYaroslav Brustinov    if not inspect.ismodule(m):
1678823b8294SYaroslav Brustinov        raise TypeError("testmod: module required; %r" % (m,))
1679823b8294SYaroslav Brustinov
1680823b8294SYaroslav Brustinov    # If no name was given, then use the module's name.
1681823b8294SYaroslav Brustinov    if name is None:
1682823b8294SYaroslav Brustinov        name = m.__name__
1683823b8294SYaroslav Brustinov
1684823b8294SYaroslav Brustinov    # Find, parse, and run all tests in the given module.
1685823b8294SYaroslav Brustinov    finder = DocTestFinder(_namefilter=isprivate, exclude_empty=exclude_empty)
1686823b8294SYaroslav Brustinov
1687823b8294SYaroslav Brustinov    if raise_on_error:
1688823b8294SYaroslav Brustinov        runner = DebugRunner(verbose=verbose, optionflags=optionflags)
1689823b8294SYaroslav Brustinov    else:
1690823b8294SYaroslav Brustinov        runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
1691823b8294SYaroslav Brustinov
1692823b8294SYaroslav Brustinov    for test in finder.find(m, name, globs=globs, extraglobs=extraglobs):
1693823b8294SYaroslav Brustinov        runner.run(test)
1694823b8294SYaroslav Brustinov
1695823b8294SYaroslav Brustinov    if report:
1696823b8294SYaroslav Brustinov        runner.summarize()
1697823b8294SYaroslav Brustinov
1698823b8294SYaroslav Brustinov    if master is None:
1699823b8294SYaroslav Brustinov        master = runner
1700823b8294SYaroslav Brustinov    else:
1701823b8294SYaroslav Brustinov        master.merge(runner)
1702823b8294SYaroslav Brustinov
1703823b8294SYaroslav Brustinov    return runner.failures, runner.tries
1704823b8294SYaroslav Brustinov
1705823b8294SYaroslav Brustinovdef testfile(filename, module_relative=True, name=None, package=None,
1706823b8294SYaroslav Brustinov             globs=None, verbose=None, report=True, optionflags=0,
1707823b8294SYaroslav Brustinov             extraglobs=None, raise_on_error=False, parser=DocTestParser()):
1708823b8294SYaroslav Brustinov    """
1709823b8294SYaroslav Brustinov    Test examples in the given file.  Return (#failures, #tests).
1710823b8294SYaroslav Brustinov
1711823b8294SYaroslav Brustinov    Optional keyword arg "module_relative" specifies how filenames
1712823b8294SYaroslav Brustinov    should be interpreted:
1713823b8294SYaroslav Brustinov
1714823b8294SYaroslav Brustinov      - If "module_relative" is True (the default), then "filename"
1715823b8294SYaroslav Brustinov         specifies a module-relative path.  By default, this path is
1716823b8294SYaroslav Brustinov         relative to the calling module's directory; but if the
1717823b8294SYaroslav Brustinov         "package" argument is specified, then it is relative to that
1718823b8294SYaroslav Brustinov         package.  To ensure os-independence, "filename" should use
1719823b8294SYaroslav Brustinov         "/" characters to separate path segments, and should not
1720823b8294SYaroslav Brustinov         be an absolute path (i.e., it may not begin with "/").
1721823b8294SYaroslav Brustinov
1722823b8294SYaroslav Brustinov      - If "module_relative" is False, then "filename" specifies an
1723823b8294SYaroslav Brustinov        os-specific path.  The path may be absolute or relative (to
1724823b8294SYaroslav Brustinov        the current working directory).
1725823b8294SYaroslav Brustinov
1726823b8294SYaroslav Brustinov    Optional keyword arg "name" gives the name of the test; by default
1727823b8294SYaroslav Brustinov    use the file's basename.
1728823b8294SYaroslav Brustinov
1729823b8294SYaroslav Brustinov    Optional keyword argument "package" is a Python package or the
1730823b8294SYaroslav Brustinov    name of a Python package whose directory should be used as the
1731823b8294SYaroslav Brustinov    base directory for a module relative filename.  If no package is
1732823b8294SYaroslav Brustinov    specified, then the calling module's directory is used as the base
1733823b8294SYaroslav Brustinov    directory for module relative filenames.  It is an error to
1734823b8294SYaroslav Brustinov    specify "package" if "module_relative" is False.
1735823b8294SYaroslav Brustinov
1736823b8294SYaroslav Brustinov    Optional keyword arg "globs" gives a dict to be used as the globals
1737823b8294SYaroslav Brustinov    when executing examples; by default, use {}.  A copy of this dict
1738823b8294SYaroslav Brustinov    is actually used for each docstring, so that each docstring's
1739823b8294SYaroslav Brustinov    examples start with a clean slate.
1740823b8294SYaroslav Brustinov
1741823b8294SYaroslav Brustinov    Optional keyword arg "extraglobs" gives a dictionary that should be
1742823b8294SYaroslav Brustinov    merged into the globals that are used to execute examples.  By
1743823b8294SYaroslav Brustinov    default, no extra globals are used.
1744823b8294SYaroslav Brustinov
1745823b8294SYaroslav Brustinov    Optional keyword arg "verbose" prints lots of stuff if true, prints
1746823b8294SYaroslav Brustinov    only failures if false; by default, it's true iff "-v" is in sys.argv.
1747823b8294SYaroslav Brustinov
1748823b8294SYaroslav Brustinov    Optional keyword arg "report" prints a summary at the end when true,
1749823b8294SYaroslav Brustinov    else prints nothing at the end.  In verbose mode, the summary is
1750823b8294SYaroslav Brustinov    detailed, else very brief (in fact, empty if all tests passed).
1751823b8294SYaroslav Brustinov
1752823b8294SYaroslav Brustinov    Optional keyword arg "optionflags" or's together module constants,
1753823b8294SYaroslav Brustinov    and defaults to 0.  Possible values (see the docs for details):
1754823b8294SYaroslav Brustinov
1755823b8294SYaroslav Brustinov        DONT_ACCEPT_TRUE_FOR_1
1756823b8294SYaroslav Brustinov        DONT_ACCEPT_BLANKLINE
1757823b8294SYaroslav Brustinov        NORMALIZE_WHITESPACE
1758823b8294SYaroslav Brustinov        ELLIPSIS
1759823b8294SYaroslav Brustinov        IGNORE_EXCEPTION_DETAIL
1760823b8294SYaroslav Brustinov        REPORT_UDIFF
1761823b8294SYaroslav Brustinov        REPORT_CDIFF
1762823b8294SYaroslav Brustinov        REPORT_NDIFF
1763823b8294SYaroslav Brustinov        REPORT_ONLY_FIRST_FAILURE
1764823b8294SYaroslav Brustinov
1765823b8294SYaroslav Brustinov    Optional keyword arg "raise_on_error" raises an exception on the
1766823b8294SYaroslav Brustinov    first unexpected exception or failure. This allows failures to be
1767823b8294SYaroslav Brustinov    post-mortem debugged.
1768823b8294SYaroslav Brustinov
1769823b8294SYaroslav Brustinov    Optional keyword arg "parser" specifies a DocTestParser (or
1770823b8294SYaroslav Brustinov    subclass) that should be used to extract tests from the files.
1771823b8294SYaroslav Brustinov
1772823b8294SYaroslav Brustinov    Advanced tomfoolery:  testmod runs methods of a local instance of
1773823b8294SYaroslav Brustinov    class doctest.Tester, then merges the results into (or creates)
1774823b8294SYaroslav Brustinov    global Tester instance doctest.master.  Methods of doctest.master
1775823b8294SYaroslav Brustinov    can be called directly too, if you want to do something unusual.
1776823b8294SYaroslav Brustinov    Passing report=0 to testmod is especially useful then, to delay
1777823b8294SYaroslav Brustinov    displaying a summary.  Invoke doctest.master.summarize(verbose)
1778823b8294SYaroslav Brustinov    when you're done fiddling.
1779823b8294SYaroslav Brustinov    """
1780823b8294SYaroslav Brustinov    global master
1781823b8294SYaroslav Brustinov
1782823b8294SYaroslav Brustinov    if package and not module_relative:
1783823b8294SYaroslav Brustinov        raise ValueError("Package may only be specified for module-"
1784823b8294SYaroslav Brustinov                         "relative paths.")
1785823b8294SYaroslav Brustinov
1786823b8294SYaroslav Brustinov    # Relativize the path
1787823b8294SYaroslav Brustinov    if module_relative:
1788823b8294SYaroslav Brustinov        package = _normalize_module(package)
1789823b8294SYaroslav Brustinov        filename = _module_relative_path(package, filename)
1790823b8294SYaroslav Brustinov
1791823b8294SYaroslav Brustinov    # If no name was given, then use the file's name.
1792823b8294SYaroslav Brustinov    if name is None:
1793823b8294SYaroslav Brustinov        name = os.path.basename(filename)
1794823b8294SYaroslav Brustinov
1795823b8294SYaroslav Brustinov    # Assemble the globals.
1796823b8294SYaroslav Brustinov    if globs is None:
1797823b8294SYaroslav Brustinov        globs = {}
1798823b8294SYaroslav Brustinov    else:
1799823b8294SYaroslav Brustinov        globs = globs.copy()
1800823b8294SYaroslav Brustinov    if extraglobs is not None:
1801823b8294SYaroslav Brustinov        globs.update(extraglobs)
1802823b8294SYaroslav Brustinov
1803823b8294SYaroslav Brustinov    if raise_on_error:
1804823b8294SYaroslav Brustinov        runner = DebugRunner(verbose=verbose, optionflags=optionflags)
1805823b8294SYaroslav Brustinov    else:
1806823b8294SYaroslav Brustinov        runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
1807823b8294SYaroslav Brustinov
1808823b8294SYaroslav Brustinov    # Read the file, convert it to a test, and run it.
1809823b8294SYaroslav Brustinov    s = open(filename).read()
1810823b8294SYaroslav Brustinov    test = parser.get_doctest(s, globs, name, filename, 0)
1811823b8294SYaroslav Brustinov    runner.run(test)
1812823b8294SYaroslav Brustinov
1813823b8294SYaroslav Brustinov    if report:
1814823b8294SYaroslav Brustinov        runner.summarize()
1815823b8294SYaroslav Brustinov
1816823b8294SYaroslav Brustinov    if master is None:
1817823b8294SYaroslav Brustinov        master = runner
1818823b8294SYaroslav Brustinov    else:
1819823b8294SYaroslav Brustinov        master.merge(runner)
1820823b8294SYaroslav Brustinov
1821823b8294SYaroslav Brustinov    return runner.failures, runner.tries
1822823b8294SYaroslav Brustinov
1823823b8294SYaroslav Brustinovdef run_docstring_examples(f, globs, verbose=False, name="NoName",
1824823b8294SYaroslav Brustinov                           compileflags=None, optionflags=0):
1825823b8294SYaroslav Brustinov    """
1826823b8294SYaroslav Brustinov    Test examples in the given object's docstring (`f`), using `globs`
1827823b8294SYaroslav Brustinov    as globals.  Optional argument `name` is used in failure messages.
1828823b8294SYaroslav Brustinov    If the optional argument `verbose` is true, then generate output
1829823b8294SYaroslav Brustinov    even if there are no failures.
1830823b8294SYaroslav Brustinov
1831823b8294SYaroslav Brustinov    `compileflags` gives the set of flags that should be used by the
1832823b8294SYaroslav Brustinov    Python compiler when running the examples.  If not specified, then
1833823b8294SYaroslav Brustinov    it will default to the set of future-import flags that apply to
1834823b8294SYaroslav Brustinov    `globs`.
1835823b8294SYaroslav Brustinov
1836823b8294SYaroslav Brustinov    Optional keyword arg `optionflags` specifies options for the
1837823b8294SYaroslav Brustinov    testing and output.  See the documentation for `testmod` for more
1838823b8294SYaroslav Brustinov    information.
1839823b8294SYaroslav Brustinov    """
1840823b8294SYaroslav Brustinov    # Find, parse, and run all tests in the given module.
1841823b8294SYaroslav Brustinov    finder = DocTestFinder(verbose=verbose, recurse=False)
1842823b8294SYaroslav Brustinov    runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
1843823b8294SYaroslav Brustinov    for test in finder.find(f, name, globs=globs):
1844823b8294SYaroslav Brustinov        runner.run(test, compileflags=compileflags)
1845823b8294SYaroslav Brustinov
1846823b8294SYaroslav Brustinov######################################################################
1847823b8294SYaroslav Brustinov## 7. Tester
1848823b8294SYaroslav Brustinov######################################################################
1849823b8294SYaroslav Brustinov# This is provided only for backwards compatibility.  It's not
1850823b8294SYaroslav Brustinov# actually used in any way.
1851823b8294SYaroslav Brustinov
1852823b8294SYaroslav Brustinovclass Tester:
1853823b8294SYaroslav Brustinov    def __init__(self, mod=None, globs=None, verbose=None,
1854823b8294SYaroslav Brustinov                 isprivate=None, optionflags=0):
1855823b8294SYaroslav Brustinov
1856823b8294SYaroslav Brustinov        warnings.warn("class Tester is deprecated; "
1857823b8294SYaroslav Brustinov                      "use class doctest.DocTestRunner instead",
1858823b8294SYaroslav Brustinov                      DeprecationWarning, stacklevel=2)
1859823b8294SYaroslav Brustinov        if mod is None and globs is None:
1860823b8294SYaroslav Brustinov            raise TypeError("Tester.__init__: must specify mod or globs")
1861823b8294SYaroslav Brustinov        if mod is not None and not inspect.ismodule(mod):
1862823b8294SYaroslav Brustinov            raise TypeError("Tester.__init__: mod must be a module; %r" %
1863823b8294SYaroslav Brustinov                            (mod,))
1864823b8294SYaroslav Brustinov        if globs is None:
1865823b8294SYaroslav Brustinov            globs = mod.__dict__
1866823b8294SYaroslav Brustinov        self.globs = globs
1867823b8294SYaroslav Brustinov
1868823b8294SYaroslav Brustinov        self.verbose = verbose
1869823b8294SYaroslav Brustinov        self.isprivate = isprivate
1870823b8294SYaroslav Brustinov        self.optionflags = optionflags
1871823b8294SYaroslav Brustinov        self.testfinder = DocTestFinder(_namefilter=isprivate)
1872823b8294SYaroslav Brustinov        self.testrunner = DocTestRunner(verbose=verbose,
1873823b8294SYaroslav Brustinov                                        optionflags=optionflags)
1874823b8294SYaroslav Brustinov
1875823b8294SYaroslav Brustinov    def runstring(self, s, name):
1876823b8294SYaroslav Brustinov        test = DocTestParser().get_doctest(s, self.globs, name, None, None)
1877823b8294SYaroslav Brustinov        if self.verbose:
1878823b8294SYaroslav Brustinov            print "Running string", name
1879823b8294SYaroslav Brustinov        (f,t) = self.testrunner.run(test)
1880823b8294SYaroslav Brustinov        if self.verbose:
1881823b8294SYaroslav Brustinov            print f, "of", t, "examples failed in string", name
1882823b8294SYaroslav Brustinov        return (f,t)
1883823b8294SYaroslav Brustinov
1884823b8294SYaroslav Brustinov    def rundoc(self, object, name=None, module=None):
1885823b8294SYaroslav Brustinov        f = t = 0
1886823b8294SYaroslav Brustinov        tests = self.testfinder.find(object, name, module=module,
1887823b8294SYaroslav Brustinov                                     globs=self.globs)
1888823b8294SYaroslav Brustinov        for test in tests:
1889823b8294SYaroslav Brustinov            (f2, t2) = self.testrunner.run(test)
1890823b8294SYaroslav Brustinov            (f,t) = (f+f2, t+t2)
1891823b8294SYaroslav Brustinov        return (f,t)
1892823b8294SYaroslav Brustinov
1893823b8294SYaroslav Brustinov    def rundict(self, d, name, module=None):
1894823b8294SYaroslav Brustinov        import new
1895823b8294SYaroslav Brustinov        m = new.module(name)
1896823b8294SYaroslav Brustinov        m.__dict__.update(d)
1897823b8294SYaroslav Brustinov        if module is None:
1898823b8294SYaroslav Brustinov            module = False
1899823b8294SYaroslav Brustinov        return self.rundoc(m, name, module)
1900823b8294SYaroslav Brustinov
1901823b8294SYaroslav Brustinov    def run__test__(self, d, name):
1902823b8294SYaroslav Brustinov        import new
1903823b8294SYaroslav Brustinov        m = new.module(name)
1904823b8294SYaroslav Brustinov        m.__test__ = d
1905823b8294SYaroslav Brustinov        return self.rundoc(m, name)
1906823b8294SYaroslav Brustinov
1907823b8294SYaroslav Brustinov    def summarize(self, verbose=None):
1908823b8294SYaroslav Brustinov        return self.testrunner.summarize(verbose)
1909823b8294SYaroslav Brustinov
1910823b8294SYaroslav Brustinov    def merge(self, other):
1911823b8294SYaroslav Brustinov        self.testrunner.merge(other.testrunner)
1912823b8294SYaroslav Brustinov
1913823b8294SYaroslav Brustinov######################################################################
1914823b8294SYaroslav Brustinov## 8. Unittest Support
1915823b8294SYaroslav Brustinov######################################################################
1916823b8294SYaroslav Brustinov
1917823b8294SYaroslav Brustinov_unittest_reportflags = 0
1918823b8294SYaroslav Brustinov
1919823b8294SYaroslav Brustinovdef set_unittest_reportflags(flags):
1920823b8294SYaroslav Brustinov    global _unittest_reportflags
1921823b8294SYaroslav Brustinov
1922823b8294SYaroslav Brustinov    if (flags & REPORTING_FLAGS) != flags:
1923823b8294SYaroslav Brustinov        raise ValueError("Only reporting flags allowed", flags)
1924823b8294SYaroslav Brustinov    old = _unittest_reportflags
1925823b8294SYaroslav Brustinov    _unittest_reportflags = flags
1926823b8294SYaroslav Brustinov    return old
1927823b8294SYaroslav Brustinov
1928823b8294SYaroslav Brustinov
1929823b8294SYaroslav Brustinovclass DocTestCase(unittest.TestCase):
1930823b8294SYaroslav Brustinov
1931823b8294SYaroslav Brustinov    def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
1932823b8294SYaroslav Brustinov                 checker=None):
1933823b8294SYaroslav Brustinov
1934823b8294SYaroslav Brustinov        unittest.TestCase.__init__(self)
1935823b8294SYaroslav Brustinov        self._dt_optionflags = optionflags
1936823b8294SYaroslav Brustinov        self._dt_checker = checker
1937823b8294SYaroslav Brustinov        self._dt_test = test
1938823b8294SYaroslav Brustinov        self._dt_setUp = setUp
1939823b8294SYaroslav Brustinov        self._dt_tearDown = tearDown
1940823b8294SYaroslav Brustinov
1941823b8294SYaroslav Brustinov    def setUp(self):
1942823b8294SYaroslav Brustinov        test = self._dt_test
1943823b8294SYaroslav Brustinov
1944823b8294SYaroslav Brustinov        if self._dt_setUp is not None:
1945823b8294SYaroslav Brustinov            self._dt_setUp(test)
1946823b8294SYaroslav Brustinov
1947823b8294SYaroslav Brustinov    def tearDown(self):
1948823b8294SYaroslav Brustinov        test = self._dt_test
1949823b8294SYaroslav Brustinov
1950823b8294SYaroslav Brustinov        if self._dt_tearDown is not None:
1951823b8294SYaroslav Brustinov            self._dt_tearDown(test)
1952823b8294SYaroslav Brustinov
1953823b8294SYaroslav Brustinov        test.globs.clear()
1954823b8294SYaroslav Brustinov
1955823b8294SYaroslav Brustinov    def runTest(self):
1956823b8294SYaroslav Brustinov        test = self._dt_test
1957823b8294SYaroslav Brustinov        old = sys.stdout
1958823b8294SYaroslav Brustinov        new = StringIO()
1959823b8294SYaroslav Brustinov        optionflags = self._dt_optionflags
1960823b8294SYaroslav Brustinov
1961823b8294SYaroslav Brustinov        if not (optionflags & REPORTING_FLAGS):
1962823b8294SYaroslav Brustinov            # The option flags don't include any reporting flags,
1963823b8294SYaroslav Brustinov            # so add the default reporting flags
1964823b8294SYaroslav Brustinov            optionflags |= _unittest_reportflags
1965823b8294SYaroslav Brustinov
1966823b8294SYaroslav Brustinov        runner = DocTestRunner(optionflags=optionflags,
1967823b8294SYaroslav Brustinov                               checker=self._dt_checker, verbose=False)
1968823b8294SYaroslav Brustinov
1969823b8294SYaroslav Brustinov        try:
1970823b8294SYaroslav Brustinov            runner.DIVIDER = "-"*70
1971823b8294SYaroslav Brustinov            failures, tries = runner.run(
1972823b8294SYaroslav Brustinov                test, out=new.write, clear_globs=False)
1973823b8294SYaroslav Brustinov        finally:
1974823b8294SYaroslav Brustinov            sys.stdout = old
1975823b8294SYaroslav Brustinov
1976823b8294SYaroslav Brustinov        if failures:
1977823b8294SYaroslav Brustinov            raise self.failureException(self.format_failure(new.getvalue()))
1978823b8294SYaroslav Brustinov
1979823b8294SYaroslav Brustinov    def format_failure(self, err):
1980823b8294SYaroslav Brustinov        test = self._dt_test
1981823b8294SYaroslav Brustinov        if test.lineno is None:
1982823b8294SYaroslav Brustinov            lineno = 'unknown line number'
1983823b8294SYaroslav Brustinov        else:
1984823b8294SYaroslav Brustinov            lineno = '%s' % test.lineno
1985823b8294SYaroslav Brustinov        lname = '.'.join(test.name.split('.')[-1:])
1986823b8294SYaroslav Brustinov        return ('Failed doctest test for %s\n'
1987823b8294SYaroslav Brustinov                '  File "%s", line %s, in %s\n\n%s'
1988823b8294SYaroslav Brustinov                % (test.name, test.filename, lineno, lname, err)
1989823b8294SYaroslav Brustinov                )
1990823b8294SYaroslav Brustinov
1991823b8294SYaroslav Brustinov    def debug(self):
1992823b8294SYaroslav Brustinov        self.setUp()
1993823b8294SYaroslav Brustinov        runner = DebugRunner(optionflags=self._dt_optionflags,
1994823b8294SYaroslav Brustinov                             checker=self._dt_checker, verbose=False)
1995823b8294SYaroslav Brustinov        runner.run(self._dt_test)
1996823b8294SYaroslav Brustinov        self.tearDown()
1997823b8294SYaroslav Brustinov
1998823b8294SYaroslav Brustinov    def id(self):
1999823b8294SYaroslav Brustinov        return self._dt_test.name
2000823b8294SYaroslav Brustinov
2001823b8294SYaroslav Brustinov    def __repr__(self):
2002823b8294SYaroslav Brustinov        name = self._dt_test.name.split('.')
2003823b8294SYaroslav Brustinov        return "%s (%s)" % (name[-1], '.'.join(name[:-1]))
2004823b8294SYaroslav Brustinov
2005823b8294SYaroslav Brustinov    __str__ = __repr__
2006823b8294SYaroslav Brustinov
2007823b8294SYaroslav Brustinov    def shortDescription(self):
2008823b8294SYaroslav Brustinov        return "Doctest: " + self._dt_test.name
2009823b8294SYaroslav Brustinov
2010823b8294SYaroslav Brustinovdef DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None,
2011823b8294SYaroslav Brustinov                 **options):
2012823b8294SYaroslav Brustinov    """
2013823b8294SYaroslav Brustinov    Convert doctest tests for a module to a unittest test suite.
2014823b8294SYaroslav Brustinov
2015823b8294SYaroslav Brustinov    This converts each documentation string in a module that
2016823b8294SYaroslav Brustinov    contains doctest tests to a unittest test case.  If any of the
2017823b8294SYaroslav Brustinov    tests in a doc string fail, then the test case fails.  An exception
2018823b8294SYaroslav Brustinov    is raised showing the name of the file containing the test and a
2019823b8294SYaroslav Brustinov    (sometimes approximate) line number.
2020823b8294SYaroslav Brustinov
2021823b8294SYaroslav Brustinov    The `module` argument provides the module to be tested.  The argument
2022823b8294SYaroslav Brustinov    can be either a module or a module name.
2023823b8294SYaroslav Brustinov
2024823b8294SYaroslav Brustinov    If no argument is given, the calling module is used.
2025823b8294SYaroslav Brustinov
2026823b8294SYaroslav Brustinov    A number of options may be provided as keyword arguments:
2027823b8294SYaroslav Brustinov
2028823b8294SYaroslav Brustinov    setUp
2029823b8294SYaroslav Brustinov      A set-up function.  This is called before running the
2030823b8294SYaroslav Brustinov      tests in each file. The setUp function will be passed a DocTest
2031823b8294SYaroslav Brustinov      object.  The setUp function can access the test globals as the
2032823b8294SYaroslav Brustinov      globs attribute of the test passed.
2033823b8294SYaroslav Brustinov
2034823b8294SYaroslav Brustinov    tearDown
2035823b8294SYaroslav Brustinov      A tear-down function.  This is called after running the
2036823b8294SYaroslav Brustinov      tests in each file.  The tearDown function will be passed a DocTest
2037823b8294SYaroslav Brustinov      object.  The tearDown function can access the test globals as the
2038823b8294SYaroslav Brustinov      globs attribute of the test passed.
2039823b8294SYaroslav Brustinov
2040823b8294SYaroslav Brustinov    globs
2041823b8294SYaroslav Brustinov      A dictionary containing initial global variables for the tests.
2042823b8294SYaroslav Brustinov
2043823b8294SYaroslav Brustinov    optionflags
2044823b8294SYaroslav Brustinov       A set of doctest option flags expressed as an integer.
2045823b8294SYaroslav Brustinov    """
2046823b8294SYaroslav Brustinov
2047823b8294SYaroslav Brustinov    if test_finder is None:
2048823b8294SYaroslav Brustinov        test_finder = DocTestFinder()
2049823b8294SYaroslav Brustinov
2050823b8294SYaroslav Brustinov    module = _normalize_module(module)
2051823b8294SYaroslav Brustinov    tests = test_finder.find(module, globs=globs, extraglobs=extraglobs)
2052823b8294SYaroslav Brustinov    if globs is None:
2053823b8294SYaroslav Brustinov        globs = module.__dict__
2054823b8294SYaroslav Brustinov    if not tests:
2055823b8294SYaroslav Brustinov        # Why do we want to do this? Because it reveals a bug that might
2056823b8294SYaroslav Brustinov        # otherwise be hidden.
2057823b8294SYaroslav Brustinov        raise ValueError(module, "has no tests")
2058823b8294SYaroslav Brustinov
2059823b8294SYaroslav Brustinov    tests.sort()
2060823b8294SYaroslav Brustinov    suite = unittest.TestSuite()
2061823b8294SYaroslav Brustinov    for test in tests:
2062823b8294SYaroslav Brustinov        if len(test.examples) == 0:
2063823b8294SYaroslav Brustinov            continue
2064823b8294SYaroslav Brustinov        if not test.filename:
2065823b8294SYaroslav Brustinov            filename = module.__file__
2066823b8294SYaroslav Brustinov            if filename[-4:] in (".pyc", ".pyo"):
2067823b8294SYaroslav Brustinov                filename = filename[:-1]
2068823b8294SYaroslav Brustinov            elif sys.platform.startswith('java') and \
2069823b8294SYaroslav Brustinov                    filename.endswith('$py.class'):
2070823b8294SYaroslav Brustinov                filename = '%s.py' % filename[:-9]
2071823b8294SYaroslav Brustinov            test.filename = filename
2072823b8294SYaroslav Brustinov        suite.addTest(DocTestCase(test, **options))
2073823b8294SYaroslav Brustinov
2074823b8294SYaroslav Brustinov    return suite
2075823b8294SYaroslav Brustinov
2076823b8294SYaroslav Brustinovclass DocFileCase(DocTestCase):
2077823b8294SYaroslav Brustinov
2078823b8294SYaroslav Brustinov    def id(self):
2079823b8294SYaroslav Brustinov        return '_'.join(self._dt_test.name.split('.'))
2080823b8294SYaroslav Brustinov
2081823b8294SYaroslav Brustinov    def __repr__(self):
2082823b8294SYaroslav Brustinov        return self._dt_test.filename
2083823b8294SYaroslav Brustinov    __str__ = __repr__
2084823b8294SYaroslav Brustinov
2085823b8294SYaroslav Brustinov    def format_failure(self, err):
2086823b8294SYaroslav Brustinov        return ('Failed doctest test for %s\n  File "%s", line 0\n\n%s'
2087823b8294SYaroslav Brustinov                % (self._dt_test.name, self._dt_test.filename, err)
2088823b8294SYaroslav Brustinov                )
2089823b8294SYaroslav Brustinov
2090823b8294SYaroslav Brustinovdef DocFileTest(path, module_relative=True, package=None,
2091823b8294SYaroslav Brustinov                globs=None, parser=DocTestParser(), **options):
2092823b8294SYaroslav Brustinov    if globs is None:
2093823b8294SYaroslav Brustinov        globs = {}
2094823b8294SYaroslav Brustinov
2095823b8294SYaroslav Brustinov    if package and not module_relative:
2096823b8294SYaroslav Brustinov        raise ValueError("Package may only be specified for module-"
2097823b8294SYaroslav Brustinov                         "relative paths.")
2098823b8294SYaroslav Brustinov
2099823b8294SYaroslav Brustinov    # Relativize the path.
2100823b8294SYaroslav Brustinov    if module_relative:
2101823b8294SYaroslav Brustinov        package = _normalize_module(package)
2102823b8294SYaroslav Brustinov        path = _module_relative_path(package, path)
2103823b8294SYaroslav Brustinov
2104823b8294SYaroslav Brustinov    # Find the file and read it.