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