1 | # Module doctest.
|
---|
2 | # Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org).
|
---|
3 | # Major enhancements and refactoring by:
|
---|
4 | # Jim Fulton
|
---|
5 | # Edward Loper
|
---|
6 |
|
---|
7 | # Provided as-is; use at your own risk; no warranty; no promises; enjoy!
|
---|
8 |
|
---|
9 | r"""Module doctest -- a framework for running examples in docstrings.
|
---|
10 |
|
---|
11 | In simplest use, end each module M to be tested with:
|
---|
12 |
|
---|
13 | def _test():
|
---|
14 | import doctest
|
---|
15 | doctest.testmod()
|
---|
16 |
|
---|
17 | if __name__ == "__main__":
|
---|
18 | _test()
|
---|
19 |
|
---|
20 | Then running the module as a script will cause the examples in the
|
---|
21 | docstrings to get executed and verified:
|
---|
22 |
|
---|
23 | python M.py
|
---|
24 |
|
---|
25 | This won't display anything unless an example fails, in which case the
|
---|
26 | failing example(s) and the cause(s) of the failure(s) are printed to stdout
|
---|
27 | (why not stderr? because stderr is a lame hack <0.2 wink>), and the final
|
---|
28 | line of output is "Test failed.".
|
---|
29 |
|
---|
30 | Run it with the -v switch instead:
|
---|
31 |
|
---|
32 | python M.py -v
|
---|
33 |
|
---|
34 | and a detailed report of all examples tried is printed to stdout, along
|
---|
35 | with assorted summaries at the end.
|
---|
36 |
|
---|
37 | You can force verbose mode by passing "verbose=True" to testmod, or prohibit
|
---|
38 | it by passing "verbose=False". In either of those cases, sys.argv is not
|
---|
39 | examined by testmod.
|
---|
40 |
|
---|
41 | There are a variety of other ways to run doctests, including integration
|
---|
42 | with the unittest framework, and support for running non-Python text
|
---|
43 | files containing doctests. There are also many ways to override parts
|
---|
44 | of doctest's default behaviors. See the Library Reference Manual for
|
---|
45 | details.
|
---|
46 | """
|
---|
47 |
|
---|
48 | __docformat__ = 'reStructuredText en'
|
---|
49 |
|
---|
50 | __all__ = [
|
---|
51 | # 0, Option Flags
|
---|
52 | 'register_optionflag',
|
---|
53 | 'DONT_ACCEPT_TRUE_FOR_1',
|
---|
54 | 'DONT_ACCEPT_BLANKLINE',
|
---|
55 | 'NORMALIZE_WHITESPACE',
|
---|
56 | 'ELLIPSIS',
|
---|
57 | 'SKIP',
|
---|
58 | 'IGNORE_EXCEPTION_DETAIL',
|
---|
59 | 'COMPARISON_FLAGS',
|
---|
60 | 'REPORT_UDIFF',
|
---|
61 | 'REPORT_CDIFF',
|
---|
62 | 'REPORT_NDIFF',
|
---|
63 | 'REPORT_ONLY_FIRST_FAILURE',
|
---|
64 | 'REPORTING_FLAGS',
|
---|
65 | # 1. Utility Functions
|
---|
66 | # 2. Example & DocTest
|
---|
67 | 'Example',
|
---|
68 | 'DocTest',
|
---|
69 | # 3. Doctest Parser
|
---|
70 | 'DocTestParser',
|
---|
71 | # 4. Doctest Finder
|
---|
72 | 'DocTestFinder',
|
---|
73 | # 5. Doctest Runner
|
---|
74 | 'DocTestRunner',
|
---|
75 | 'OutputChecker',
|
---|
76 | 'DocTestFailure',
|
---|
77 | 'UnexpectedException',
|
---|
78 | 'DebugRunner',
|
---|
79 | # 6. Test Functions
|
---|
80 | 'testmod',
|
---|
81 | 'testfile',
|
---|
82 | 'run_docstring_examples',
|
---|
83 | # 7. Tester
|
---|
84 | 'Tester',
|
---|
85 | # 8. Unittest Support
|
---|
86 | 'DocTestSuite',
|
---|
87 | 'DocFileSuite',
|
---|
88 | 'set_unittest_reportflags',
|
---|
89 | # 9. Debugging Support
|
---|
90 | 'script_from_examples',
|
---|
91 | 'testsource',
|
---|
92 | 'debug_src',
|
---|
93 | 'debug',
|
---|
94 | ]
|
---|
95 |
|
---|
96 | import __future__
|
---|
97 |
|
---|
98 | import sys, traceback, inspect, linecache, os, re
|
---|
99 | import unittest, difflib, pdb, tempfile
|
---|
100 | import warnings
|
---|
101 | from StringIO import StringIO
|
---|
102 |
|
---|
103 | # There are 4 basic classes:
|
---|
104 | # - Example: a <source, want> pair, plus an intra-docstring line number.
|
---|
105 | # - DocTest: a collection of examples, parsed from a docstring, plus
|
---|
106 | # info about where the docstring came from (name, filename, lineno).
|
---|
107 | # - DocTestFinder: extracts DocTests from a given object's docstring and
|
---|
108 | # its contained objects' docstrings.
|
---|
109 | # - DocTestRunner: runs DocTest cases, and accumulates statistics.
|
---|
110 | #
|
---|
111 | # So the basic picture is:
|
---|
112 | #
|
---|
113 | # list of:
|
---|
114 | # +------+ +---------+ +-------+
|
---|
115 | # |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results|
|
---|
116 | # +------+ +---------+ +-------+
|
---|
117 | # | Example |
|
---|
118 | # | ... |
|
---|
119 | # | Example |
|
---|
120 | # +---------+
|
---|
121 |
|
---|
122 | # Option constants.
|
---|
123 |
|
---|
124 | OPTIONFLAGS_BY_NAME = {}
|
---|
125 | def register_optionflag(name):
|
---|
126 | # Create a new flag unless `name` is already known.
|
---|
127 | return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME))
|
---|
128 |
|
---|
129 | DONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1')
|
---|
130 | DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE')
|
---|
131 | NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE')
|
---|
132 | ELLIPSIS = register_optionflag('ELLIPSIS')
|
---|
133 | SKIP = register_optionflag('SKIP')
|
---|
134 | IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL')
|
---|
135 |
|
---|
136 | COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 |
|
---|
137 | DONT_ACCEPT_BLANKLINE |
|
---|
138 | NORMALIZE_WHITESPACE |
|
---|
139 | ELLIPSIS |
|
---|
140 | SKIP |
|
---|
141 | IGNORE_EXCEPTION_DETAIL)
|
---|
142 |
|
---|
143 | REPORT_UDIFF = register_optionflag('REPORT_UDIFF')
|
---|
144 | REPORT_CDIFF = register_optionflag('REPORT_CDIFF')
|
---|
145 | REPORT_NDIFF = register_optionflag('REPORT_NDIFF')
|
---|
146 | REPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE')
|
---|
147 |
|
---|
148 | REPORTING_FLAGS = (REPORT_UDIFF |
|
---|
149 | REPORT_CDIFF |
|
---|
150 | REPORT_NDIFF |
|
---|
151 | REPORT_ONLY_FIRST_FAILURE)
|
---|
152 |
|
---|
153 | # Special string markers for use in `want` strings:
|
---|
154 | BLANKLINE_MARKER = '<BLANKLINE>'
|
---|
155 | ELLIPSIS_MARKER = '...'
|
---|
156 |
|
---|
157 | ######################################################################
|
---|
158 | ## Table of Contents
|
---|
159 | ######################################################################
|
---|
160 | # 1. Utility Functions
|
---|
161 | # 2. Example & DocTest -- store test cases
|
---|
162 | # 3. DocTest Parser -- extracts examples from strings
|
---|
163 | # 4. DocTest Finder -- extracts test cases from objects
|
---|
164 | # 5. DocTest Runner -- runs test cases
|
---|
165 | # 6. Test Functions -- convenient wrappers for testing
|
---|
166 | # 7. Tester Class -- for backwards compatibility
|
---|
167 | # 8. Unittest Support
|
---|
168 | # 9. Debugging Support
|
---|
169 | # 10. Example Usage
|
---|
170 |
|
---|
171 | ######################################################################
|
---|
172 | ## 1. Utility Functions
|
---|
173 | ######################################################################
|
---|
174 |
|
---|
175 | def _extract_future_flags(globs):
|
---|
176 | """
|
---|
177 | Return the compiler-flags associated with the future features that
|
---|
178 | have been imported into the given namespace (globs).
|
---|
179 | """
|
---|
180 | flags = 0
|
---|
181 | for fname in __future__.all_feature_names:
|
---|
182 | feature = globs.get(fname, None)
|
---|
183 | if feature is getattr(__future__, fname):
|
---|
184 | flags |= feature.compiler_flag
|
---|
185 | return flags
|
---|
186 |
|
---|
187 | def _normalize_module(module, depth=2):
|
---|
188 | """
|
---|
189 | Return the module specified by `module`. In particular:
|
---|
190 | - If `module` is a module, then return module.
|
---|
191 | - If `module` is a string, then import and return the
|
---|
192 | module with that name.
|
---|
193 | - If `module` is None, then return the calling module.
|
---|
194 | The calling module is assumed to be the module of
|
---|
195 | the stack frame at the given depth in the call stack.
|
---|
196 | """
|
---|
197 | if inspect.ismodule(module):
|
---|
198 | return module
|
---|
199 | elif isinstance(module, (str, unicode)):
|
---|
200 | return __import__(module, globals(), locals(), ["*"])
|
---|
201 | elif module is None:
|
---|
202 | return sys.modules[sys._getframe(depth).f_globals['__name__']]
|
---|
203 | else:
|
---|
204 | raise TypeError("Expected a module, string, or None")
|
---|
205 |
|
---|
206 | def _load_testfile(filename, package, module_relative):
|
---|
207 | if module_relative:
|
---|
208 | package = _normalize_module(package, 3)
|
---|
209 | filename = _module_relative_path(package, filename)
|
---|
210 | if hasattr(package, '__loader__'):
|
---|
211 | if hasattr(package.__loader__, 'get_data'):
|
---|
212 | return package.__loader__.get_data(filename), filename
|
---|
213 | return open(filename).read(), filename
|
---|
214 |
|
---|
215 | def _indent(s, indent=4):
|
---|
216 | """
|
---|
217 | Add the given number of space characters to the beginning every
|
---|
218 | non-blank line in `s`, and return the result.
|
---|
219 | """
|
---|
220 | # This regexp matches the start of non-blank lines:
|
---|
221 | return re.sub('(?m)^(?!$)', indent*' ', s)
|
---|
222 |
|
---|
223 | def _exception_traceback(exc_info):
|
---|
224 | """
|
---|
225 | Return a string containing a traceback message for the given
|
---|
226 | exc_info tuple (as returned by sys.exc_info()).
|
---|
227 | """
|
---|
228 | # Get a traceback message.
|
---|
229 | excout = StringIO()
|
---|
230 | exc_type, exc_val, exc_tb = exc_info
|
---|
231 | traceback.print_exception(exc_type, exc_val, exc_tb, file=excout)
|
---|
232 | return excout.getvalue()
|
---|
233 |
|
---|
234 | # Override some StringIO methods.
|
---|
235 | class _SpoofOut(StringIO):
|
---|
236 | def getvalue(self):
|
---|
237 | result = StringIO.getvalue(self)
|
---|
238 | # If anything at all was written, make sure there's a trailing
|
---|
239 | # newline. There's no way for the expected output to indicate
|
---|
240 | # that a trailing newline is missing.
|
---|
241 | if result and not result.endswith("\n"):
|
---|
242 | result += "\n"
|
---|
243 | # Prevent softspace from screwing up the next test case, in
|
---|
244 | # case they used print with a trailing comma in an example.
|
---|
245 | if hasattr(self, "softspace"):
|
---|
246 | del self.softspace
|
---|
247 | return result
|
---|
248 |
|
---|
249 | def truncate(self, size=None):
|
---|
250 | StringIO.truncate(self, size)
|
---|
251 | if hasattr(self, "softspace"):
|
---|
252 | del self.softspace
|
---|
253 |
|
---|
254 | # Worst-case linear-time ellipsis matching.
|
---|
255 | def _ellipsis_match(want, got):
|
---|
256 | """
|
---|
257 | Essentially the only subtle case:
|
---|
258 | >>> _ellipsis_match('aa...aa', 'aaa')
|
---|
259 | False
|
---|
260 | """
|
---|
261 | if ELLIPSIS_MARKER not in want:
|
---|
262 | return want == got
|
---|
263 |
|
---|
264 | # Find "the real" strings.
|
---|
265 | ws = want.split(ELLIPSIS_MARKER)
|
---|
266 | assert len(ws) >= 2
|
---|
267 |
|
---|
268 | # Deal with exact matches possibly needed at one or both ends.
|
---|
269 | startpos, endpos = 0, len(got)
|
---|
270 | w = ws[0]
|
---|
271 | if w: # starts with exact match
|
---|
272 | if got.startswith(w):
|
---|
273 | startpos = len(w)
|
---|
274 | del ws[0]
|
---|
275 | else:
|
---|
276 | return False
|
---|
277 | w = ws[-1]
|
---|
278 | if w: # ends with exact match
|
---|
279 | if got.endswith(w):
|
---|
280 | endpos -= len(w)
|
---|
281 | del ws[-1]
|
---|
282 | else:
|
---|
283 | return False
|
---|
284 |
|
---|
285 | if startpos > endpos:
|
---|
286 | # Exact end matches required more characters than we have, as in
|
---|
287 | # _ellipsis_match('aa...aa', 'aaa')
|
---|
288 | return False
|
---|
289 |
|
---|
290 | # For the rest, we only need to find the leftmost non-overlapping
|
---|
291 | # match for each piece. If there's no overall match that way alone,
|
---|
292 | # there's no overall match period.
|
---|
293 | for w in ws:
|
---|
294 | # w may be '' at times, if there are consecutive ellipses, or
|
---|
295 | # due to an ellipsis at the start or end of `want`. That's OK.
|
---|
296 | # Search for an empty string succeeds, and doesn't change startpos.
|
---|
297 | startpos = got.find(w, startpos, endpos)
|
---|
298 | if startpos < 0:
|
---|
299 | return False
|
---|
300 | startpos += len(w)
|
---|
301 |
|
---|
302 | return True
|
---|
303 |
|
---|
304 | def _comment_line(line):
|
---|
305 | "Return a commented form of the given line"
|
---|
306 | line = line.rstrip()
|
---|
307 | if line:
|
---|
308 | return '# '+line
|
---|
309 | else:
|
---|
310 | return '#'
|
---|
311 |
|
---|
312 | class _OutputRedirectingPdb(pdb.Pdb):
|
---|
313 | """
|
---|
314 | A specialized version of the python debugger that redirects stdout
|
---|
315 | to a given stream when interacting with the user. Stdout is *not*
|
---|
316 | redirected when traced code is executed.
|
---|
317 | """
|
---|
318 | def __init__(self, out):
|
---|
319 | self.__out = out
|
---|
320 | pdb.Pdb.__init__(self, stdout=out)
|
---|
321 |
|
---|
322 | def trace_dispatch(self, *args):
|
---|
323 | # Redirect stdout to the given stream.
|
---|
324 | save_stdout = sys.stdout
|
---|
325 | sys.stdout = self.__out
|
---|
326 | # Call Pdb's trace dispatch method.
|
---|
327 | try:
|
---|
328 | return pdb.Pdb.trace_dispatch(self, *args)
|
---|
329 | finally:
|
---|
330 | sys.stdout = save_stdout
|
---|
331 |
|
---|
332 | # [XX] Normalize with respect to os.path.pardir?
|
---|
333 | def _module_relative_path(module, path):
|
---|
334 | if not inspect.ismodule(module):
|
---|
335 | raise TypeError, 'Expected a module: %r' % module
|
---|
336 | if path.startswith('/'):
|
---|
337 | raise ValueError, 'Module-relative files may not have absolute paths'
|
---|
338 |
|
---|
339 | # Find the base directory for the path.
|
---|
340 | if hasattr(module, '__file__'):
|
---|
341 | # A normal module/package
|
---|
342 | basedir = os.path.split(module.__file__)[0]
|
---|
343 | elif module.__name__ == '__main__':
|
---|
344 | # An interactive session.
|
---|
345 | if len(sys.argv)>0 and sys.argv[0] != '':
|
---|
346 | basedir = os.path.split(sys.argv[0])[0]
|
---|
347 | else:
|
---|
348 | basedir = os.curdir
|
---|
349 | else:
|
---|
350 | # A module w/o __file__ (this includes builtins)
|
---|
351 | raise ValueError("Can't resolve paths relative to the module " +
|
---|
352 | module + " (it has no __file__)")
|
---|
353 |
|
---|
354 | # Combine the base directory and the path.
|
---|
355 | return os.path.join(basedir, *(path.split('/')))
|
---|
356 |
|
---|
357 | ######################################################################
|
---|
358 | ## 2. Example & DocTest
|
---|
359 | ######################################################################
|
---|
360 | ## - An "example" is a <source, want> pair, where "source" is a
|
---|
361 | ## fragment of source code, and "want" is the expected output for
|
---|
362 | ## "source." The Example class also includes information about
|
---|
363 | ## where the example was extracted from.
|
---|
364 | ##
|
---|
365 | ## - A "doctest" is a collection of examples, typically extracted from
|
---|
366 | ## a string (such as an object's docstring). The DocTest class also
|
---|
367 | ## includes information about where the string was extracted from.
|
---|
368 |
|
---|
369 | class Example:
|
---|
370 | """
|
---|
371 | A single doctest example, consisting of source code and expected
|
---|
372 | output. `Example` defines the following attributes:
|
---|
373 |
|
---|
374 | - source: A single Python statement, always ending with a newline.
|
---|
375 | The constructor adds a newline if needed.
|
---|
376 |
|
---|
377 | - want: The expected output from running the source code (either
|
---|
378 | from stdout, or a traceback in case of exception). `want` ends
|
---|
379 | with a newline unless it's empty, in which case it's an empty
|
---|
380 | string. The constructor adds a newline if needed.
|
---|
381 |
|
---|
382 | - exc_msg: The exception message generated by the example, if
|
---|
383 | the example is expected to generate an exception; or `None` if
|
---|
384 | it is not expected to generate an exception. This exception
|
---|
385 | message is compared against the return value of
|
---|
386 | `traceback.format_exception_only()`. `exc_msg` ends with a
|
---|
387 | newline unless it's `None`. The constructor adds a newline
|
---|
388 | if needed.
|
---|
389 |
|
---|
390 | - lineno: The line number within the DocTest string containing
|
---|
391 | this Example where the Example begins. This line number is
|
---|
392 | zero-based, with respect to the beginning of the DocTest.
|
---|
393 |
|
---|
394 | - indent: The example's indentation in the DocTest string.
|
---|
395 | I.e., the number of space characters that preceed the
|
---|
396 | example's first prompt.
|
---|
397 |
|
---|
398 | - options: A dictionary mapping from option flags to True or
|
---|
399 | False, which is used to override default options for this
|
---|
400 | example. Any option flags not contained in this dictionary
|
---|
401 | are left at their default value (as specified by the
|
---|
402 | DocTestRunner's optionflags). By default, no options are set.
|
---|
403 | """
|
---|
404 | def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
|
---|
405 | options=None):
|
---|
406 | # Normalize inputs.
|
---|
407 | if not source.endswith('\n'):
|
---|
408 | source += '\n'
|
---|
409 | if want and not want.endswith('\n'):
|
---|
410 | want += '\n'
|
---|
411 | if exc_msg is not None and not exc_msg.endswith('\n'):
|
---|
412 | exc_msg += '\n'
|
---|
413 | # Store properties.
|
---|
414 | self.source = source
|
---|
415 | self.want = want
|
---|
416 | self.lineno = lineno
|
---|
417 | self.indent = indent
|
---|
418 | if options is None: options = {}
|
---|
419 | self.options = options
|
---|
420 | self.exc_msg = exc_msg
|
---|
421 |
|
---|
422 | class DocTest:
|
---|
423 | """
|
---|
424 | A collection of doctest examples that should be run in a single
|
---|
425 | namespace. Each `DocTest` defines the following attributes:
|
---|
426 |
|
---|
427 | - examples: the list of examples.
|
---|
428 |
|
---|
429 | - globs: The namespace (aka globals) that the examples should
|
---|
430 | be run in.
|
---|
431 |
|
---|
432 | - name: A name identifying the DocTest (typically, the name of
|
---|
433 | the object whose docstring this DocTest was extracted from).
|
---|
434 |
|
---|
435 | - filename: The name of the file that this DocTest was extracted
|
---|
436 | from, or `None` if the filename is unknown.
|
---|
437 |
|
---|
438 | - lineno: The line number within filename where this DocTest
|
---|
439 | begins, or `None` if the line number is unavailable. This
|
---|
440 | line number is zero-based, with respect to the beginning of
|
---|
441 | the file.
|
---|
442 |
|
---|
443 | - docstring: The string that the examples were extracted from,
|
---|
444 | or `None` if the string is unavailable.
|
---|
445 | """
|
---|
446 | def __init__(self, examples, globs, name, filename, lineno, docstring):
|
---|
447 | """
|
---|
448 | Create a new DocTest containing the given examples. The
|
---|
449 | DocTest's globals are initialized with a copy of `globs`.
|
---|
450 | """
|
---|
451 | assert not isinstance(examples, basestring), \
|
---|
452 | "DocTest no longer accepts str; use DocTestParser instead"
|
---|
453 | self.examples = examples
|
---|
454 | self.docstring = docstring
|
---|
455 | self.globs = globs.copy()
|
---|
456 | self.name = name
|
---|
457 | self.filename = filename
|
---|
458 | self.lineno = lineno
|
---|
459 |
|
---|
460 | def __repr__(self):
|
---|
461 | if len(self.examples) == 0:
|
---|
462 | examples = 'no examples'
|
---|
463 | elif len(self.examples) == 1:
|
---|
464 | examples = '1 example'
|
---|
465 | else:
|
---|
466 | examples = '%d examples' % len(self.examples)
|
---|
467 | return ('<DocTest %s from %s:%s (%s)>' %
|
---|
468 | (self.name, self.filename, self.lineno, examples))
|
---|
469 |
|
---|
470 |
|
---|
471 | # This lets us sort tests by name:
|
---|
472 | def __cmp__(self, other):
|
---|
473 | if not isinstance(other, DocTest):
|
---|
474 | return -1
|
---|
475 | return cmp((self.name, self.filename, self.lineno, id(self)),
|
---|
476 | (other.name, other.filename, other.lineno, id(other)))
|
---|
477 |
|
---|
478 | ######################################################################
|
---|
479 | ## 3. DocTestParser
|
---|
480 | ######################################################################
|
---|
481 |
|
---|
482 | class DocTestParser:
|
---|
483 | """
|
---|
484 | A class used to parse strings containing doctest examples.
|
---|
485 | """
|
---|
486 | # This regular expression is used to find doctest examples in a
|
---|
487 | # string. It defines three groups: `source` is the source code
|
---|
488 | # (including leading indentation and prompts); `indent` is the
|
---|
489 | # indentation of the first (PS1) line of the source code; and
|
---|
490 | # `want` is the expected output (including leading indentation).
|
---|
491 | _EXAMPLE_RE = re.compile(r'''
|
---|
492 | # Source consists of a PS1 line followed by zero or more PS2 lines.
|
---|
493 | (?P<source>
|
---|
494 | (?:^(?P<indent> [ ]*) >>> .*) # PS1 line
|
---|
495 | (?:\n [ ]* \.\.\. .*)*) # PS2 lines
|
---|
496 | \n?
|
---|
497 | # Want consists of any non-blank lines that do not start with PS1.
|
---|
498 | (?P<want> (?:(?![ ]*$) # Not a blank line
|
---|
499 | (?![ ]*>>>) # Not a line starting with PS1
|
---|
500 | .*$\n? # But any other line
|
---|
501 | )*)
|
---|
502 | ''', re.MULTILINE | re.VERBOSE)
|
---|
503 |
|
---|
504 | # A regular expression for handling `want` strings that contain
|
---|
505 | # expected exceptions. It divides `want` into three pieces:
|
---|
506 | # - the traceback header line (`hdr`)
|
---|
507 | # - the traceback stack (`stack`)
|
---|
508 | # - the exception message (`msg`), as generated by
|
---|
509 | # traceback.format_exception_only()
|
---|
510 | # `msg` may have multiple lines. We assume/require that the
|
---|
511 | # exception message is the first non-indented line starting with a word
|
---|
512 | # character following the traceback header line.
|
---|
513 | _EXCEPTION_RE = re.compile(r"""
|
---|
514 | # Grab the traceback header. Different versions of Python have
|
---|
515 | # said different things on the first traceback line.
|
---|
516 | ^(?P<hdr> Traceback\ \(
|
---|
517 | (?: most\ recent\ call\ last
|
---|
518 | | innermost\ last
|
---|
519 | ) \) :
|
---|
520 | )
|
---|
521 | \s* $ # toss trailing whitespace on the header.
|
---|
522 | (?P<stack> .*?) # don't blink: absorb stuff until...
|
---|
523 | ^ (?P<msg> \w+ .*) # a line *starts* with alphanum.
|
---|
524 | """, re.VERBOSE | re.MULTILINE | re.DOTALL)
|
---|
525 |
|
---|
526 | # A callable returning a true value iff its argument is a blank line
|
---|
527 | # or contains a single comment.
|
---|
528 | _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match
|
---|
529 |
|
---|
530 | def parse(self, string, name='<string>'):
|
---|
531 | """
|
---|
532 | Divide the given string into examples and intervening text,
|
---|
533 | and return them as a list of alternating Examples and strings.
|
---|
534 | Line numbers for the Examples are 0-based. The optional
|
---|
535 | argument `name` is a name identifying this string, and is only
|
---|
536 | used for error messages.
|
---|
537 | """
|
---|
538 | string = string.expandtabs()
|
---|
539 | # If all lines begin with the same indentation, then strip it.
|
---|
540 | min_indent = self._min_indent(string)
|
---|
541 | if min_indent > 0:
|
---|
542 | string = '\n'.join([l[min_indent:] for l in string.split('\n')])
|
---|
543 |
|
---|
544 | output = []
|
---|
545 | charno, lineno = 0, 0
|
---|
546 | # Find all doctest examples in the string:
|
---|
547 | for m in self._EXAMPLE_RE.finditer(string):
|
---|
548 | # Add the pre-example text to `output`.
|
---|
549 | output.append(string[charno:m.start()])
|
---|
550 | # Update lineno (lines before this example)
|
---|
551 | lineno += string.count('\n', charno, m.start())
|
---|
552 | # Extract info from the regexp match.
|
---|
553 | (source, options, want, exc_msg) = \
|
---|
554 | self._parse_example(m, name, lineno)
|
---|
555 | # Create an Example, and add it to the list.
|
---|
556 | if not self._IS_BLANK_OR_COMMENT(source):
|
---|
557 | output.append( Example(source, want, exc_msg,
|
---|
558 | lineno=lineno,
|
---|
559 | indent=min_indent+len(m.group('indent')),
|
---|
560 | options=options) )
|
---|
561 | # Update lineno (lines inside this example)
|
---|
562 | lineno += string.count('\n', m.start(), m.end())
|
---|
563 | # Update charno.
|
---|
564 | charno = m.end()
|
---|
565 | # Add any remaining post-example text to `output`.
|
---|
566 | output.append(string[charno:])
|
---|
567 | return output
|
---|
568 |
|
---|
569 | def get_doctest(self, string, globs, name, filename, lineno):
|
---|
570 | """
|
---|
571 | Extract all doctest examples from the given string, and
|
---|
572 | collect them into a `DocTest` object.
|
---|
573 |
|
---|
574 | `globs`, `name`, `filename`, and `lineno` are attributes for
|
---|
575 | the new `DocTest` object. See the documentation for `DocTest`
|
---|
576 | for more information.
|
---|
577 | """
|
---|
578 | return DocTest(self.get_examples(string, name), globs,
|
---|
579 | name, filename, lineno, string)
|
---|
580 |
|
---|
581 | def get_examples(self, string, name='<string>'):
|
---|
582 | """
|
---|
583 | Extract all doctest examples from the given string, and return
|
---|
584 | them as a list of `Example` objects. Line numbers are
|
---|
585 | 0-based, because it's most common in doctests that nothing
|
---|
586 | interesting appears on the same line as opening triple-quote,
|
---|
587 | and so the first interesting line is called \"line 1\" then.
|
---|
588 |
|
---|
589 | The optional argument `name` is a name identifying this
|
---|
590 | string, and is only used for error messages.
|
---|
591 | """
|
---|
592 | return [x for x in self.parse(string, name)
|
---|
593 | if isinstance(x, Example)]
|
---|
594 |
|
---|
595 | def _parse_example(self, m, name, lineno):
|
---|
596 | """
|
---|
597 | Given a regular expression match from `_EXAMPLE_RE` (`m`),
|
---|
598 | return a pair `(source, want)`, where `source` is the matched
|
---|
599 | example's source code (with prompts and indentation stripped);
|
---|
600 | and `want` is the example's expected output (with indentation
|
---|
601 | stripped).
|
---|
602 |
|
---|
603 | `name` is the string's name, and `lineno` is the line number
|
---|
604 | where the example starts; both are used for error messages.
|
---|
605 | """
|
---|
606 | # Get the example's indentation level.
|
---|
607 | indent = len(m.group('indent'))
|
---|
608 |
|
---|
609 | # Divide source into lines; check that they're properly
|
---|
610 | # indented; and then strip their indentation & prompts.
|
---|
611 | source_lines = m.group('source').split('\n')
|
---|
612 | self._check_prompt_blank(source_lines, indent, name, lineno)
|
---|
613 | self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno)
|
---|
614 | source = '\n'.join([sl[indent+4:] for sl in source_lines])
|
---|
615 |
|
---|
616 | # Divide want into lines; check that it's properly indented; and
|
---|
617 | # then strip the indentation. Spaces before the last newline should
|
---|
618 | # be preserved, so plain rstrip() isn't good enough.
|
---|
619 | want = m.group('want')
|
---|
620 | want_lines = want.split('\n')
|
---|
621 | if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
|
---|
622 | del want_lines[-1] # forget final newline & spaces after it
|
---|
623 | self._check_prefix(want_lines, ' '*indent, name,
|
---|
624 | lineno + len(source_lines))
|
---|
625 | want = '\n'.join([wl[indent:] for wl in want_lines])
|
---|
626 |
|
---|
627 | # If `want` contains a traceback message, then extract it.
|
---|
628 | m = self._EXCEPTION_RE.match(want)
|
---|
629 | if m:
|
---|
630 | exc_msg = m.group('msg')
|
---|
631 | else:
|
---|
632 | exc_msg = None
|
---|
633 |
|
---|
634 | # Extract options from the source.
|
---|
635 | options = self._find_options(source, name, lineno)
|
---|
636 |
|
---|
637 | return source, options, want, exc_msg
|
---|
638 |
|
---|
639 | # This regular expression looks for option directives in the
|
---|
640 | # source code of an example. Option directives are comments
|
---|
641 | # starting with "doctest:". Warning: this may give false
|
---|
642 | # positives for string-literals that contain the string
|
---|
643 | # "#doctest:". Eliminating these false positives would require
|
---|
644 | # actually parsing the string; but we limit them by ignoring any
|
---|
645 | # line containing "#doctest:" that is *followed* by a quote mark.
|
---|
646 | _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$',
|
---|
647 | re.MULTILINE)
|
---|
648 |
|
---|
649 | def _find_options(self, source, name, lineno):
|
---|
650 | """
|
---|
651 | Return a dictionary containing option overrides extracted from
|
---|
652 | option directives in the given source string.
|
---|
653 |
|
---|
654 | `name` is the string's name, and `lineno` is the line number
|
---|
655 | where the example starts; both are used for error messages.
|
---|
656 | """
|
---|
657 | options = {}
|
---|
658 | # (note: with the current regexp, this will match at most once:)
|
---|
659 | for m in self._OPTION_DIRECTIVE_RE.finditer(source):
|
---|
660 | option_strings = m.group(1).replace(',', ' ').split()
|
---|
661 | for option in option_strings:
|
---|
662 | if (option[0] not in '+-' or
|
---|
663 | option[1:] not in OPTIONFLAGS_BY_NAME):
|
---|
664 | raise ValueError('line %r of the doctest for %s '
|
---|
665 | 'has an invalid option: %r' %
|
---|
666 | (lineno+1, name, option))
|
---|
667 | flag = OPTIONFLAGS_BY_NAME[option[1:]]
|
---|
668 | options[flag] = (option[0] == '+')
|
---|
669 | if options and self._IS_BLANK_OR_COMMENT(source):
|
---|
670 | raise ValueError('line %r of the doctest for %s has an option '
|
---|
671 | 'directive on a line with no example: %r' %
|
---|
672 | (lineno, name, source))
|
---|
673 | return options
|
---|
674 |
|
---|
675 | # This regular expression finds the indentation of every non-blank
|
---|
676 | # line in a string.
|
---|
677 | _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE)
|
---|
678 |
|
---|
679 | def _min_indent(self, s):
|
---|
680 | "Return the minimum indentation of any non-blank line in `s`"
|
---|
681 | indents = [len(indent) for indent in self._INDENT_RE.findall(s)]
|
---|
682 | if len(indents) > 0:
|
---|
683 | return min(indents)
|
---|
684 | else:
|
---|
685 | return 0
|
---|
686 |
|
---|
687 | def _check_prompt_blank(self, lines, indent, name, lineno):
|
---|
688 | """
|
---|
689 | Given the lines of a source string (including prompts and
|
---|
690 | leading indentation), check to make sure that every prompt is
|
---|
691 | followed by a space character. If any line is not followed by
|
---|
692 | a space character, then raise ValueError.
|
---|
693 | """
|
---|
694 | for i, line in enumerate(lines):
|
---|
695 | if len(line) >= indent+4 and line[indent+3] != ' ':
|
---|
696 | raise ValueError('line %r of the docstring for %s '
|
---|
697 | 'lacks blank after %s: %r' %
|
---|
698 | (lineno+i+1, name,
|
---|
699 | line[indent:indent+3], line))
|
---|
700 |
|
---|
701 | def _check_prefix(self, lines, prefix, name, lineno):
|
---|
702 | """
|
---|
703 | Check that every line in the given list starts with the given
|
---|
704 | prefix; if any line does not, then raise a ValueError.
|
---|
705 | """
|
---|
706 | for i, line in enumerate(lines):
|
---|
707 | if line and not line.startswith(prefix):
|
---|
708 | raise ValueError('line %r of the docstring for %s has '
|
---|
709 | 'inconsistent leading whitespace: %r' %
|
---|
710 | (lineno+i+1, name, line))
|
---|
711 |
|
---|
712 |
|
---|
713 | ######################################################################
|
---|
714 | ## 4. DocTest Finder
|
---|
715 | ######################################################################
|
---|
716 |
|
---|
717 | class DocTestFinder:
|
---|
718 | """
|
---|
719 | A class used to extract the DocTests that are relevant to a given
|
---|
720 | object, from its docstring and the docstrings of its contained
|
---|
721 | objects. Doctests can currently be extracted from the following
|
---|
722 | object types: modules, functions, classes, methods, staticmethods,
|
---|
723 | classmethods, and properties.
|
---|
724 | """
|
---|
725 |
|
---|
726 | def __init__(self, verbose=False, parser=DocTestParser(),
|
---|
727 | recurse=True, exclude_empty=True):
|
---|
728 | """
|
---|
729 | Create a new doctest finder.
|
---|
730 |
|
---|
731 | The optional argument `parser` specifies a class or
|
---|
732 | function that should be used to create new DocTest objects (or
|
---|
733 | objects that implement the same interface as DocTest). The
|
---|
734 | signature for this factory function should match the signature
|
---|
735 | of the DocTest constructor.
|
---|
736 |
|
---|
737 | If the optional argument `recurse` is false, then `find` will
|
---|
738 | only examine the given object, and not any contained objects.
|
---|
739 |
|
---|
740 | If the optional argument `exclude_empty` is false, then `find`
|
---|
741 | will include tests for objects with empty docstrings.
|
---|
742 | """
|
---|
743 | self._parser = parser
|
---|
744 | self._verbose = verbose
|
---|
745 | self._recurse = recurse
|
---|
746 | self._exclude_empty = exclude_empty
|
---|
747 |
|
---|
748 | def find(self, obj, name=None, module=None, globs=None, extraglobs=None):
|
---|
749 | """
|
---|
750 | Return a list of the DocTests that are defined by the given
|
---|
751 | object's docstring, or by any of its contained objects'
|
---|
752 | docstrings.
|
---|
753 |
|
---|
754 | The optional parameter `module` is the module that contains
|
---|
755 | the given object. If the module is not specified or is None, then
|
---|
756 | the test finder will attempt to automatically determine the
|
---|
757 | correct module. The object's module is used:
|
---|
758 |
|
---|
759 | - As a default namespace, if `globs` is not specified.
|
---|
760 | - To prevent the DocTestFinder from extracting DocTests
|
---|
761 | from objects that are imported from other modules.
|
---|
762 | - To find the name of the file containing the object.
|
---|
763 | - To help find the line number of the object within its
|
---|
764 | file.
|
---|
765 |
|
---|
766 | Contained objects whose module does not match `module` are ignored.
|
---|
767 |
|
---|
768 | If `module` is False, no attempt to find the module will be made.
|
---|
769 | This is obscure, of use mostly in tests: if `module` is False, or
|
---|
770 | is None but cannot be found automatically, then all objects are
|
---|
771 | considered to belong to the (non-existent) module, so all contained
|
---|
772 | objects will (recursively) be searched for doctests.
|
---|
773 |
|
---|
774 | The globals for each DocTest is formed by combining `globs`
|
---|
775 | and `extraglobs` (bindings in `extraglobs` override bindings
|
---|
776 | in `globs`). A new copy of the globals dictionary is created
|
---|
777 | for each DocTest. If `globs` is not specified, then it
|
---|
778 | defaults to the module's `__dict__`, if specified, or {}
|
---|
779 | otherwise. If `extraglobs` is not specified, then it defaults
|
---|
780 | to {}.
|
---|
781 |
|
---|
782 | """
|
---|
783 | # If name was not specified, then extract it from the object.
|
---|
784 | if name is None:
|
---|
785 | name = getattr(obj, '__name__', None)
|
---|
786 | if name is None:
|
---|
787 | raise ValueError("DocTestFinder.find: name must be given "
|
---|
788 | "when obj.__name__ doesn't exist: %r" %
|
---|
789 | (type(obj),))
|
---|
790 |
|
---|
791 | # Find the module that contains the given object (if obj is
|
---|
792 | # a module, then module=obj.). Note: this may fail, in which
|
---|
793 | # case module will be None.
|
---|
794 | if module is False:
|
---|
795 | module = None
|
---|
796 | elif module is None:
|
---|
797 | module = inspect.getmodule(obj)
|
---|
798 |
|
---|
799 | # Read the module's source code. This is used by
|
---|
800 | # DocTestFinder._find_lineno to find the line number for a
|
---|
801 | # given object's docstring.
|
---|
802 | try:
|
---|
803 | file = inspect.getsourcefile(obj) or inspect.getfile(obj)
|
---|
804 | source_lines = linecache.getlines(file)
|
---|
805 | if not source_lines:
|
---|
806 | source_lines = None
|
---|
807 | except TypeError:
|
---|
808 | source_lines = None
|
---|
809 |
|
---|
810 | # Initialize globals, and merge in extraglobs.
|
---|
811 | if globs is None:
|
---|
812 | if module is None:
|
---|
813 | globs = {}
|
---|
814 | else:
|
---|
815 | globs = module.__dict__.copy()
|
---|
816 | else:
|
---|
817 | globs = globs.copy()
|
---|
818 | if extraglobs is not None:
|
---|
819 | globs.update(extraglobs)
|
---|
820 |
|
---|
821 | # Recursively expore `obj`, extracting DocTests.
|
---|
822 | tests = []
|
---|
823 | self._find(tests, obj, name, module, source_lines, globs, {})
|
---|
824 | # Sort the tests by alpha order of names, for consistency in
|
---|
825 | # verbose-mode output. This was a feature of doctest in Pythons
|
---|
826 | # <= 2.3 that got lost by accident in 2.4. It was repaired in
|
---|
827 | # 2.4.4 and 2.5.
|
---|
828 | tests.sort()
|
---|
829 | return tests
|
---|
830 |
|
---|
831 | def _from_module(self, module, object):
|
---|
832 | """
|
---|
833 | Return true if the given object is defined in the given
|
---|
834 | module.
|
---|
835 | """
|
---|
836 | if module is None:
|
---|
837 | return True
|
---|
838 | elif inspect.isfunction(object):
|
---|
839 | return module.__dict__ is object.func_globals
|
---|
840 | elif inspect.isclass(object):
|
---|
841 | return module.__name__ == object.__module__
|
---|
842 | elif inspect.getmodule(object) is not None:
|
---|
843 | return module is inspect.getmodule(object)
|
---|
844 | elif hasattr(object, '__module__'):
|
---|
845 | return module.__name__ == object.__module__
|
---|
846 | elif isinstance(object, property):
|
---|
847 | return True # [XX] no way not be sure.
|
---|
848 | else:
|
---|
849 | raise ValueError("object must be a class or function")
|
---|
850 |
|
---|
851 | def _find(self, tests, obj, name, module, source_lines, globs, seen):
|
---|
852 | """
|
---|
853 | Find tests for the given object and any contained objects, and
|
---|
854 | add them to `tests`.
|
---|
855 | """
|
---|
856 | if self._verbose:
|
---|
857 | print 'Finding tests in %s' % name
|
---|
858 |
|
---|
859 | # If we've already processed this object, then ignore it.
|
---|
860 | if id(obj) in seen:
|
---|
861 | return
|
---|
862 | seen[id(obj)] = 1
|
---|
863 |
|
---|
864 | # Find a test for this object, and add it to the list of tests.
|
---|
865 | test = self._get_test(obj, name, module, globs, source_lines)
|
---|
866 | if test is not None:
|
---|
867 | tests.append(test)
|
---|
868 |
|
---|
869 | # Look for tests in a module's contained objects.
|
---|
870 | if inspect.ismodule(obj) and self._recurse:
|
---|
871 | for valname, val in obj.__dict__.items():
|
---|
872 | valname = '%s.%s' % (name, valname)
|
---|
873 | # Recurse to functions & classes.
|
---|
874 | if ((inspect.isfunction(val) or inspect.isclass(val)) and
|
---|
875 | self._from_module(module, val)):
|
---|
876 | self._find(tests, val, valname, module, source_lines,
|
---|
877 | globs, seen)
|
---|
878 |
|
---|
879 | # Look for tests in a module's __test__ dictionary.
|
---|
880 | if inspect.ismodule(obj) and self._recurse:
|
---|
881 | for valname, val in getattr(obj, '__test__', {}).items():
|
---|
882 | if not isinstance(valname, basestring):
|
---|
883 | raise ValueError("DocTestFinder.find: __test__ keys "
|
---|
884 | "must be strings: %r" %
|
---|
885 | (type(valname),))
|
---|
886 | if not (inspect.isfunction(val) or inspect.isclass(val) or
|
---|
887 | inspect.ismethod(val) or inspect.ismodule(val) or
|
---|
888 | isinstance(val, basestring)):
|
---|
889 | raise ValueError("DocTestFinder.find: __test__ values "
|
---|
890 | "must be strings, functions, methods, "
|
---|
891 | "classes, or modules: %r" %
|
---|
892 | (type(val),))
|
---|
893 | valname = '%s.__test__.%s' % (name, valname)
|
---|
894 | self._find(tests, val, valname, module, source_lines,
|
---|
895 | globs, seen)
|
---|
896 |
|
---|
897 | # Look for tests in a class's contained objects.
|
---|
898 | if inspect.isclass(obj) and self._recurse:
|
---|
899 | for valname, val in obj.__dict__.items():
|
---|
900 | # Special handling for staticmethod/classmethod.
|
---|
901 | if isinstance(val, staticmethod):
|
---|
902 | val = getattr(obj, valname)
|
---|
903 | if isinstance(val, classmethod):
|
---|
904 | val = getattr(obj, valname).im_func
|
---|
905 |
|
---|
906 | # Recurse to methods, properties, and nested classes.
|
---|
907 | if ((inspect.isfunction(val) or inspect.isclass(val) or
|
---|
908 | isinstance(val, property)) and
|
---|
909 | self._from_module(module, val)):
|
---|
910 | valname = '%s.%s' % (name, valname)
|
---|
911 | self._find(tests, val, valname, module, source_lines,
|
---|
912 | globs, seen)
|
---|
913 |
|
---|
914 | def _get_test(self, obj, name, module, globs, source_lines):
|
---|
915 | """
|
---|
916 | Return a DocTest for the given object, if it defines a docstring;
|
---|
917 | otherwise, return None.
|
---|
918 | """
|
---|
919 | # Extract the object's docstring. If it doesn't have one,
|
---|
920 | # then return None (no test for this object).
|
---|
921 | if isinstance(obj, basestring):
|
---|
922 | docstring = obj
|
---|
923 | else:
|
---|
924 | try:
|
---|
925 | if obj.__doc__ is None:
|
---|
926 | docstring = ''
|
---|
927 | else:
|
---|
928 | docstring = obj.__doc__
|
---|
929 | if not isinstance(docstring, basestring):
|
---|
930 | docstring = str(docstring)
|
---|
931 | except (TypeError, AttributeError):
|
---|
932 | docstring = ''
|
---|
933 |
|
---|
934 | # Find the docstring's location in the file.
|
---|
935 | lineno = self._find_lineno(obj, source_lines)
|
---|
936 |
|
---|
937 | # Don't bother if the docstring is empty.
|
---|
938 | if self._exclude_empty and not docstring:
|
---|
939 | return None
|
---|
940 |
|
---|
941 | # Return a DocTest for this object.
|
---|
942 | if module is None:
|
---|
943 | filename = None
|
---|
944 | else:
|
---|
945 | filename = getattr(module, '__file__', module.__name__)
|
---|
946 | if filename[-4:] in (".pyc", ".pyo"):
|
---|
947 | filename = filename[:-1]
|
---|
948 | return self._parser.get_doctest(docstring, globs, name,
|
---|
949 | filename, lineno)
|
---|
950 |
|
---|
951 | def _find_lineno(self, obj, source_lines):
|
---|
952 | """
|
---|
953 | Return a line number of the given object's docstring. Note:
|
---|
954 | this method assumes that the object has a docstring.
|
---|
955 | """
|
---|
956 | lineno = None
|
---|
957 |
|
---|
958 | # Find the line number for modules.
|
---|
959 | if inspect.ismodule(obj):
|
---|
960 | lineno = 0
|
---|
961 |
|
---|
962 | # Find the line number for classes.
|
---|
963 | # Note: this could be fooled if a class is defined multiple
|
---|
964 | # times in a single file.
|
---|
965 | if inspect.isclass(obj):
|
---|
966 | if source_lines is None:
|
---|
967 | return None
|
---|
968 | pat = re.compile(r'^\s*class\s*%s\b' %
|
---|
969 | getattr(obj, '__name__', '-'))
|
---|
970 | for i, line in enumerate(source_lines):
|
---|
971 | if pat.match(line):
|
---|
972 | lineno = i
|
---|
973 | break
|
---|
974 |
|
---|
975 | # Find the line number for functions & methods.
|
---|
976 | if inspect.ismethod(obj): obj = obj.im_func
|
---|
977 | if inspect.isfunction(obj): obj = obj.func_code
|
---|
978 | if inspect.istraceback(obj): obj = obj.tb_frame
|
---|
979 | if inspect.isframe(obj): obj = obj.f_code
|
---|
980 | if inspect.iscode(obj):
|
---|
981 | lineno = getattr(obj, 'co_firstlineno', None)-1
|
---|
982 |
|
---|
983 | # Find the line number where the docstring starts. Assume
|
---|
984 | # that it's the first line that begins with a quote mark.
|
---|
985 | # Note: this could be fooled by a multiline function
|
---|
986 | # signature, where a continuation line begins with a quote
|
---|
987 | # mark.
|
---|
988 | if lineno is not None:
|
---|
989 | if source_lines is None:
|
---|
990 | return lineno+1
|
---|
991 | pat = re.compile('(^|.*:)\s*\w*("|\')')
|
---|
992 | for lineno in range(lineno, len(source_lines)):
|
---|
993 | if pat.match(source_lines[lineno]):
|
---|
994 | return lineno
|
---|
995 |
|
---|
996 | # We couldn't find the line number.
|
---|
997 | return None
|
---|
998 |
|
---|
999 | ######################################################################
|
---|
1000 | ## 5. DocTest Runner
|
---|
1001 | ######################################################################
|
---|
1002 |
|
---|
1003 | class DocTestRunner:
|
---|
1004 | """
|
---|
1005 | A class used to run DocTest test cases, and accumulate statistics.
|
---|
1006 | The `run` method is used to process a single DocTest case. It
|
---|
1007 | returns a tuple `(f, t)`, where `t` is the number of test cases
|
---|
1008 | tried, and `f` is the number of test cases that failed.
|
---|
1009 |
|
---|
1010 | >>> tests = DocTestFinder().find(_TestClass)
|
---|
1011 | >>> runner = DocTestRunner(verbose=False)
|
---|
1012 | >>> tests.sort(key = lambda test: test.name)
|
---|
1013 | >>> for test in tests:
|
---|
1014 | ... print test.name, '->', runner.run(test)
|
---|
1015 | _TestClass -> (0, 2)
|
---|
1016 | _TestClass.__init__ -> (0, 2)
|
---|
1017 | _TestClass.get -> (0, 2)
|
---|
1018 | _TestClass.square -> (0, 1)
|
---|
1019 |
|
---|
1020 | The `summarize` method prints a summary of all the test cases that
|
---|
1021 | have been run by the runner, and returns an aggregated `(f, t)`
|
---|
1022 | tuple:
|
---|
1023 |
|
---|
1024 | >>> runner.summarize(verbose=1)
|
---|
1025 | 4 items passed all tests:
|
---|
1026 | 2 tests in _TestClass
|
---|
1027 | 2 tests in _TestClass.__init__
|
---|
1028 | 2 tests in _TestClass.get
|
---|
1029 | 1 tests in _TestClass.square
|
---|
1030 | 7 tests in 4 items.
|
---|
1031 | 7 passed and 0 failed.
|
---|
1032 | Test passed.
|
---|
1033 | (0, 7)
|
---|
1034 |
|
---|
1035 | The aggregated number of tried examples and failed examples is
|
---|
1036 | also available via the `tries` and `failures` attributes:
|
---|
1037 |
|
---|
1038 | >>> runner.tries
|
---|
1039 | 7
|
---|
1040 | >>> runner.failures
|
---|
1041 | 0
|
---|
1042 |
|
---|
1043 | The comparison between expected outputs and actual outputs is done
|
---|
1044 | by an `OutputChecker`. This comparison may be customized with a
|
---|
1045 | number of option flags; see the documentation for `testmod` for
|
---|
1046 | more information. If the option flags are insufficient, then the
|
---|
1047 | comparison may also be customized by passing a subclass of
|
---|
1048 | `OutputChecker` to the constructor.
|
---|
1049 |
|
---|
1050 | The test runner's display output can be controlled in two ways.
|
---|
1051 | First, an output function (`out) can be passed to
|
---|
1052 | `TestRunner.run`; this function will be called with strings that
|
---|
1053 | should be displayed. It defaults to `sys.stdout.write`. If
|
---|
1054 | capturing the output is not sufficient, then the display output
|
---|
1055 | can be also customized by subclassing DocTestRunner, and
|
---|
1056 | overriding the methods `report_start`, `report_success`,
|
---|
1057 | `report_unexpected_exception`, and `report_failure`.
|
---|
1058 | """
|
---|
1059 | # This divider string is used to separate failure messages, and to
|
---|
1060 | # separate sections of the summary.
|
---|
1061 | DIVIDER = "*" * 70
|
---|
1062 |
|
---|
1063 | def __init__(self, checker=None, verbose=None, optionflags=0):
|
---|
1064 | """
|
---|
1065 | Create a new test runner.
|
---|
1066 |
|
---|
1067 | Optional keyword arg `checker` is the `OutputChecker` that
|
---|
1068 | should be used to compare the expected outputs and actual
|
---|
1069 | outputs of doctest examples.
|
---|
1070 |
|
---|
1071 | Optional keyword arg 'verbose' prints lots of stuff if true,
|
---|
1072 | only failures if false; by default, it's true iff '-v' is in
|
---|
1073 | sys.argv.
|
---|
1074 |
|
---|
1075 | Optional argument `optionflags` can be used to control how the
|
---|
1076 | test runner compares expected output to actual output, and how
|
---|
1077 | it displays failures. See the documentation for `testmod` for
|
---|
1078 | more information.
|
---|
1079 | """
|
---|
1080 | self._checker = checker or OutputChecker()
|
---|
1081 | if verbose is None:
|
---|
1082 | verbose = '-v' in sys.argv
|
---|
1083 | self._verbose = verbose
|
---|
1084 | self.optionflags = optionflags
|
---|
1085 | self.original_optionflags = optionflags
|
---|
1086 |
|
---|
1087 | # Keep track of the examples we've run.
|
---|
1088 | self.tries = 0
|
---|
1089 | self.failures = 0
|
---|
1090 | self._name2ft = {}
|
---|
1091 |
|
---|
1092 | # Create a fake output target for capturing doctest output.
|
---|
1093 | self._fakeout = _SpoofOut()
|
---|
1094 |
|
---|
1095 | #/////////////////////////////////////////////////////////////////
|
---|
1096 | # Reporting methods
|
---|
1097 | #/////////////////////////////////////////////////////////////////
|
---|
1098 |
|
---|
1099 | def report_start(self, out, test, example):
|
---|
1100 | """
|
---|
1101 | Report that the test runner is about to process the given
|
---|
1102 | example. (Only displays a message if verbose=True)
|
---|
1103 | """
|
---|
1104 | if self._verbose:
|
---|
1105 | if example.want:
|
---|
1106 | out('Trying:\n' + _indent(example.source) +
|
---|
1107 | 'Expecting:\n' + _indent(example.want))
|
---|
1108 | else:
|
---|
1109 | out('Trying:\n' + _indent(example.source) +
|
---|
1110 | 'Expecting nothing\n')
|
---|
1111 |
|
---|
1112 | def report_success(self, out, test, example, got):
|
---|
1113 | """
|
---|
1114 | Report that the given example ran successfully. (Only
|
---|
1115 | displays a message if verbose=True)
|
---|
1116 | """
|
---|
1117 | if self._verbose:
|
---|
1118 | out("ok\n")
|
---|
1119 |
|
---|
1120 | def report_failure(self, out, test, example, got):
|
---|
1121 | """
|
---|
1122 | Report that the given example failed.
|
---|
1123 | """
|
---|
1124 | out(self._failure_header(test, example) +
|
---|
1125 | self._checker.output_difference(example, got, self.optionflags))
|
---|
1126 |
|
---|
1127 | def report_unexpected_exception(self, out, test, example, exc_info):
|
---|
1128 | """
|
---|
1129 | Report that the given example raised an unexpected exception.
|
---|
1130 | """
|
---|
1131 | out(self._failure_header(test, example) +
|
---|
1132 | 'Exception raised:\n' + _indent(_exception_traceback(exc_info)))
|
---|
1133 |
|
---|
1134 | def _failure_header(self, test, example):
|
---|
1135 | out = [self.DIVIDER]
|
---|
1136 | if test.filename:
|
---|
1137 | if test.lineno is not None and example.lineno is not None:
|
---|
1138 | lineno = test.lineno + example.lineno + 1
|
---|
1139 | else:
|
---|
1140 | lineno = '?'
|
---|
1141 | out.append('File "%s", line %s, in %s' %
|
---|
1142 | (test.filename, lineno, test.name))
|
---|
1143 | else:
|
---|
1144 | out.append('Line %s, in %s' % (example.lineno+1, test.name))
|
---|
1145 | out.append('Failed example:')
|
---|
1146 | source = example.source
|
---|
1147 | out.append(_indent(source))
|
---|
1148 | return '\n'.join(out)
|
---|
1149 |
|
---|
1150 | #/////////////////////////////////////////////////////////////////
|
---|
1151 | # DocTest Running
|
---|
1152 | #/////////////////////////////////////////////////////////////////
|
---|
1153 |
|
---|
1154 | def __run(self, test, compileflags, out):
|
---|
1155 | """
|
---|
1156 | Run the examples in `test`. Write the outcome of each example
|
---|
1157 | with one of the `DocTestRunner.report_*` methods, using the
|
---|
1158 | writer function `out`. `compileflags` is the set of compiler
|
---|
1159 | flags that should be used to execute examples. Return a tuple
|
---|
1160 | `(f, t)`, where `t` is the number of examples tried, and `f`
|
---|
1161 | is the number of examples that failed. The examples are run
|
---|
1162 | in the namespace `test.globs`.
|
---|
1163 | """
|
---|
1164 | # Keep track of the number of failures and tries.
|
---|
1165 | failures = tries = 0
|
---|
1166 |
|
---|
1167 | # Save the option flags (since option directives can be used
|
---|
1168 | # to modify them).
|
---|
1169 | original_optionflags = self.optionflags
|
---|
1170 |
|
---|
1171 | SUCCESS, FAILURE, BOOM = range(3) # `outcome` state
|
---|
1172 |
|
---|
1173 | check = self._checker.check_output
|
---|
1174 |
|
---|
1175 | # Process each example.
|
---|
1176 | for examplenum, example in enumerate(test.examples):
|
---|
1177 |
|
---|
1178 | # If REPORT_ONLY_FIRST_FAILURE is set, then supress
|
---|
1179 | # reporting after the first failure.
|
---|
1180 | quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and
|
---|
1181 | failures > 0)
|
---|
1182 |
|
---|
1183 | # Merge in the example's options.
|
---|
1184 | self.optionflags = original_optionflags
|
---|
1185 | if example.options:
|
---|
1186 | for (optionflag, val) in example.options.items():
|
---|
1187 | if val:
|
---|
1188 | self.optionflags |= optionflag
|
---|
1189 | else:
|
---|
1190 | self.optionflags &= ~optionflag
|
---|
1191 |
|
---|
1192 | # If 'SKIP' is set, then skip this example.
|
---|
1193 | if self.optionflags & SKIP:
|
---|
1194 | continue
|
---|
1195 |
|
---|
1196 | # Record that we started this example.
|
---|
1197 | tries += 1
|
---|
1198 | if not quiet:
|
---|
1199 | self.report_start(out, test, example)
|
---|
1200 |
|
---|
1201 | # Use a special filename for compile(), so we can retrieve
|
---|
1202 | # the source code during interactive debugging (see
|
---|
1203 | # __patched_linecache_getlines).
|
---|
1204 | filename = '<doctest %s[%d]>' % (test.name, examplenum)
|
---|
1205 |
|
---|
1206 | # Run the example in the given context (globs), and record
|
---|
1207 | # any exception that gets raised. (But don't intercept
|
---|
1208 | # keyboard interrupts.)
|
---|
1209 | try:
|
---|
1210 | # Don't blink! This is where the user's code gets run.
|
---|
1211 | exec compile(example.source, filename, "single",
|
---|
1212 | compileflags, 1) in test.globs
|
---|
1213 | self.debugger.set_continue() # ==== Example Finished ====
|
---|
1214 | exception = None
|
---|
1215 | except KeyboardInterrupt:
|
---|
1216 | raise
|
---|
1217 | except:
|
---|
1218 | exception = sys.exc_info()
|
---|
1219 | self.debugger.set_continue() # ==== Example Finished ====
|
---|
1220 |
|
---|
1221 | got = self._fakeout.getvalue() # the actual output
|
---|
1222 | self._fakeout.truncate(0)
|
---|
1223 | outcome = FAILURE # guilty until proved innocent or insane
|
---|
1224 |
|
---|
1225 | # If the example executed without raising any exceptions,
|
---|
1226 | # verify its output.
|
---|
1227 | if exception is None:
|
---|
1228 | if check(example.want, got, self.optionflags):
|
---|
1229 | outcome = SUCCESS
|
---|
1230 |
|
---|
1231 | # The example raised an exception: check if it was expected.
|
---|
1232 | else:
|
---|
1233 | exc_info = sys.exc_info()
|
---|
1234 | exc_msg = traceback.format_exception_only(*exc_info[:2])[-1]
|
---|
1235 | if not quiet:
|
---|
1236 | got += _exception_traceback(exc_info)
|
---|
1237 |
|
---|
1238 | # If `example.exc_msg` is None, then we weren't expecting
|
---|
1239 | # an exception.
|
---|
1240 | if example.exc_msg is None:
|
---|
1241 | outcome = BOOM
|
---|
1242 |
|
---|
1243 | # We expected an exception: see whether it matches.
|
---|
1244 | elif check(example.exc_msg, exc_msg, self.optionflags):
|
---|
1245 | outcome = SUCCESS
|
---|
1246 |
|
---|
1247 | # Another chance if they didn't care about the detail.
|
---|
1248 | elif self.optionflags & IGNORE_EXCEPTION_DETAIL:
|
---|
1249 | m1 = re.match(r'[^:]*:', example.exc_msg)
|
---|
1250 | m2 = re.match(r'[^:]*:', exc_msg)
|
---|
1251 | if m1 and m2 and check(m1.group(0), m2.group(0),
|
---|
1252 | self.optionflags):
|
---|
1253 | outcome = SUCCESS
|
---|
1254 |
|
---|
1255 | # Report the outcome.
|
---|
1256 | if outcome is SUCCESS:
|
---|
1257 | if not quiet:
|
---|
1258 | self.report_success(out, test, example, got)
|
---|
1259 | elif outcome is FAILURE:
|
---|
1260 | if not quiet:
|
---|
1261 | self.report_failure(out, test, example, got)
|
---|
1262 | failures += 1
|
---|
1263 | elif outcome is BOOM:
|
---|
1264 | if not quiet:
|
---|
1265 | self.report_unexpected_exception(out, test, example,
|
---|
1266 | exc_info)
|
---|
1267 | failures += 1
|
---|
1268 | else:
|
---|
1269 | assert False, ("unknown outcome", outcome)
|
---|
1270 |
|
---|
1271 | # Restore the option flags (in case they were modified)
|
---|
1272 | self.optionflags = original_optionflags
|
---|
1273 |
|
---|
1274 | # Record and return the number of failures and tries.
|
---|
1275 | self.__record_outcome(test, failures, tries)
|
---|
1276 | return failures, tries
|
---|
1277 |
|
---|
1278 | def __record_outcome(self, test, f, t):
|
---|
1279 | """
|
---|
1280 | Record the fact that the given DocTest (`test`) generated `f`
|
---|
1281 | failures out of `t` tried examples.
|
---|
1282 | """
|
---|
1283 | f2, t2 = self._name2ft.get(test.name, (0,0))
|
---|
1284 | self._name2ft[test.name] = (f+f2, t+t2)
|
---|
1285 | self.failures += f
|
---|
1286 | self.tries += t
|
---|
1287 |
|
---|
1288 | __LINECACHE_FILENAME_RE = re.compile(r'<doctest '
|
---|
1289 | r'(?P<name>[\w\.]+)'
|
---|
1290 | r'\[(?P<examplenum>\d+)\]>$')
|
---|
1291 | def __patched_linecache_getlines(self, filename, module_globals=None):
|
---|
1292 | m = self.__LINECACHE_FILENAME_RE.match(filename)
|
---|
1293 | if m and m.group('name') == self.test.name:
|
---|
1294 | example = self.test.examples[int(m.group('examplenum'))]
|
---|
1295 | return example.source.splitlines(True)
|
---|
1296 | else:
|
---|
1297 | return self.save_linecache_getlines(filename, module_globals)
|
---|
1298 |
|
---|
1299 | def run(self, test, compileflags=None, out=None, clear_globs=True):
|
---|
1300 | """
|
---|
1301 | Run the examples in `test`, and display the results using the
|
---|
1302 | writer function `out`.
|
---|
1303 |
|
---|
1304 | The examples are run in the namespace `test.globs`. If
|
---|
1305 | `clear_globs` is true (the default), then this namespace will
|
---|
1306 | be cleared after the test runs, to help with garbage
|
---|
1307 | collection. If you would like to examine the namespace after
|
---|
1308 | the test completes, then use `clear_globs=False`.
|
---|
1309 |
|
---|
1310 | `compileflags` gives the set of flags that should be used by
|
---|
1311 | the Python compiler when running the examples. If not
|
---|
1312 | specified, then it will default to the set of future-import
|
---|
1313 | flags that apply to `globs`.
|
---|
1314 |
|
---|
1315 | The output of each example is checked using
|
---|
1316 | `DocTestRunner.check_output`, and the results are formatted by
|
---|
1317 | the `DocTestRunner.report_*` methods.
|
---|
1318 | """
|
---|
1319 | self.test = test
|
---|
1320 |
|
---|
1321 | if compileflags is None:
|
---|
1322 | compileflags = _extract_future_flags(test.globs)
|
---|
1323 |
|
---|
1324 | save_stdout = sys.stdout
|
---|
1325 | if out is None:
|
---|
1326 | out = save_stdout.write
|
---|
1327 | sys.stdout = self._fakeout
|
---|
1328 |
|
---|
1329 | # Patch pdb.set_trace to restore sys.stdout during interactive
|
---|
1330 | # debugging (so it's not still redirected to self._fakeout).
|
---|
1331 | # Note that the interactive output will go to *our*
|
---|
1332 | # save_stdout, even if that's not the real sys.stdout; this
|
---|
1333 | # allows us to write test cases for the set_trace behavior.
|
---|
1334 | save_set_trace = pdb.set_trace
|
---|
1335 | self.debugger = _OutputRedirectingPdb(save_stdout)
|
---|
1336 | self.debugger.reset()
|
---|
1337 | pdb.set_trace = self.debugger.set_trace
|
---|
1338 |
|
---|
1339 | # Patch linecache.getlines, so we can see the example's source
|
---|
1340 | # when we're inside the debugger.
|
---|
1341 | self.save_linecache_getlines = linecache.getlines
|
---|
1342 | linecache.getlines = self.__patched_linecache_getlines
|
---|
1343 |
|
---|
1344 | try:
|
---|
1345 | return self.__run(test, compileflags, out)
|
---|
1346 | finally:
|
---|
1347 | sys.stdout = save_stdout
|
---|
1348 | pdb.set_trace = save_set_trace
|
---|
1349 | linecache.getlines = self.save_linecache_getlines
|
---|
1350 | if clear_globs:
|
---|
1351 | test.globs.clear()
|
---|
1352 |
|
---|
1353 | #/////////////////////////////////////////////////////////////////
|
---|
1354 | # Summarization
|
---|
1355 | #/////////////////////////////////////////////////////////////////
|
---|
1356 | def summarize(self, verbose=None):
|
---|
1357 | """
|
---|
1358 | Print a summary of all the test cases that have been run by
|
---|
1359 | this DocTestRunner, and return a tuple `(f, t)`, where `f` is
|
---|
1360 | the total number of failed examples, and `t` is the total
|
---|
1361 | number of tried examples.
|
---|
1362 |
|
---|
1363 | The optional `verbose` argument controls how detailed the
|
---|
1364 | summary is. If the verbosity is not specified, then the
|
---|
1365 | DocTestRunner's verbosity is used.
|
---|
1366 | """
|
---|
1367 | if verbose is None:
|
---|
1368 | verbose = self._verbose
|
---|
1369 | notests = []
|
---|
1370 | passed = []
|
---|
1371 | failed = []
|
---|
1372 | totalt = totalf = 0
|
---|
1373 | for x in self._name2ft.items():
|
---|
1374 | name, (f, t) = x
|
---|
1375 | assert f <= t
|
---|
1376 | totalt += t
|
---|
1377 | totalf += f
|
---|
1378 | if t == 0:
|
---|
1379 | notests.append(name)
|
---|
1380 | elif f == 0:
|
---|
1381 | passed.append( (name, t) )
|
---|
1382 | else:
|
---|
1383 | failed.append(x)
|
---|
1384 | if verbose:
|
---|
1385 | if notests:
|
---|
1386 | print len(notests), "items had no tests:"
|
---|
1387 | notests.sort()
|
---|
1388 | for thing in notests:
|
---|
1389 | print " ", thing
|
---|
1390 | if passed:
|
---|
1391 | print len(passed), "items passed all tests:"
|
---|
1392 | passed.sort()
|
---|
1393 | for thing, count in passed:
|
---|
1394 | print " %3d tests in %s" % (count, thing)
|
---|
1395 | if failed:
|
---|
1396 | print self.DIVIDER
|
---|
1397 | print len(failed), "items had failures:"
|
---|
1398 | failed.sort()
|
---|
1399 | for thing, (f, t) in failed:
|
---|
1400 | print " %3d of %3d in %s" % (f, t, thing)
|
---|
1401 | if verbose:
|
---|
1402 | print totalt, "tests in", len(self._name2ft), "items."
|
---|
1403 | print totalt - totalf, "passed and", totalf, "failed."
|
---|
1404 | if totalf:
|
---|
1405 | print "***Test Failed***", totalf, "failures."
|
---|
1406 | elif verbose:
|
---|
1407 | print "Test passed."
|
---|
1408 | return totalf, totalt
|
---|
1409 |
|
---|
1410 | #/////////////////////////////////////////////////////////////////
|
---|
1411 | # Backward compatibility cruft to maintain doctest.master.
|
---|
1412 | #/////////////////////////////////////////////////////////////////
|
---|
1413 | def merge(self, other):
|
---|
1414 | d = self._name2ft
|
---|
1415 | for name, (f, t) in other._name2ft.items():
|
---|
1416 | if name in d:
|
---|
1417 | print "*** DocTestRunner.merge: '" + name + "' in both" \
|
---|
1418 | " testers; summing outcomes."
|
---|
1419 | f2, t2 = d[name]
|
---|
1420 | f = f + f2
|
---|
1421 | t = t + t2
|
---|
1422 | d[name] = f, t
|
---|
1423 |
|
---|
1424 | class OutputChecker:
|
---|
1425 | """
|
---|
1426 | A class used to check the whether the actual output from a doctest
|
---|
1427 | example matches the expected output. `OutputChecker` defines two
|
---|
1428 | methods: `check_output`, which compares a given pair of outputs,
|
---|
1429 | and returns true if they match; and `output_difference`, which
|
---|
1430 | returns a string describing the differences between two outputs.
|
---|
1431 | """
|
---|
1432 | def check_output(self, want, got, optionflags):
|
---|
1433 | """
|
---|
1434 | Return True iff the actual output from an example (`got`)
|
---|
1435 | matches the expected output (`want`). These strings are
|
---|
1436 | always considered to match if they are identical; but
|
---|
1437 | depending on what option flags the test runner is using,
|
---|
1438 | several non-exact match types are also possible. See the
|
---|
1439 | documentation for `TestRunner` for more information about
|
---|
1440 | option flags.
|
---|
1441 | """
|
---|
1442 | # Handle the common case first, for efficiency:
|
---|
1443 | # if they're string-identical, always return true.
|
---|
1444 | if got == want:
|
---|
1445 | return True
|
---|
1446 |
|
---|
1447 | # The values True and False replaced 1 and 0 as the return
|
---|
1448 | # value for boolean comparisons in Python 2.3.
|
---|
1449 | if not (optionflags & DONT_ACCEPT_TRUE_FOR_1):
|
---|
1450 | if (got,want) == ("True\n", "1\n"):
|
---|
1451 | return True
|
---|
1452 | if (got,want) == ("False\n", "0\n"):
|
---|
1453 | return True
|
---|
1454 |
|
---|
1455 | # <BLANKLINE> can be used as a special sequence to signify a
|
---|
1456 | # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used.
|
---|
1457 | if not (optionflags & DONT_ACCEPT_BLANKLINE):
|
---|
1458 | # Replace <BLANKLINE> in want with a blank line.
|
---|
1459 | want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER),
|
---|
1460 | '', want)
|
---|
1461 | # If a line in got contains only spaces, then remove the
|
---|
1462 | # spaces.
|
---|
1463 | got = re.sub('(?m)^\s*?$', '', got)
|
---|
1464 | if got == want:
|
---|
1465 | return True
|
---|
1466 |
|
---|
1467 | # This flag causes doctest to ignore any differences in the
|
---|
1468 | # contents of whitespace strings. Note that this can be used
|
---|
1469 | # in conjunction with the ELLIPSIS flag.
|
---|
1470 | if optionflags & NORMALIZE_WHITESPACE:
|
---|
1471 | got = ' '.join(got.split())
|
---|
1472 | want = ' '.join(want.split())
|
---|
1473 | if got == want:
|
---|
1474 | return True
|
---|
1475 |
|
---|
1476 | # The ELLIPSIS flag says to let the sequence "..." in `want`
|
---|
1477 | # match any substring in `got`.
|
---|
1478 | if optionflags & ELLIPSIS:
|
---|
1479 | if _ellipsis_match(want, got):
|
---|
1480 | return True
|
---|
1481 |
|
---|
1482 | # We didn't find any match; return false.
|
---|
1483 | return False
|
---|
1484 |
|
---|
1485 | # Should we do a fancy diff?
|
---|
1486 | def _do_a_fancy_diff(self, want, got, optionflags):
|
---|
1487 | # Not unless they asked for a fancy diff.
|
---|
1488 | if not optionflags & (REPORT_UDIFF |
|
---|
1489 | REPORT_CDIFF |
|
---|
1490 | REPORT_NDIFF):
|
---|
1491 | return False
|
---|
1492 |
|
---|
1493 | # If expected output uses ellipsis, a meaningful fancy diff is
|
---|
1494 | # too hard ... or maybe not. In two real-life failures Tim saw,
|
---|
1495 | # a diff was a major help anyway, so this is commented out.
|
---|
1496 | # [todo] _ellipsis_match() knows which pieces do and don't match,
|
---|
1497 | # and could be the basis for a kick-ass diff in this case.
|
---|
1498 | ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want:
|
---|
1499 | ## return False
|
---|
1500 |
|
---|
1501 | # ndiff does intraline difference marking, so can be useful even
|
---|
1502 | # for 1-line differences.
|
---|
1503 | if optionflags & REPORT_NDIFF:
|
---|
1504 | return True
|
---|
1505 |
|
---|
1506 | # The other diff types need at least a few lines to be helpful.
|
---|
1507 | return want.count('\n') > 2 and got.count('\n') > 2
|
---|
1508 |
|
---|
1509 | def output_difference(self, example, got, optionflags):
|
---|
1510 | """
|
---|
1511 | Return a string describing the differences between the
|
---|
1512 | expected output for a given example (`example`) and the actual
|
---|
1513 | output (`got`). `optionflags` is the set of option flags used
|
---|
1514 | to compare `want` and `got`.
|
---|
1515 | """
|
---|
1516 | want = example.want
|
---|
1517 | # If <BLANKLINE>s are being used, then replace blank lines
|
---|
1518 | # with <BLANKLINE> in the actual output string.
|
---|
1519 | if not (optionflags & DONT_ACCEPT_BLANKLINE):
|
---|
1520 | got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got)
|
---|
1521 |
|
---|
1522 | # Check if we should use diff.
|
---|
1523 | if self._do_a_fancy_diff(want, got, optionflags):
|
---|
1524 | # Split want & got into lines.
|
---|
1525 | want_lines = want.splitlines(True) # True == keep line ends
|
---|
1526 | got_lines = got.splitlines(True)
|
---|
1527 | # Use difflib to find their differences.
|
---|
1528 | if optionflags & REPORT_UDIFF:
|
---|
1529 | diff = difflib.unified_diff(want_lines, got_lines, n=2)
|
---|
1530 | diff = list(diff)[2:] # strip the diff header
|
---|
1531 | kind = 'unified diff with -expected +actual'
|
---|
1532 | elif optionflags & REPORT_CDIFF:
|
---|
1533 | diff = difflib.context_diff(want_lines, got_lines, n=2)
|
---|
1534 | diff = list(diff)[2:] # strip the diff header
|
---|
1535 | kind = 'context diff with expected followed by actual'
|
---|
1536 | elif optionflags & REPORT_NDIFF:
|
---|
1537 | engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
|
---|
1538 | diff = list(engine.compare(want_lines, got_lines))
|
---|
1539 | kind = 'ndiff with -expected +actual'
|
---|
1540 | else:
|
---|
1541 | assert 0, 'Bad diff option'
|
---|
1542 | # Remove trailing whitespace on diff output.
|
---|
1543 | diff = [line.rstrip() + '\n' for line in diff]
|
---|
1544 | return 'Differences (%s):\n' % kind + _indent(''.join(diff))
|
---|
1545 |
|
---|
1546 | # If we're not using diff, then simply list the expected
|
---|
1547 | # output followed by the actual output.
|
---|
1548 | if want and got:
|
---|
1549 | return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got))
|
---|
1550 | elif want:
|
---|
1551 | return 'Expected:\n%sGot nothing\n' % _indent(want)
|
---|
1552 | elif got:
|
---|
1553 | return 'Expected nothing\nGot:\n%s' % _indent(got)
|
---|
1554 | else:
|
---|
1555 | return 'Expected nothing\nGot nothing\n'
|
---|
1556 |
|
---|
1557 | class DocTestFailure(Exception):
|
---|
1558 | """A DocTest example has failed in debugging mode.
|
---|
1559 |
|
---|
1560 | The exception instance has variables:
|
---|
1561 |
|
---|
1562 | - test: the DocTest object being run
|
---|
1563 |
|
---|
1564 | - example: the Example object that failed
|
---|
1565 |
|
---|
1566 | - got: the actual output
|
---|
1567 | """
|
---|
1568 | def __init__(self, test, example, got):
|
---|
1569 | self.test = test
|
---|
1570 | self.example = example
|
---|
1571 | self.got = got
|
---|
1572 |
|
---|
1573 | def __str__(self):
|
---|
1574 | return str(self.test)
|
---|
1575 |
|
---|
1576 | class UnexpectedException(Exception):
|
---|
1577 | """A DocTest example has encountered an unexpected exception
|
---|
1578 |
|
---|
1579 | The exception instance has variables:
|
---|
1580 |
|
---|
1581 | - test: the DocTest object being run
|
---|
1582 |
|
---|
1583 | - example: the Example object that failed
|
---|
1584 |
|
---|
1585 | - exc_info: the exception info
|
---|
1586 | """
|
---|
1587 | def __init__(self, test, example, exc_info):
|
---|
1588 | self.test = test
|
---|
1589 | self.example = example
|
---|
1590 | self.exc_info = exc_info
|
---|
1591 |
|
---|
1592 | def __str__(self):
|
---|
1593 | return str(self.test)
|
---|
1594 |
|
---|
1595 | class DebugRunner(DocTestRunner):
|
---|
1596 | r"""Run doc tests but raise an exception as soon as there is a failure.
|
---|
1597 |
|
---|
1598 | If an unexpected exception occurs, an UnexpectedException is raised.
|
---|
1599 | It contains the test, the example, and the original exception:
|
---|
1600 |
|
---|
1601 | >>> runner = DebugRunner(verbose=False)
|
---|
1602 | >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42',
|
---|
1603 | ... {}, 'foo', 'foo.py', 0)
|
---|
1604 | >>> try:
|
---|
1605 | ... runner.run(test)
|
---|
1606 | ... except UnexpectedException, failure:
|
---|
1607 | ... pass
|
---|
1608 |
|
---|
1609 | >>> failure.test is test
|
---|
1610 | True
|
---|
1611 |
|
---|
1612 | >>> failure.example.want
|
---|
1613 | '42\n'
|
---|
1614 |
|
---|
1615 | >>> exc_info = failure.exc_info
|
---|
1616 | >>> raise exc_info[0], exc_info[1], exc_info[2]
|
---|
1617 | Traceback (most recent call last):
|
---|
1618 | ...
|
---|
1619 | KeyError
|
---|
1620 |
|
---|
1621 | We wrap the original exception to give the calling application
|
---|
1622 | access to the test and example information.
|
---|
1623 |
|
---|
1624 | If the output doesn't match, then a DocTestFailure is raised:
|
---|
1625 |
|
---|
1626 | >>> test = DocTestParser().get_doctest('''
|
---|
1627 | ... >>> x = 1
|
---|
1628 | ... >>> x
|
---|
1629 | ... 2
|
---|
1630 | ... ''', {}, 'foo', 'foo.py', 0)
|
---|
1631 |
|
---|
1632 | >>> try:
|
---|
1633 | ... runner.run(test)
|
---|
1634 | ... except DocTestFailure, failure:
|
---|
1635 | ... pass
|
---|
1636 |
|
---|
1637 | DocTestFailure objects provide access to the test:
|
---|
1638 |
|
---|
1639 | >>> failure.test is test
|
---|
1640 | True
|
---|
1641 |
|
---|
1642 | As well as to the example:
|
---|
1643 |
|
---|
1644 | >>> failure.example.want
|
---|
1645 | '2\n'
|
---|
1646 |
|
---|
1647 | and the actual output:
|
---|
1648 |
|
---|
1649 | >>> failure.got
|
---|
1650 | '1\n'
|
---|
1651 |
|
---|
1652 | If a failure or error occurs, the globals are left intact:
|
---|
1653 |
|
---|
1654 | >>> del test.globs['__builtins__']
|
---|
1655 | >>> test.globs
|
---|
1656 | {'x': 1}
|
---|
1657 |
|
---|
1658 | >>> test = DocTestParser().get_doctest('''
|
---|
1659 | ... >>> x = 2
|
---|
1660 | ... >>> raise KeyError
|
---|
1661 | ... ''', {}, 'foo', 'foo.py', 0)
|
---|
1662 |
|
---|
1663 | >>> runner.run(test)
|
---|
1664 | Traceback (most recent call last):
|
---|
1665 | ...
|
---|
1666 | UnexpectedException: <DocTest foo from foo.py:0 (2 examples)>
|
---|
1667 |
|
---|
1668 | >>> del test.globs['__builtins__']
|
---|
1669 | >>> test.globs
|
---|
1670 | {'x': 2}
|
---|
1671 |
|
---|
1672 | But the globals are cleared if there is no error:
|
---|
1673 |
|
---|
1674 | >>> test = DocTestParser().get_doctest('''
|
---|
1675 | ... >>> x = 2
|
---|
1676 | ... ''', {}, 'foo', 'foo.py', 0)
|
---|
1677 |
|
---|
1678 | >>> runner.run(test)
|
---|
1679 | (0, 1)
|
---|
1680 |
|
---|
1681 | >>> test.globs
|
---|
1682 | {}
|
---|
1683 |
|
---|
1684 | """
|
---|
1685 |
|
---|
1686 | def run(self, test, compileflags=None, out=None, clear_globs=True):
|
---|
1687 | r = DocTestRunner.run(self, test, compileflags, out, False)
|
---|
1688 | if clear_globs:
|
---|
1689 | test.globs.clear()
|
---|
1690 | return r
|
---|
1691 |
|
---|
1692 | def report_unexpected_exception(self, out, test, example, exc_info):
|
---|
1693 | raise UnexpectedException(test, example, exc_info)
|
---|
1694 |
|
---|
1695 | def report_failure(self, out, test, example, got):
|
---|
1696 | raise DocTestFailure(test, example, got)
|
---|
1697 |
|
---|
1698 | ######################################################################
|
---|
1699 | ## 6. Test Functions
|
---|
1700 | ######################################################################
|
---|
1701 | # These should be backwards compatible.
|
---|
1702 |
|
---|
1703 | # For backward compatibility, a global instance of a DocTestRunner
|
---|
1704 | # class, updated by testmod.
|
---|
1705 | master = None
|
---|
1706 |
|
---|
1707 | def testmod(m=None, name=None, globs=None, verbose=None,
|
---|
1708 | report=True, optionflags=0, extraglobs=None,
|
---|
1709 | raise_on_error=False, exclude_empty=False):
|
---|
1710 | """m=None, name=None, globs=None, verbose=None, report=True,
|
---|
1711 | optionflags=0, extraglobs=None, raise_on_error=False,
|
---|
1712 | exclude_empty=False
|
---|
1713 |
|
---|
1714 | Test examples in docstrings in functions and classes reachable
|
---|
1715 | from module m (or the current module if m is not supplied), starting
|
---|
1716 | with m.__doc__.
|
---|
1717 |
|
---|
1718 | Also test examples reachable from dict m.__test__ if it exists and is
|
---|
1719 | not None. m.__test__ maps names to functions, classes and strings;
|
---|
1720 | function and class docstrings are tested even if the name is private;
|
---|
1721 | strings are tested directly, as if they were docstrings.
|
---|
1722 |
|
---|
1723 | Return (#failures, #tests).
|
---|
1724 |
|
---|
1725 | See doctest.__doc__ for an overview.
|
---|
1726 |
|
---|
1727 | Optional keyword arg "name" gives the name of the module; by default
|
---|
1728 | use m.__name__.
|
---|
1729 |
|
---|
1730 | Optional keyword arg "globs" gives a dict to be used as the globals
|
---|
1731 | when executing examples; by default, use m.__dict__. A copy of this
|
---|
1732 | dict is actually used for each docstring, so that each docstring's
|
---|
1733 | examples start with a clean slate.
|
---|
1734 |
|
---|
1735 | Optional keyword arg "extraglobs" gives a dictionary that should be
|
---|
1736 | merged into the globals that are used to execute examples. By
|
---|
1737 | default, no extra globals are used. This is new in 2.4.
|
---|
1738 |
|
---|
1739 | Optional keyword arg "verbose" prints lots of stuff if true, prints
|
---|
1740 | only failures if false; by default, it's true iff "-v" is in sys.argv.
|
---|
1741 |
|
---|
1742 | Optional keyword arg "report" prints a summary at the end when true,
|
---|
1743 | else prints nothing at the end. In verbose mode, the summary is
|
---|
1744 | detailed, else very brief (in fact, empty if all tests passed).
|
---|
1745 |
|
---|
1746 | Optional keyword arg "optionflags" or's together module constants,
|
---|
1747 | and defaults to 0. This is new in 2.3. Possible values (see the
|
---|
1748 | docs for details):
|
---|
1749 |
|
---|
1750 | DONT_ACCEPT_TRUE_FOR_1
|
---|
1751 | DONT_ACCEPT_BLANKLINE
|
---|
1752 | NORMALIZE_WHITESPACE
|
---|
1753 | ELLIPSIS
|
---|
1754 | SKIP
|
---|
1755 | IGNORE_EXCEPTION_DETAIL
|
---|
1756 | REPORT_UDIFF
|
---|
1757 | REPORT_CDIFF
|
---|
1758 | REPORT_NDIFF
|
---|
1759 | REPORT_ONLY_FIRST_FAILURE
|
---|
1760 |
|
---|
1761 | Optional keyword arg "raise_on_error" raises an exception on the
|
---|
1762 | first unexpected exception or failure. This allows failures to be
|
---|
1763 | post-mortem debugged.
|
---|
1764 |
|
---|
1765 | Advanced tomfoolery: testmod runs methods of a local instance of
|
---|
1766 | class doctest.Tester, then merges the results into (or creates)
|
---|
1767 | global Tester instance doctest.master. Methods of doctest.master
|
---|
1768 | can be called directly too, if you want to do something unusual.
|
---|
1769 | Passing report=0 to testmod is especially useful then, to delay
|
---|
1770 | displaying a summary. Invoke doctest.master.summarize(verbose)
|
---|
1771 | when you're done fiddling.
|
---|
1772 | """
|
---|
1773 | global master
|
---|
1774 |
|
---|
1775 | # If no module was given, then use __main__.
|
---|
1776 | if m is None:
|
---|
1777 | # DWA - m will still be None if this wasn't invoked from the command
|
---|
1778 | # line, in which case the following TypeError is about as good an error
|
---|
1779 | # as we should expect
|
---|
1780 | m = sys.modules.get('__main__')
|
---|
1781 |
|
---|
1782 | # Check that we were actually given a module.
|
---|
1783 | if not inspect.ismodule(m):
|
---|
1784 | raise TypeError("testmod: module required; %r" % (m,))
|
---|
1785 |
|
---|
1786 | # If no name was given, then use the module's name.
|
---|
1787 | if name is None:
|
---|
1788 | name = m.__name__
|
---|
1789 |
|
---|
1790 | # Find, parse, and run all tests in the given module.
|
---|
1791 | finder = DocTestFinder(exclude_empty=exclude_empty)
|
---|
1792 |
|
---|
1793 | if raise_on_error:
|
---|
1794 | runner = DebugRunner(verbose=verbose, optionflags=optionflags)
|
---|
1795 | else:
|
---|
1796 | runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
|
---|
1797 |
|
---|
1798 | for test in finder.find(m, name, globs=globs, extraglobs=extraglobs):
|
---|
1799 | runner.run(test)
|
---|
1800 |
|
---|
1801 | if report:
|
---|
1802 | runner.summarize()
|
---|
1803 |
|
---|
1804 | if master is None:
|
---|
1805 | master = runner
|
---|
1806 | else:
|
---|
1807 | master.merge(runner)
|
---|
1808 |
|
---|
1809 | return runner.failures, runner.tries
|
---|
1810 |
|
---|
1811 | def testfile(filename, module_relative=True, name=None, package=None,
|
---|
1812 | globs=None, verbose=None, report=True, optionflags=0,
|
---|
1813 | extraglobs=None, raise_on_error=False, parser=DocTestParser(),
|
---|
1814 | encoding=None):
|
---|
1815 | """
|
---|
1816 | Test examples in the given file. Return (#failures, #tests).
|
---|
1817 |
|
---|
1818 | Optional keyword arg "module_relative" specifies how filenames
|
---|
1819 | should be interpreted:
|
---|
1820 |
|
---|
1821 | - If "module_relative" is True (the default), then "filename"
|
---|
1822 | specifies a module-relative path. By default, this path is
|
---|
1823 | relative to the calling module's directory; but if the
|
---|
1824 | "package" argument is specified, then it is relative to that
|
---|
1825 | package. To ensure os-independence, "filename" should use
|
---|
1826 | "/" characters to separate path segments, and should not
|
---|
1827 | be an absolute path (i.e., it may not begin with "/").
|
---|
1828 |
|
---|
1829 | - If "module_relative" is False, then "filename" specifies an
|
---|
1830 | os-specific path. The path may be absolute or relative (to
|
---|
1831 | the current working directory).
|
---|
1832 |
|
---|
1833 | Optional keyword arg "name" gives the name of the test; by default
|
---|
1834 | use the file's basename.
|
---|
1835 |
|
---|
1836 | Optional keyword argument "package" is a Python package or the
|
---|
1837 | name of a Python package whose directory should be used as the
|
---|
1838 | base directory for a module relative filename. If no package is
|
---|
1839 | specified, then the calling module's directory is used as the base
|
---|
1840 | directory for module relative filenames. It is an error to
|
---|
1841 | specify "package" if "module_relative" is False.
|
---|
1842 |
|
---|
1843 | Optional keyword arg "globs" gives a dict to be used as the globals
|
---|
1844 | when executing examples; by default, use {}. A copy of this dict
|
---|
1845 | is actually used for each docstring, so that each docstring's
|
---|
1846 | examples start with a clean slate.
|
---|
1847 |
|
---|
1848 | Optional keyword arg "extraglobs" gives a dictionary that should be
|
---|
1849 | merged into the globals that are used to execute examples. By
|
---|
1850 | default, no extra globals are used.
|
---|
1851 |
|
---|
1852 | Optional keyword arg "verbose" prints lots of stuff if true, prints
|
---|
1853 | only failures if false; by default, it's true iff "-v" is in sys.argv.
|
---|
1854 |
|
---|
1855 | Optional keyword arg "report" prints a summary at the end when true,
|
---|
1856 | else prints nothing at the end. In verbose mode, the summary is
|
---|
1857 | detailed, else very brief (in fact, empty if all tests passed).
|
---|
1858 |
|
---|
1859 | Optional keyword arg "optionflags" or's together module constants,
|
---|
1860 | and defaults to 0. Possible values (see the docs for details):
|
---|
1861 |
|
---|
1862 | DONT_ACCEPT_TRUE_FOR_1
|
---|
1863 | DONT_ACCEPT_BLANKLINE
|
---|
1864 | NORMALIZE_WHITESPACE
|
---|
1865 | ELLIPSIS
|
---|
1866 | SKIP
|
---|
1867 | IGNORE_EXCEPTION_DETAIL
|
---|
1868 | REPORT_UDIFF
|
---|
1869 | REPORT_CDIFF
|
---|
1870 | REPORT_NDIFF
|
---|
1871 | REPORT_ONLY_FIRST_FAILURE
|
---|
1872 |
|
---|
1873 | Optional keyword arg "raise_on_error" raises an exception on the
|
---|
1874 | first unexpected exception or failure. This allows failures to be
|
---|
1875 | post-mortem debugged.
|
---|
1876 |
|
---|
1877 | Optional keyword arg "parser" specifies a DocTestParser (or
|
---|
1878 | subclass) that should be used to extract tests from the files.
|
---|
1879 |
|
---|
1880 | Optional keyword arg "encoding" specifies an encoding that should
|
---|
1881 | be used to convert the file to unicode.
|
---|
1882 |
|
---|
1883 | Advanced tomfoolery: testmod runs methods of a local instance of
|
---|
1884 | class doctest.Tester, then merges the results into (or creates)
|
---|
1885 | global Tester instance doctest.master. Methods of doctest.master
|
---|
1886 | can be called directly too, if you want to do something unusual.
|
---|
1887 | Passing report=0 to testmod is especially useful then, to delay
|
---|
1888 | displaying a summary. Invoke doctest.master.summarize(verbose)
|
---|
1889 | when you're done fiddling.
|
---|
1890 | """
|
---|
1891 | global master
|
---|
1892 |
|
---|
1893 | if package and not module_relative:
|
---|
1894 | raise ValueError("Package may only be specified for module-"
|
---|
1895 | "relative paths.")
|
---|
1896 |
|
---|
1897 | # Relativize the path
|
---|
1898 | text, filename = _load_testfile(filename, package, module_relative)
|
---|
1899 |
|
---|
1900 | # If no name was given, then use the file's name.
|
---|
1901 | if name is None:
|
---|
1902 | name = os.path.basename(filename)
|
---|
1903 |
|
---|
1904 | # Assemble the globals.
|
---|
1905 | if globs is None:
|
---|
1906 | globs = {}
|
---|
1907 | else:
|
---|
1908 | globs = globs.copy()
|
---|
1909 | if extraglobs is not None:
|
---|
1910 | globs.update(extraglobs)
|
---|
1911 |
|
---|
1912 | if raise_on_error:
|
---|
1913 | runner = DebugRunner(verbose=verbose, optionflags=optionflags)
|
---|
1914 | else:
|
---|
1915 | runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
|
---|
1916 |
|
---|
1917 | if encoding is not None:
|
---|
1918 | text = text.decode(encoding)
|
---|
1919 |
|
---|
1920 | # Read the file, convert it to a test, and run it.
|
---|
1921 | test = parser.get_doctest(text, globs, name, filename, 0)
|
---|
1922 | runner.run(test)
|
---|
1923 |
|
---|
1924 | if report:
|
---|
1925 | runner.summarize()
|
---|
1926 |
|
---|
1927 | if master is None:
|
---|
1928 | master = runner
|
---|
1929 | else:
|
---|
1930 | master.merge(runner)
|
---|
1931 |
|
---|
1932 | return runner.failures, runner.tries
|
---|
1933 |
|
---|
1934 | def run_docstring_examples(f, globs, verbose=False, name="NoName",
|
---|
1935 | compileflags=None, optionflags=0):
|
---|
1936 | """
|
---|
1937 | Test examples in the given object's docstring (`f`), using `globs`
|
---|
1938 | as globals. Optional argument `name` is used in failure messages.
|
---|
1939 | If the optional argument `verbose` is true, then generate output
|
---|
1940 | even if there are no failures.
|
---|
1941 |
|
---|
1942 | `compileflags` gives the set of flags that should be used by the
|
---|
1943 | Python compiler when running the examples. If not specified, then
|
---|
1944 | it will default to the set of future-import flags that apply to
|
---|
1945 | `globs`.
|
---|
1946 |
|
---|
1947 | Optional keyword arg `optionflags` specifies options for the
|
---|
1948 | testing and output. See the documentation for `testmod` for more
|
---|
1949 | information.
|
---|
1950 | """
|
---|
1951 | # Find, parse, and run all tests in the given module.
|
---|
1952 | finder = DocTestFinder(verbose=verbose, recurse=False)
|
---|
1953 | runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
|
---|
1954 | for test in finder.find(f, name, globs=globs):
|
---|
1955 | runner.run(test, compileflags=compileflags)
|
---|
1956 |
|
---|
1957 | ######################################################################
|
---|
1958 | ## 7. Tester
|
---|
1959 | ######################################################################
|
---|
1960 | # This is provided only for backwards compatibility. It's not
|
---|
1961 | # actually used in any way.
|
---|
1962 |
|
---|
1963 | class Tester:
|
---|
1964 | def __init__(self, mod=None, globs=None, verbose=None, optionflags=0):
|
---|
1965 |
|
---|
1966 | warnings.warn("class Tester is deprecated; "
|
---|
1967 | "use class doctest.DocTestRunner instead",
|
---|
1968 | DeprecationWarning, stacklevel=2)
|
---|
1969 | if mod is None and globs is None:
|
---|
1970 | raise TypeError("Tester.__init__: must specify mod or globs")
|
---|
1971 | if mod is not None and not inspect.ismodule(mod):
|
---|
1972 | raise TypeError("Tester.__init__: mod must be a module; %r" %
|
---|
1973 | (mod,))
|
---|
1974 | if globs is None:
|
---|
1975 | globs = mod.__dict__
|
---|
1976 | self.globs = globs
|
---|
1977 |
|
---|
1978 | self.verbose = verbose
|
---|
1979 | self.optionflags = optionflags
|
---|
1980 | self.testfinder = DocTestFinder()
|
---|
1981 | self.testrunner = DocTestRunner(verbose=verbose,
|
---|
1982 | optionflags=optionflags)
|
---|
1983 |
|
---|
1984 | def runstring(self, s, name):
|
---|
1985 | test = DocTestParser().get_doctest(s, self.globs, name, None, None)
|
---|
1986 | if self.verbose:
|
---|
1987 | print "Running string", name
|
---|
1988 | (f,t) = self.testrunner.run(test)
|
---|
1989 | if self.verbose:
|
---|
1990 | print f, "of", t, "examples failed in string", name
|
---|
1991 | return (f,t)
|
---|
1992 |
|
---|
1993 | def rundoc(self, object, name=None, module=None):
|
---|
1994 | f = t = 0
|
---|
1995 | tests = self.testfinder.find(object, name, module=module,
|
---|
1996 | globs=self.globs)
|
---|
1997 | for test in tests:
|
---|
1998 | (f2, t2) = self.testrunner.run(test)
|
---|
1999 | (f,t) = (f+f2, t+t2)
|
---|
2000 | return (f,t)
|
---|
2001 |
|
---|
2002 | def rundict(self, d, name, module=None):
|
---|
2003 | import new
|
---|
2004 | m = new.module(name)
|
---|
2005 | m.__dict__.update(d)
|
---|
2006 | if module is None:
|
---|
2007 | module = False
|
---|
2008 | return self.rundoc(m, name, module)
|
---|
2009 |
|
---|
2010 | def run__test__(self, d, name):
|
---|
2011 | import new
|
---|
2012 | m = new.module(name)
|
---|
2013 | m.__test__ = d
|
---|
2014 | return self.rundoc(m, name)
|
---|
2015 |
|
---|
2016 | def summarize(self, verbose=None):
|
---|
2017 | return self.testrunner.summarize(verbose)
|
---|
2018 |
|
---|
2019 | def merge(self, other):
|
---|
2020 | self.testrunner.merge(other.testrunner)
|
---|
2021 |
|
---|
2022 | ######################################################################
|
---|
2023 | ## 8. Unittest Support
|
---|
2024 | ######################################################################
|
---|
2025 |
|
---|
2026 | _unittest_reportflags = 0
|
---|
2027 |
|
---|
2028 | def set_unittest_reportflags(flags):
|
---|
2029 | """Sets the unittest option flags.
|
---|
2030 |
|
---|
2031 | The old flag is returned so that a runner could restore the old
|
---|
2032 | value if it wished to:
|
---|
2033 |
|
---|
2034 | >>> import doctest
|
---|
2035 | >>> old = doctest._unittest_reportflags
|
---|
2036 | >>> doctest.set_unittest_reportflags(REPORT_NDIFF |
|
---|
2037 | ... REPORT_ONLY_FIRST_FAILURE) == old
|
---|
2038 | True
|
---|
2039 |
|
---|
2040 | >>> doctest._unittest_reportflags == (REPORT_NDIFF |
|
---|
2041 | ... REPORT_ONLY_FIRST_FAILURE)
|
---|
2042 | True
|
---|
2043 |
|
---|
2044 | Only reporting flags can be set:
|
---|
2045 |
|
---|
2046 | >>> doctest.set_unittest_reportflags(ELLIPSIS)
|
---|
2047 | Traceback (most recent call last):
|
---|
2048 | ...
|
---|
2049 | ValueError: ('Only reporting flags allowed', 8)
|
---|
2050 |
|
---|
2051 | >>> doctest.set_unittest_reportflags(old) == (REPORT_NDIFF |
|
---|
2052 | ... REPORT_ONLY_FIRST_FAILURE)
|
---|
2053 | True
|
---|
2054 | """
|
---|
2055 | global _unittest_reportflags
|
---|
2056 |
|
---|
2057 | if (flags & REPORTING_FLAGS) != flags:
|
---|
2058 | raise ValueError("Only reporting flags allowed", flags)
|
---|
2059 | old = _unittest_reportflags
|
---|
2060 | _unittest_reportflags = flags
|
---|
2061 | return old
|
---|
2062 |
|
---|
2063 |
|
---|
2064 | class DocTestCase(unittest.TestCase):
|
---|
2065 |
|
---|
2066 | def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
|
---|
2067 | checker=None):
|
---|
2068 |
|
---|
2069 | unittest.TestCase.__init__(self)
|
---|
2070 | self._dt_optionflags = optionflags
|
---|
2071 | self._dt_checker = checker
|
---|
2072 | self._dt_test = test
|
---|
2073 | self._dt_setUp = setUp
|
---|
2074 | self._dt_tearDown = tearDown
|
---|
2075 |
|
---|
2076 | def setUp(self):
|
---|
2077 | test = self._dt_test
|
---|
2078 |
|
---|
2079 | if self._dt_setUp is not None:
|
---|
2080 | self._dt_setUp(test)
|
---|
2081 |
|
---|
2082 | def tearDown(self):
|
---|
2083 | test = self._dt_test
|
---|
2084 |
|
---|
2085 | if self._dt_tearDown is not None:
|
---|
2086 | self._dt_tearDown(test)
|
---|
2087 |
|
---|
2088 | test.globs.clear()
|
---|
2089 |
|
---|
2090 | def runTest(self):
|
---|
2091 | test = self._dt_test
|
---|
2092 | old = sys.stdout
|
---|
2093 | new = StringIO()
|
---|
2094 | optionflags = self._dt_optionflags
|
---|
2095 |
|
---|
2096 | if not (optionflags & REPORTING_FLAGS):
|
---|
2097 | # The option flags don't include any reporting flags,
|
---|
2098 | # so add the default reporting flags
|
---|
2099 | optionflags |= _unittest_reportflags
|
---|
2100 |
|
---|
2101 | runner = DocTestRunner(optionflags=optionflags,
|
---|
2102 | checker=self._dt_checker, verbose=False)
|
---|
2103 |
|
---|
2104 | try:
|
---|
2105 | runner.DIVIDER = "-"*70
|
---|
2106 | failures, tries = runner.run(
|
---|
2107 | test, out=new.write, clear_globs=False)
|
---|
2108 | finally:
|
---|
2109 | sys.stdout = old
|
---|
2110 |
|
---|
2111 | if failures:
|
---|
2112 | raise self.failureException(self.format_failure(new.getvalue()))
|
---|
2113 |
|
---|
2114 | def format_failure(self, err):
|
---|
2115 | test = self._dt_test
|
---|
2116 | if test.lineno is None:
|
---|
2117 | lineno = 'unknown line number'
|
---|
2118 | else:
|
---|
2119 | lineno = '%s' % test.lineno
|
---|
2120 | lname = '.'.join(test.name.split('.')[-1:])
|
---|
2121 | return ('Failed doctest test for %s\n'
|
---|
2122 | ' File "%s", line %s, in %s\n\n%s'
|
---|
2123 | % (test.name, test.filename, lineno, lname, err)
|
---|
2124 | )
|
---|
2125 |
|
---|
2126 | def debug(self):
|
---|
2127 | r"""Run the test case without results and without catching exceptions
|
---|
2128 |
|
---|
2129 | The unit test framework includes a debug method on test cases
|
---|
2130 | and test suites to support post-mortem debugging. The test code
|
---|
2131 | is run in such a way that errors are not caught. This way a
|
---|
2132 | caller can catch the errors and initiate post-mortem debugging.
|
---|
2133 |
|
---|
2134 | The DocTestCase provides a debug method that raises
|
---|
2135 | UnexpectedException errors if there is an unexepcted
|
---|
2136 | exception:
|
---|
2137 |
|
---|
2138 | >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42',
|
---|
2139 | ... {}, 'foo', 'foo.py', 0)
|
---|
2140 | >>> case = DocTestCase(test)
|
---|
2141 | >>> try:
|
---|
2142 | ... case.debug()
|
---|
2143 | ... except UnexpectedException, failure:
|
---|
2144 | ... pass
|
---|
2145 |
|
---|
2146 | The UnexpectedException contains the test, the example, and
|
---|
2147 | the original exception:
|
---|
2148 |
|
---|
2149 | >>> failure.test is test
|
---|
2150 | True
|
---|
2151 |
|
---|
2152 | >>> failure.example.want
|
---|
2153 | '42\n'
|
---|
2154 |
|
---|
2155 | >>> exc_info = failure.exc_info
|
---|
2156 | >>> raise exc_info[0], exc_info[1], exc_info[2]
|
---|
2157 | Traceback (most recent call last):
|
---|
2158 | ...
|
---|
2159 | KeyError
|
---|
2160 |
|
---|
2161 | If the output doesn't match, then a DocTestFailure is raised:
|
---|
2162 |
|
---|
2163 | >>> test = DocTestParser().get_doctest('''
|
---|
2164 | ... >>> x = 1
|
---|
2165 | ... >>> x
|
---|
2166 | ... 2
|
---|
2167 | ... ''', {}, 'foo', 'foo.py', 0)
|
---|
2168 | >>> case = DocTestCase(test)
|
---|
2169 |
|
---|
2170 | >>> try:
|
---|
2171 | ... case.debug()
|
---|
2172 | ... except DocTestFailure, failure:
|
---|
2173 | ... pass
|
---|
2174 |
|
---|
2175 | DocTestFailure objects provide access to the test:
|
---|
2176 |
|
---|
2177 | >>> failure.test is test
|
---|
2178 | True
|
---|
2179 |
|
---|
2180 | As well as to the example:
|
---|
2181 |
|
---|
2182 | >>> failure.example.want
|
---|
2183 | '2\n'
|
---|
2184 |
|
---|
2185 | and the actual output:
|
---|
2186 |
|
---|
2187 | >>> failure.got
|
---|
2188 | '1\n'
|
---|
2189 |
|
---|
2190 | """
|
---|
2191 |
|
---|
2192 | self.setUp()
|
---|
2193 | runner = DebugRunner(optionflags=self._dt_optionflags,
|
---|
2194 | checker=self._dt_checker, verbose=False)
|
---|
2195 | runner.run(self._dt_test)
|
---|
2196 | self.tearDown()
|
---|
2197 |
|
---|
2198 | def id(self):
|
---|
2199 | return self._dt_test.name
|
---|
2200 |
|
---|
2201 | def __repr__(self):
|
---|
2202 | name = self._dt_test.name.split('.')
|
---|
2203 | return "%s (%s)" % (name[-1], '.'.join(name[:-1]))
|
---|
2204 |
|
---|
2205 | __str__ = __repr__
|
---|
2206 |
|
---|
2207 | def shortDescription(self):
|
---|
2208 | return "Doctest: " + self._dt_test.name
|
---|
2209 |
|
---|
2210 | def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None,
|
---|
2211 | **options):
|
---|
2212 | """
|
---|
2213 | Convert doctest tests for a module to a unittest test suite.
|
---|
2214 |
|
---|
2215 | This converts each documentation string in a module that
|
---|
2216 | contains doctest tests to a unittest test case. If any of the
|
---|
2217 | tests in a doc string fail, then the test case fails. An exception
|
---|
2218 | is raised showing the name of the file containing the test and a
|
---|
2219 | (sometimes approximate) line number.
|
---|
2220 |
|
---|
2221 | The `module` argument provides the module to be tested. The argument
|
---|
2222 | can be either a module or a module name.
|
---|
2223 |
|
---|
2224 | If no argument is given, the calling module is used.
|
---|
2225 |
|
---|
2226 | A number of options may be provided as keyword arguments:
|
---|
2227 |
|
---|
2228 | setUp
|
---|
2229 | A set-up function. This is called before running the
|
---|
2230 | tests in each file. The setUp function will be passed a DocTest
|
---|
2231 | object. The setUp function can access the test globals as the
|
---|
2232 | globs attribute of the test passed.
|
---|
2233 |
|
---|
2234 | tearDown
|
---|
2235 | A tear-down function. This is called after running the
|
---|
2236 | tests in each file. The tearDown function will be passed a DocTest
|
---|
2237 | object. The tearDown function can access the test globals as the
|
---|
2238 | globs attribute of the test passed.
|
---|
2239 |
|
---|
2240 | globs
|
---|
2241 | A dictionary containing initial global variables for the tests.
|
---|
2242 |
|
---|
2243 | optionflags
|
---|
2244 | A set of doctest option flags expressed as an integer.
|
---|
2245 | """
|
---|
2246 |
|
---|
2247 | if test_finder is None:
|
---|
2248 | test_finder = DocTestFinder()
|
---|
2249 |
|
---|
2250 | module = _normalize_module(module)
|
---|
2251 | tests = test_finder.find(module, globs=globs, extraglobs=extraglobs)
|
---|
2252 | if globs is None:
|
---|
2253 | globs = module.__dict__
|
---|
2254 | if not tests:
|
---|
2255 | # Why do we want to do this? Because it reveals a bug that might
|
---|
2256 | # otherwise be hidden.
|
---|
2257 | raise ValueError(module, "has no tests")
|
---|
2258 |
|
---|
2259 | tests.sort()
|
---|
2260 | suite = unittest.TestSuite()
|
---|
2261 | for test in tests:
|
---|
2262 | if len(test.examples) == 0:
|
---|
2263 | continue
|
---|
2264 | if not test.filename:
|
---|
2265 | filename = module.__file__
|
---|
2266 | if filename[-4:] in (".pyc", ".pyo"):
|
---|
2267 | filename = filename[:-1]
|
---|
2268 | test.filename = filename
|
---|
2269 | suite.addTest(DocTestCase(test, **options))
|
---|
2270 |
|
---|
2271 | return suite
|
---|
2272 |
|
---|
2273 | class DocFileCase(DocTestCase):
|
---|
2274 |
|
---|
2275 | def id(self):
|
---|
2276 | return '_'.join(self._dt_test.name.split('.'))
|
---|
2277 |
|
---|
2278 | def __repr__(self):
|
---|
2279 | return self._dt_test.filename
|
---|
2280 | __str__ = __repr__
|
---|
2281 |
|
---|
2282 | def format_failure(self, err):
|
---|
2283 | return ('Failed doctest test for %s\n File "%s", line 0\n\n%s'
|
---|
2284 | % (self._dt_test.name, self._dt_test.filename, err)
|
---|
2285 | )
|
---|
2286 |
|
---|
2287 | def DocFileTest(path, module_relative=True, package=None,
|
---|
2288 | globs=None, parser=DocTestParser(),
|
---|
2289 | encoding=None, **options):
|
---|
2290 | if globs is None:
|
---|
2291 | globs = {}
|
---|
2292 | else:
|
---|
2293 | globs = globs.copy()
|
---|
2294 |
|
---|
2295 | if package and not module_relative:
|
---|
2296 | raise ValueError("Package may only be specified for module-"
|
---|
2297 | "relative paths.")
|
---|
2298 |
|
---|
2299 | # Relativize the path.
|
---|
2300 | doc, path = _load_testfile(path, package, module_relative)
|
---|
2301 |
|
---|
2302 | if "__file__" not in globs:
|
---|
2303 | globs["__file__"] = path
|
---|
2304 |
|
---|
2305 | # Find the file and read it.
|
---|
2306 | name = os.path.basename(path)
|
---|
2307 |
|
---|
2308 | # If an encoding is specified, use it to convert the file to unicode
|
---|
2309 | if encoding is not None:
|
---|
2310 | doc = doc.decode(encoding)
|
---|
2311 |
|
---|
2312 | # Convert it to a test, and wrap it in a DocFileCase.
|
---|
2313 | test = parser.get_doctest(doc, globs, name, path, 0)
|
---|
2314 | return DocFileCase(test, **options)
|
---|
2315 |
|
---|
2316 | def DocFileSuite(*paths, **kw):
|
---|
2317 | """A unittest suite for one or more doctest files.
|
---|
2318 |
|
---|
2319 | The path to each doctest file is given as a string; the
|
---|
2320 | interpretation of that string depends on the keyword argument
|
---|
2321 | "module_relative".
|
---|
2322 |
|
---|
2323 | A number of options may be provided as keyword arguments:
|
---|
2324 |
|
---|
2325 | module_relative
|
---|
2326 | If "module_relative" is True, then the given file paths are
|
---|
2327 | interpreted as os-independent module-relative paths. By
|
---|
2328 | default, these paths are relative to the calling module's
|
---|
2329 | directory; but if the "package" argument is specified, then
|
---|
2330 | they are relative to that package. To ensure os-independence,
|
---|
2331 | "filename" should use "/" characters to separate path
|
---|
2332 | segments, and may not be an absolute path (i.e., it may not
|
---|
2333 | begin with "/").
|
---|
2334 |
|
---|
2335 | If "module_relative" is False, then the given file paths are
|
---|
2336 | interpreted as os-specific paths. These paths may be absolute
|
---|
2337 | or relative (to the current working directory).
|
---|
2338 |
|
---|
2339 | package
|
---|
2340 | A Python package or the name of a Python package whose directory
|
---|
2341 | should be used as the base directory for module relative paths.
|
---|
2342 | If "package" is not specified, then the calling module's
|
---|
2343 | directory is used as the base directory for module relative
|
---|
2344 | filenames. It is an error to specify "package" if
|
---|
2345 | "module_relative" is False.
|
---|
2346 |
|
---|
2347 | setUp
|
---|
2348 | A set-up function. This is called before running the
|
---|
2349 | tests in each file. The setUp function will be passed a DocTest
|
---|
2350 | object. The setUp function can access the test globals as the
|
---|
2351 | globs attribute of the test passed.
|
---|
2352 |
|
---|
2353 | tearDown
|
---|
2354 | A tear-down function. This is called after running the
|
---|
2355 | tests in each file. The tearDown function will be passed a DocTest
|
---|
2356 | object. The tearDown function can access the test globals as the
|
---|
2357 | globs attribute of the test passed.
|
---|
2358 |
|
---|
2359 | globs
|
---|
2360 | A dictionary containing initial global variables for the tests.
|
---|
2361 |
|
---|
2362 | optionflags
|
---|
2363 | A set of doctest option flags expressed as an integer.
|
---|
2364 |
|
---|
2365 | parser
|
---|
2366 | A DocTestParser (or subclass) that should be used to extract
|
---|
2367 | tests from the files.
|
---|
2368 |
|
---|
2369 | encoding
|
---|
2370 | An encoding that will be used to convert the files to unicode.
|
---|
2371 | """
|
---|
2372 | suite = unittest.TestSuite()
|
---|
2373 |
|
---|
2374 | # We do this here so that _normalize_module is called at the right
|
---|
2375 | # level. If it were called in DocFileTest, then this function
|
---|
2376 | # would be the caller and we might guess the package incorrectly.
|
---|
2377 | if kw.get('module_relative', True):
|
---|
2378 | kw['package'] = _normalize_module(kw.get('package'))
|
---|
2379 |
|
---|
2380 | for path in paths:
|
---|
2381 | suite.addTest(DocFileTest(path, **kw))
|
---|
2382 |
|
---|
2383 | return suite
|
---|
2384 |
|
---|
2385 | ######################################################################
|
---|
2386 | ## 9. Debugging Support
|
---|
2387 | ######################################################################
|
---|
2388 |
|
---|
2389 | def script_from_examples(s):
|
---|
2390 | r"""Extract script from text with examples.
|
---|
2391 |
|
---|
2392 | Converts text with examples to a Python script. Example input is
|
---|
2393 | converted to regular code. Example output and all other words
|
---|
2394 | are converted to comments:
|
---|
2395 |
|
---|
2396 | >>> text = '''
|
---|
2397 | ... Here are examples of simple math.
|
---|
2398 | ...
|
---|
2399 | ... Python has super accurate integer addition
|
---|
2400 | ...
|
---|
2401 | ... >>> 2 + 2
|
---|
2402 | ... 5
|
---|
2403 | ...
|
---|
2404 | ... And very friendly error messages:
|
---|
2405 | ...
|
---|
2406 | ... >>> 1/0
|
---|
2407 | ... To Infinity
|
---|
2408 | ... And
|
---|
2409 | ... Beyond
|
---|
2410 | ...
|
---|
2411 | ... You can use logic if you want:
|
---|
2412 | ...
|
---|
2413 | ... >>> if 0:
|
---|
2414 | ... ... blah
|
---|
2415 | ... ... blah
|
---|
2416 | ... ...
|
---|
2417 | ...
|
---|
2418 | ... Ho hum
|
---|
2419 | ... '''
|
---|
2420 |
|
---|
2421 | >>> print script_from_examples(text)
|
---|
2422 | # Here are examples of simple math.
|
---|
2423 | #
|
---|
2424 | # Python has super accurate integer addition
|
---|
2425 | #
|
---|
2426 | 2 + 2
|
---|
2427 | # Expected:
|
---|
2428 | ## 5
|
---|
2429 | #
|
---|
2430 | # And very friendly error messages:
|
---|
2431 | #
|
---|
2432 | 1/0
|
---|
2433 | # Expected:
|
---|
2434 | ## To Infinity
|
---|
2435 | ## And
|
---|
2436 | ## Beyond
|
---|
2437 | #
|
---|
2438 | # You can use logic if you want:
|
---|
2439 | #
|
---|
2440 | if 0:
|
---|
2441 | blah
|
---|
2442 | blah
|
---|
2443 | #
|
---|
2444 | # Ho hum
|
---|
2445 | <BLANKLINE>
|
---|
2446 | """
|
---|
2447 | output = []
|
---|
2448 | for piece in DocTestParser().parse(s):
|
---|
2449 | if isinstance(piece, Example):
|
---|
2450 | # Add the example's source code (strip trailing NL)
|
---|
2451 | output.append(piece.source[:-1])
|
---|
2452 | # Add the expected output:
|
---|
2453 | want = piece.want
|
---|
2454 | if want:
|
---|
2455 | output.append('# Expected:')
|
---|
2456 | output += ['## '+l for l in want.split('\n')[:-1]]
|
---|
2457 | else:
|
---|
2458 | # Add non-example text.
|
---|
2459 | output += [_comment_line(l)
|
---|
2460 | for l in piece.split('\n')[:-1]]
|
---|
2461 |
|
---|
2462 | # Trim junk on both ends.
|
---|
2463 | while output and output[-1] == '#':
|
---|
2464 | output.pop()
|
---|
2465 | while output and output[0] == '#':
|
---|
2466 | output.pop(0)
|
---|
2467 | # Combine the output, and return it.
|
---|
2468 | # Add a courtesy newline to prevent exec from choking (see bug #1172785)
|
---|
2469 | return '\n'.join(output) + '\n'
|
---|
2470 |
|
---|
2471 | def testsource(module, name):
|
---|
2472 | """Extract the test sources from a doctest docstring as a script.
|
---|
2473 |
|
---|
2474 | Provide the module (or dotted name of the module) containing the
|
---|
2475 | test to be debugged and the name (within the module) of the object
|
---|
2476 | with the doc string with tests to be debugged.
|
---|
2477 | """
|
---|
2478 | module = _normalize_module(module)
|
---|
2479 | tests = DocTestFinder().find(module)
|
---|
2480 | test = [t for t in tests if t.name == name]
|
---|
2481 | if not test:
|
---|
2482 | raise ValueError(name, "not found in tests")
|
---|
2483 | test = test[0]
|
---|
2484 | testsrc = script_from_examples(test.docstring)
|
---|
2485 | return testsrc
|
---|
2486 |
|
---|
2487 | def debug_src(src, pm=False, globs=None):
|
---|
2488 | """Debug a single doctest docstring, in argument `src`'"""
|
---|
2489 | testsrc = script_from_examples(src)
|
---|
2490 | debug_script(testsrc, pm, globs)
|
---|
2491 |
|
---|
2492 | def debug_script(src, pm=False, globs=None):
|
---|
2493 | "Debug a test script. `src` is the script, as a string."
|
---|
2494 | import pdb
|
---|
2495 |
|
---|
2496 | # Note that tempfile.NameTemporaryFile() cannot be used. As the
|
---|
2497 | # docs say, a file so created cannot be opened by name a second time
|
---|
2498 | # on modern Windows boxes, and execfile() needs to open it.
|
---|
2499 | srcfilename = tempfile.mktemp(".py", "doctestdebug")
|
---|
2500 | f = open(srcfilename, 'w')
|
---|
2501 | f.write(src)
|
---|
2502 | f.close()
|
---|
2503 |
|
---|
2504 | try:
|
---|
2505 | if globs:
|
---|
2506 | globs = globs.copy()
|
---|
2507 | else:
|
---|
2508 | globs = {}
|
---|
2509 |
|
---|
2510 | if pm:
|
---|
2511 | try:
|
---|
2512 | execfile(srcfilename, globs, globs)
|
---|
2513 | except:
|
---|
2514 | print sys.exc_info()[1]
|
---|
2515 | pdb.post_mortem(sys.exc_info()[2])
|
---|
2516 | else:
|
---|
2517 | # Note that %r is vital here. '%s' instead can, e.g., cause
|
---|
2518 | # backslashes to get treated as metacharacters on Windows.
|
---|
2519 | pdb.run("execfile(%r)" % srcfilename, globs, globs)
|
---|
2520 |
|
---|
2521 | finally:
|
---|
2522 | os.remove(srcfilename)
|
---|
2523 |
|
---|
2524 | def debug(module, name, pm=False):
|
---|
2525 | """Debug a single doctest docstring.
|
---|
2526 |
|
---|
2527 | Provide the module (or dotted name of the module) containing the
|
---|
2528 | test to be debugged and the name (within the module) of the object
|
---|
2529 | with the docstring with tests to be debugged.
|
---|
2530 | """
|
---|
2531 | module = _normalize_module(module)
|
---|
2532 | testsrc = testsource(module, name)
|
---|
2533 | debug_script(testsrc, pm, module.__dict__)
|
---|
2534 |
|
---|
2535 | ######################################################################
|
---|
2536 | ## 10. Example Usage
|
---|
2537 | ######################################################################
|
---|
2538 | class _TestClass:
|
---|
2539 | """
|
---|
2540 | A pointless class, for sanity-checking of docstring testing.
|
---|
2541 |
|
---|
2542 | Methods:
|
---|
2543 | square()
|
---|
2544 | get()
|
---|
2545 |
|
---|
2546 | >>> _TestClass(13).get() + _TestClass(-12).get()
|
---|
2547 | 1
|
---|
2548 | >>> hex(_TestClass(13).square().get())
|
---|
2549 | '0xa9'
|
---|
2550 | """
|
---|
2551 |
|
---|
2552 | def __init__(self, val):
|
---|
2553 | """val -> _TestClass object with associated value val.
|
---|
2554 |
|
---|
2555 | >>> t = _TestClass(123)
|
---|
2556 | >>> print t.get()
|
---|
2557 | 123
|
---|
2558 | """
|
---|
2559 |
|
---|
2560 | self.val = val
|
---|
2561 |
|
---|
2562 | def square(self):
|
---|
2563 | """square() -> square TestClass's associated value
|
---|
2564 |
|
---|
2565 | >>> _TestClass(13).square().get()
|
---|
2566 | 169
|
---|
2567 | """
|
---|
2568 |
|
---|
2569 | self.val = self.val ** 2
|
---|
2570 | return self
|
---|
2571 |
|
---|
2572 | def get(self):
|
---|
2573 | """get() -> return TestClass's associated value.
|
---|
2574 |
|
---|
2575 | >>> x = _TestClass(-42)
|
---|
2576 | >>> print x.get()
|
---|
2577 | -42
|
---|
2578 | """
|
---|
2579 |
|
---|
2580 | return self.val
|
---|
2581 |
|
---|
2582 | __test__ = {"_TestClass": _TestClass,
|
---|
2583 | "string": r"""
|
---|
2584 | Example of a string object, searched as-is.
|
---|
2585 | >>> x = 1; y = 2
|
---|
2586 | >>> x + y, x * y
|
---|
2587 | (3, 2)
|
---|
2588 | """,
|
---|
2589 |
|
---|
2590 | "bool-int equivalence": r"""
|
---|
2591 | In 2.2, boolean expressions displayed
|
---|
2592 | 0 or 1. By default, we still accept
|
---|
2593 | them. This can be disabled by passing
|
---|
2594 | DONT_ACCEPT_TRUE_FOR_1 to the new
|
---|
2595 | optionflags argument.
|
---|
2596 | >>> 4 == 4
|
---|
2597 | 1
|
---|
2598 | >>> 4 == 4
|
---|
2599 | True
|
---|
2600 | >>> 4 > 4
|
---|
2601 | 0
|
---|
2602 | >>> 4 > 4
|
---|
2603 | False
|
---|
2604 | """,
|
---|
2605 |
|
---|
2606 | "blank lines": r"""
|
---|
2607 | Blank lines can be marked with <BLANKLINE>:
|
---|
2608 | >>> print 'foo\n\nbar\n'
|
---|
2609 | foo
|
---|
2610 | <BLANKLINE>
|
---|
2611 | bar
|
---|
2612 | <BLANKLINE>
|
---|
2613 | """,
|
---|
2614 |
|
---|
2615 | "ellipsis": r"""
|
---|
2616 | If the ellipsis flag is used, then '...' can be used to
|
---|
2617 | elide substrings in the desired output:
|
---|
2618 | >>> print range(1000) #doctest: +ELLIPSIS
|
---|
2619 | [0, 1, 2, ..., 999]
|
---|
2620 | """,
|
---|
2621 |
|
---|
2622 | "whitespace normalization": r"""
|
---|
2623 | If the whitespace normalization flag is used, then
|
---|
2624 | differences in whitespace are ignored.
|
---|
2625 | >>> print range(30) #doctest: +NORMALIZE_WHITESPACE
|
---|
2626 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
---|
2627 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
|
---|
2628 | 27, 28, 29]
|
---|
2629 | """,
|
---|
2630 | }
|
---|
2631 |
|
---|
2632 | def _test():
|
---|
2633 | r = unittest.TextTestRunner()
|
---|
2634 | r.run(DocTestSuite())
|
---|
2635 |
|
---|
2636 | if __name__ == "__main__":
|
---|
2637 | _test()
|
---|