14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Module doctest. 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org). 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Major enhancements and refactoring by: 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Jim Fulton 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Edward Loper 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Provided as-is; use at your own risk; no warranty; no promises; enjoy! 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmr"""Module doctest -- a framework for running examples in docstrings. 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIn simplest use, end each module M to be tested with: 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _test(): 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import doctest 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm doctest.testmod() 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__": 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _test() 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThen running the module as a script will cause the examples in the 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdocstrings to get executed and verified: 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmpython M.py 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThis won't display anything unless an example fails, in which case the 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfailing example(s) and the cause(s) of the failure(s) are printed to stdout 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm(why not stderr? because stderr is a lame hack <0.2 wink>), and the final 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmline of output is "Test failed.". 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmRun it with the -v switch instead: 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmpython M.py -v 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmand a detailed report of all examples tried is printed to stdout, along 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwith assorted summaries at the end. 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmYou can force verbose mode by passing "verbose=True" to testmod, or prohibit 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmit by passing "verbose=False". In either of those cases, sys.argv is not 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexamined by testmod. 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThere are a variety of other ways to run doctests, including integration 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwith the unittest framework, and support for running non-Python text 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfiles containing doctests. There are also many ways to override parts 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmof doctest's default behaviors. See the Library Reference Manual for 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdetails. 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__docformat__ = 'reStructuredText en' 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = [ 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 0, Option Flags 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'register_optionflag', 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DONT_ACCEPT_TRUE_FOR_1', 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DONT_ACCEPT_BLANKLINE', 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'NORMALIZE_WHITESPACE', 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'ELLIPSIS', 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'SKIP', 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'IGNORE_EXCEPTION_DETAIL', 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'COMPARISON_FLAGS', 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'REPORT_UDIFF', 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'REPORT_CDIFF', 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'REPORT_NDIFF', 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'REPORT_ONLY_FIRST_FAILURE', 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'REPORTING_FLAGS', 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 1. Utility Functions 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 2. Example & DocTest 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'Example', 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DocTest', 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 3. Doctest Parser 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DocTestParser', 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 4. Doctest Finder 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DocTestFinder', 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 5. Doctest Runner 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DocTestRunner', 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'OutputChecker', 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DocTestFailure', 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'UnexpectedException', 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DebugRunner', 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 6. Test Functions 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'testmod', 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'testfile', 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'run_docstring_examples', 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 7. Tester 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'Tester', 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 8. Unittest Support 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DocTestSuite', 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'DocFileSuite', 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'set_unittest_reportflags', 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 9. Debugging Support 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'script_from_examples', 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'testsource', 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'debug_src', 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'debug', 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm] 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport __future__ 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys, traceback, inspect, linecache, os, re 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest, difflib, pdb, tempfile 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport warnings 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom StringIO import StringIO 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom collections import namedtuple 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTestResults = namedtuple('TestResults', 'failed attempted') 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# There are 4 basic classes: 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# - Example: a <source, want> pair, plus an intra-docstring line number. 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# - DocTest: a collection of examples, parsed from a docstring, plus 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# info about where the docstring came from (name, filename, lineno). 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# - DocTestFinder: extracts DocTests from a given object's docstring and 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# its contained objects' docstrings. 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# - DocTestRunner: runs DocTest cases, and accumulates statistics. 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# So the basic picture is: 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# list of: 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# +------+ +---------+ +-------+ 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results| 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# +------+ +---------+ +-------+ 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# | Example | 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# | ... | 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# | Example | 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# +---------+ 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Option constants. 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmOPTIONFLAGS_BY_NAME = {} 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef register_optionflag(name): 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Create a new flag unless `name` is already known. 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME)) 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1') 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE') 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE') 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmELLIPSIS = register_optionflag('ELLIPSIS') 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSKIP = register_optionflag('SKIP') 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmIGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmCOMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DONT_ACCEPT_BLANKLINE | 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NORMALIZE_WHITESPACE | 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ELLIPSIS | 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm SKIP | 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm IGNORE_EXCEPTION_DETAIL) 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmREPORT_UDIFF = register_optionflag('REPORT_UDIFF') 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmREPORT_CDIFF = register_optionflag('REPORT_CDIFF') 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmREPORT_NDIFF = register_optionflag('REPORT_NDIFF') 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmREPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE') 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmREPORTING_FLAGS = (REPORT_UDIFF | 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_CDIFF | 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_NDIFF | 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_ONLY_FIRST_FAILURE) 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Special string markers for use in `want` strings: 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBLANKLINE_MARKER = '<BLANKLINE>' 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmELLIPSIS_MARKER = '...' 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## Table of Contents 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 1. Utility Functions 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 2. Example & DocTest -- store test cases 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 3. DocTest Parser -- extracts examples from strings 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 4. DocTest Finder -- extracts test cases from objects 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 5. DocTest Runner -- runs test cases 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 6. Test Functions -- convenient wrappers for testing 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 7. Tester Class -- for backwards compatibility 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 8. Unittest Support 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 9. Debugging Support 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 10. Example Usage 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 1. Utility Functions 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _extract_future_flags(globs): 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return the compiler-flags associated with the future features that 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm have been imported into the given namespace (globs). 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flags = 0 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for fname in __future__.all_feature_names: 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm feature = globs.get(fname, None) 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if feature is getattr(__future__, fname): 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flags |= feature.compiler_flag 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return flags 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _normalize_module(module, depth=2): 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return the module specified by `module`. In particular: 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - If `module` is a module, then return module. 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - If `module` is a string, then import and return the 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module with that name. 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - If `module` is None, then return the calling module. 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The calling module is assumed to be the module of 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the stack frame at the given depth in the call stack. 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.ismodule(module): 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return module 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif isinstance(module, (str, unicode)): 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return __import__(module, globals(), locals(), ["*"]) 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif module is None: 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return sys.modules[sys._getframe(depth).f_globals['__name__']] 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError("Expected a module, string, or None") 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _load_testfile(filename, package, module_relative): 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module_relative: 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm package = _normalize_module(package, 3) 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename = _module_relative_path(package, filename) 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(package, '__loader__'): 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(package.__loader__, 'get_data'): 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file_contents = package.__loader__.get_data(filename) 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # get_data() opens files as 'rb', so one must do the equivalent 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # conversion as universal newlines would do. 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return file_contents.replace(os.linesep, '\n'), filename 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with open(filename) as f: 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return f.read(), filename 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Use sys.stdout encoding for ouput. 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_encoding = getattr(sys.__stdout__, 'encoding', None) or 'utf-8' 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _indent(s, indent=4): 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Add the given number of space characters to the beginning of 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm every non-blank line in `s`, and return the result. 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the string `s` is Unicode, it is encoded using the stdout 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding and the `backslashreplace` error handler. 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(s, unicode): 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = s.encode(_encoding, 'backslashreplace') 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This regexp matches the start of non-blank lines: 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return re.sub('(?m)^(?!$)', indent*' ', s) 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _exception_traceback(exc_info): 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return a string containing a traceback message for the given 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exc_info tuple (as returned by sys.exc_info()). 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Get a traceback message. 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm excout = StringIO() 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exc_type, exc_val, exc_tb = exc_info 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm traceback.print_exception(exc_type, exc_val, exc_tb, file=excout) 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return excout.getvalue() 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Override some StringIO methods. 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass _SpoofOut(StringIO): 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def getvalue(self): 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm result = StringIO.getvalue(self) 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If anything at all was written, make sure there's a trailing 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # newline. There's no way for the expected output to indicate 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # that a trailing newline is missing. 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if result and not result.endswith("\n"): 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm result += "\n" 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Prevent softspace from screwing up the next test case, in 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # case they used print with a trailing comma in an example. 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(self, "softspace"): 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del self.softspace 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return result 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def truncate(self, size=None): 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm StringIO.truncate(self, size) 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(self, "softspace"): 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del self.softspace 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self.buf: 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Reset it to an empty string, to make sure it's not unicode. 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.buf = '' 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Worst-case linear-time ellipsis matching. 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _ellipsis_match(want, got): 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Essentially the only subtle case: 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> _ellipsis_match('aa...aa', 'aaa') 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm False 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ELLIPSIS_MARKER not in want: 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return want == got 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find "the real" strings. 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ws = want.split(ELLIPSIS_MARKER) 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert len(ws) >= 2 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Deal with exact matches possibly needed at one or both ends. 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm startpos, endpos = 0, len(got) 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm w = ws[0] 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if w: # starts with exact match 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if got.startswith(w): 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm startpos = len(w) 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del ws[0] 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm w = ws[-1] 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if w: # ends with exact match 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if got.endswith(w): 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm endpos -= len(w) 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del ws[-1] 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if startpos > endpos: 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Exact end matches required more characters than we have, as in 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # _ellipsis_match('aa...aa', 'aaa') 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # For the rest, we only need to find the leftmost non-overlapping 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # match for each piece. If there's no overall match that way alone, 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # there's no overall match period. 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for w in ws: 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # w may be '' at times, if there are consecutive ellipses, or 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # due to an ellipsis at the start or end of `want`. That's OK. 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Search for an empty string succeeds, and doesn't change startpos. 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm startpos = got.find(w, startpos, endpos) 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if startpos < 0: 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm startpos += len(w) 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _comment_line(line): 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Return a commented form of the given line" 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = line.rstrip() 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if line: 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return '# '+line 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return '#' 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass _OutputRedirectingPdb(pdb.Pdb): 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A specialized version of the python debugger that redirects stdout 3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm to a given stream when interacting with the user. Stdout is *not* 3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm redirected when traced code is executed. 3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, out): 3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__out = out 3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__debugger_used = False 3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pdb.Pdb.__init__(self, stdout=out) 3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # still use input() to get user input 3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.use_rawinput = 1 3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def set_trace(self, frame=None): 3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__debugger_used = True 3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if frame is None: 3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm frame = sys._getframe().f_back 3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pdb.Pdb.set_trace(self, frame) 3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def set_continue(self): 3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Calling set_continue unconditionally would break unit test 3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # coverage reporting, as Bdb.set_continue calls sys.settrace(None). 3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.__debugger_used: 3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pdb.Pdb.set_continue(self) 3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def trace_dispatch(self, *args): 3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Redirect stdout to the given stream. 3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save_stdout = sys.stdout 3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout = self.__out 3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Call Pdb's trace dispatch method. 3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return pdb.Pdb.trace_dispatch(self, *args) 3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout = save_stdout 3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# [XX] Normalize with respect to os.path.pardir? 3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _module_relative_path(module, path): 3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not inspect.ismodule(module): 3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError, 'Expected a module: %r' % module 3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if path.startswith('/'): 3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, 'Module-relative files may not have absolute paths' 3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find the base directory for the path. 3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(module, '__file__'): 3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A normal module/package 3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm basedir = os.path.split(module.__file__)[0] 3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif module.__name__ == '__main__': 3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # An interactive session. 3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(sys.argv)>0 and sys.argv[0] != '': 3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm basedir = os.path.split(sys.argv[0])[0] 3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm basedir = os.curdir 3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A module w/o __file__ (this includes builtins) 3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("Can't resolve paths relative to the module " + 3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module + " (it has no __file__)") 3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Combine the base directory and the path. 3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return os.path.join(basedir, *(path.split('/'))) 3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 2. Example & DocTest 3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## - An "example" is a <source, want> pair, where "source" is a 3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## fragment of source code, and "want" is the expected output for 3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## "source." The Example class also includes information about 3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## where the example was extracted from. 3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## - A "doctest" is a collection of examples, typically extracted from 3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## a string (such as an object's docstring). The DocTest class also 3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## includes information about where the string was extracted from. 4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Example: 4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A single doctest example, consisting of source code and expected 4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output. `Example` defines the following attributes: 4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - source: A single Python statement, always ending with a newline. 4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The constructor adds a newline if needed. 4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - want: The expected output from running the source code (either 4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm from stdout, or a traceback in case of exception). `want` ends 4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with a newline unless it's empty, in which case it's an empty 4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm string. The constructor adds a newline if needed. 4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - exc_msg: The exception message generated by the example, if 4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the example is expected to generate an exception; or `None` if 4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm it is not expected to generate an exception. This exception 4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm message is compared against the return value of 4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `traceback.format_exception_only()`. `exc_msg` ends with a 4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm newline unless it's `None`. The constructor adds a newline 4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if needed. 4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - lineno: The line number within the DocTest string containing 4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm this Example where the Example begins. This line number is 4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm zero-based, with respect to the beginning of the DocTest. 4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - indent: The example's indentation in the DocTest string. 4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm I.e., the number of space characters that preceed the 4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm example's first prompt. 4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - options: A dictionary mapping from option flags to True or 4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm False, which is used to override default options for this 4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm example. Any option flags not contained in this dictionary 4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm are left at their default value (as specified by the 4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DocTestRunner's optionflags). By default, no options are set. 4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, source, want, exc_msg=None, lineno=0, indent=0, 4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm options=None): 4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Normalize inputs. 4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not source.endswith('\n'): 4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source += '\n' 4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if want and not want.endswith('\n'): 4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want += '\n' 4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if exc_msg is not None and not exc_msg.endswith('\n'): 4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exc_msg += '\n' 4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Store properties. 4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.source = source 4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.want = want 4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.lineno = lineno 4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.indent = indent 4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if options is None: options = {} 4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.options = options 4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.exc_msg = exc_msg 4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DocTest: 4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A collection of doctest examples that should be run in a single 4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm namespace. Each `DocTest` defines the following attributes: 4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - examples: the list of examples. 4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - globs: The namespace (aka globals) that the examples should 4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm be run in. 4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - name: A name identifying the DocTest (typically, the name of 4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the object whose docstring this DocTest was extracted from). 4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - filename: The name of the file that this DocTest was extracted 4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm from, or `None` if the filename is unknown. 4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - lineno: The line number within filename where this DocTest 4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm begins, or `None` if the line number is unavailable. This 4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line number is zero-based, with respect to the beginning of 4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the file. 4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - docstring: The string that the examples were extracted from, 4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm or `None` if the string is unavailable. 4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, examples, globs, name, filename, lineno, docstring): 4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Create a new DocTest containing the given examples. The 4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DocTest's globals are initialized with a copy of `globs`. 4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert not isinstance(examples, basestring), \ 4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "DocTest no longer accepts str; use DocTestParser instead" 4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.examples = examples 4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.docstring = docstring 4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.globs = globs.copy() 4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.name = name 4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.filename = filename 4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.lineno = lineno 4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __repr__(self): 4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(self.examples) == 0: 4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm examples = 'no examples' 4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif len(self.examples) == 1: 4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm examples = '1 example' 4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm examples = '%d examples' % len(self.examples) 4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return ('<DocTest %s from %s:%s (%s)>' % 5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (self.name, self.filename, self.lineno, examples)) 5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This lets us sort tests by name: 5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __cmp__(self, other): 5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not isinstance(other, DocTest): 5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1 5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return cmp((self.name, self.filename, self.lineno, id(self)), 5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (other.name, other.filename, other.lineno, id(other))) 5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 3. DocTestParser 5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DocTestParser: 5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A class used to parse strings containing doctest examples. 5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This regular expression is used to find doctest examples in a 5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # string. It defines three groups: `source` is the source code 5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # (including leading indentation and prompts); `indent` is the 5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # indentation of the first (PS1) line of the source code; and 5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # `want` is the expected output (including leading indentation). 5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _EXAMPLE_RE = re.compile(r''' 5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Source consists of a PS1 line followed by zero or more PS2 lines. 5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (?P<source> 5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (?:^(?P<indent> [ ]*) >>> .*) # PS1 line 5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (?:\n [ ]* \.\.\. .*)*) # PS2 lines 5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm \n? 5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Want consists of any non-blank lines that do not start with PS1. 5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (?P<want> (?:(?![ ]*$) # Not a blank line 5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (?![ ]*>>>) # Not a line starting with PS1 5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm .*$\n? # But any other line 5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm )*) 5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ''', re.MULTILINE | re.VERBOSE) 5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A regular expression for handling `want` strings that contain 5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # expected exceptions. It divides `want` into three pieces: 5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # - the traceback header line (`hdr`) 5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # - the traceback stack (`stack`) 5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # - the exception message (`msg`), as generated by 5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # traceback.format_exception_only() 5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # `msg` may have multiple lines. We assume/require that the 5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # exception message is the first non-indented line starting with a word 5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # character following the traceback header line. 5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _EXCEPTION_RE = re.compile(r""" 5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Grab the traceback header. Different versions of Python have 5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # said different things on the first traceback line. 5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ^(?P<hdr> Traceback\ \( 5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (?: most\ recent\ call\ last 5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm | innermost\ last 5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ) \) : 5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ) 5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm \s* $ # toss trailing whitespace on the header. 5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (?P<stack> .*?) # don't blink: absorb stuff until... 5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ^ (?P<msg> \w+ .*) # a line *starts* with alphanum. 5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """, re.VERBOSE | re.MULTILINE | re.DOTALL) 5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A callable returning a true value iff its argument is a blank line 5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # or contains a single comment. 5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match 5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def parse(self, string, name='<string>'): 5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Divide the given string into examples and intervening text, 5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and return them as a list of alternating Examples and strings. 5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Line numbers for the Examples are 0-based. The optional 5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm argument `name` is a name identifying this string, and is only 5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm used for error messages. 5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm string = string.expandtabs() 5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If all lines begin with the same indentation, then strip it. 5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm min_indent = self._min_indent(string) 5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if min_indent > 0: 5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm string = '\n'.join([l[min_indent:] for l in string.split('\n')]) 5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output = [] 5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm charno, lineno = 0, 0 5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find all doctest examples in the string: 5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for m in self._EXAMPLE_RE.finditer(string): 5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Add the pre-example text to `output`. 5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output.append(string[charno:m.start()]) 5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Update lineno (lines before this example) 5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno += string.count('\n', charno, m.start()) 5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Extract info from the regexp match. 5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (source, options, want, exc_msg) = \ 5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._parse_example(m, name, lineno) 5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Create an Example, and add it to the list. 5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self._IS_BLANK_OR_COMMENT(source): 5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output.append( Example(source, want, exc_msg, 5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno=lineno, 5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm indent=min_indent+len(m.group('indent')), 5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm options=options) ) 5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Update lineno (lines inside this example) 5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno += string.count('\n', m.start(), m.end()) 5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Update charno. 5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm charno = m.end() 5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Add any remaining post-example text to `output`. 5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output.append(string[charno:]) 5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return output 6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def get_doctest(self, string, globs, name, filename, lineno): 6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Extract all doctest examples from the given string, and 6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm collect them into a `DocTest` object. 6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `globs`, `name`, `filename`, and `lineno` are attributes for 6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the new `DocTest` object. See the documentation for `DocTest` 6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for more information. 6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return DocTest(self.get_examples(string, name), globs, 6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name, filename, lineno, string) 6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def get_examples(self, string, name='<string>'): 6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Extract all doctest examples from the given string, and return 6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm them as a list of `Example` objects. Line numbers are 6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0-based, because it's most common in doctests that nothing 6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm interesting appears on the same line as opening triple-quote, 6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and so the first interesting line is called \"line 1\" then. 6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional argument `name` is a name identifying this 6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm string, and is only used for error messages. 6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return [x for x in self.parse(string, name) 6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(x, Example)] 6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _parse_example(self, m, name, lineno): 6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Given a regular expression match from `_EXAMPLE_RE` (`m`), 6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return a pair `(source, want)`, where `source` is the matched 6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm example's source code (with prompts and indentation stripped); 6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and `want` is the example's expected output (with indentation 6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stripped). 6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `name` is the string's name, and `lineno` is the line number 6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm where the example starts; both are used for error messages. 6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Get the example's indentation level. 6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm indent = len(m.group('indent')) 6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Divide source into lines; check that they're properly 6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # indented; and then strip their indentation & prompts. 6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source_lines = m.group('source').split('\n') 6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._check_prompt_blank(source_lines, indent, name, lineno) 6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno) 6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source = '\n'.join([sl[indent+4:] for sl in source_lines]) 6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Divide want into lines; check that it's properly indented; and 6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # then strip the indentation. Spaces before the last newline should 6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # be preserved, so plain rstrip() isn't good enough. 6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want = m.group('want') 6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want_lines = want.split('\n') 6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]): 6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del want_lines[-1] # forget final newline & spaces after it 6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._check_prefix(want_lines, ' '*indent, name, 6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno + len(source_lines)) 6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want = '\n'.join([wl[indent:] for wl in want_lines]) 6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If `want` contains a traceback message, then extract it. 6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = self._EXCEPTION_RE.match(want) 6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if m: 6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exc_msg = m.group('msg') 6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exc_msg = None 6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Extract options from the source. 6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm options = self._find_options(source, name, lineno) 6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return source, options, want, exc_msg 6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This regular expression looks for option directives in the 6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # source code of an example. Option directives are comments 6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # starting with "doctest:". Warning: this may give false 6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # positives for string-literals that contain the string 6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # "#doctest:". Eliminating these false positives would require 6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # actually parsing the string; but we limit them by ignoring any 6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # line containing "#doctest:" that is *followed* by a quote mark. 6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$', 6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm re.MULTILINE) 6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _find_options(self, source, name, lineno): 6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return a dictionary containing option overrides extracted from 6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm option directives in the given source string. 6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `name` is the string's name, and `lineno` is the line number 6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm where the example starts; both are used for error messages. 6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm options = {} 6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # (note: with the current regexp, this will match at most once:) 6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for m in self._OPTION_DIRECTIVE_RE.finditer(source): 6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm option_strings = m.group(1).replace(',', ' ').split() 6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for option in option_strings: 6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (option[0] not in '+-' or 6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm option[1:] not in OPTIONFLAGS_BY_NAME): 6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError('line %r of the doctest for %s ' 6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'has an invalid option: %r' % 6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (lineno+1, name, option)) 6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flag = OPTIONFLAGS_BY_NAME[option[1:]] 7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm options[flag] = (option[0] == '+') 7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if options and self._IS_BLANK_OR_COMMENT(source): 7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError('line %r of the doctest for %s has an option ' 7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'directive on a line with no example: %r' % 7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (lineno, name, source)) 7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return options 7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This regular expression finds the indentation of every non-blank 7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # line in a string. 7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE) 7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _min_indent(self, s): 7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Return the minimum indentation of any non-blank line in `s`" 7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm indents = [len(indent) for indent in self._INDENT_RE.findall(s)] 7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(indents) > 0: 7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return min(indents) 7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0 7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _check_prompt_blank(self, lines, indent, name, lineno): 7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Given the lines of a source string (including prompts and 7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm leading indentation), check to make sure that every prompt is 7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm followed by a space character. If any line is not followed by 7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a space character, then raise ValueError. 7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i, line in enumerate(lines): 7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(line) >= indent+4 and line[indent+3] != ' ': 7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError('line %r of the docstring for %s ' 7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'lacks blank after %s: %r' % 7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (lineno+i+1, name, 7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line[indent:indent+3], line)) 7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _check_prefix(self, lines, prefix, name, lineno): 7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Check that every line in the given list starts with the given 7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm prefix; if any line does not, then raise a ValueError. 7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i, line in enumerate(lines): 7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if line and not line.startswith(prefix): 7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError('line %r of the docstring for %s has ' 7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'inconsistent leading whitespace: %r' % 7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (lineno+i+1, name, line)) 7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 4. DocTest Finder 7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DocTestFinder: 7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A class used to extract the DocTests that are relevant to a given 7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object, from its docstring and the docstrings of its contained 7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm objects. Doctests can currently be extracted from the following 7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object types: modules, functions, classes, methods, staticmethods, 7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm classmethods, and properties. 7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, verbose=False, parser=DocTestParser(), 7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm recurse=True, exclude_empty=True): 7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Create a new doctest finder. 7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional argument `parser` specifies a class or 7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm function that should be used to create new DocTest objects (or 7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm objects that implement the same interface as DocTest). The 7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm signature for this factory function should match the signature 7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm of the DocTest constructor. 7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the optional argument `recurse` is false, then `find` will 7704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm only examine the given object, and not any contained objects. 7714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the optional argument `exclude_empty` is false, then `find` 7734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm will include tests for objects with empty docstrings. 7744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._parser = parser 7764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._verbose = verbose 7774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._recurse = recurse 7784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._exclude_empty = exclude_empty 7794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def find(self, obj, name=None, module=None, globs=None, extraglobs=None): 7814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return a list of the DocTests that are defined by the given 7834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object's docstring, or by any of its contained objects' 7844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm docstrings. 7854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional parameter `module` is the module that contains 7874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the given object. If the module is not specified or is None, then 7884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the test finder will attempt to automatically determine the 7894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm correct module. The object's module is used: 7904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - As a default namespace, if `globs` is not specified. 7924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - To prevent the DocTestFinder from extracting DocTests 7934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm from objects that are imported from other modules. 7944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - To find the name of the file containing the object. 7954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - To help find the line number of the object within its 7964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file. 7974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Contained objects whose module does not match `module` are ignored. 7994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If `module` is False, no attempt to find the module will be made. 8014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This is obscure, of use mostly in tests: if `module` is False, or 8024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm is None but cannot be found automatically, then all objects are 8034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm considered to belong to the (non-existent) module, so all contained 8044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm objects will (recursively) be searched for doctests. 8054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The globals for each DocTest is formed by combining `globs` 8074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and `extraglobs` (bindings in `extraglobs` override bindings 8084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm in `globs`). A new copy of the globals dictionary is created 8094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for each DocTest. If `globs` is not specified, then it 8104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm defaults to the module's `__dict__`, if specified, or {} 8114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm otherwise. If `extraglobs` is not specified, then it defaults 8124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm to {}. 8134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 8154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If name was not specified, then extract it from the object. 8164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if name is None: 8174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = getattr(obj, '__name__', None) 8184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if name is None: 8194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("DocTestFinder.find: name must be given " 8204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "when obj.__name__ doesn't exist: %r" % 8214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (type(obj),)) 8224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find the module that contains the given object (if obj is 8244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # a module, then module=obj.). Note: this may fail, in which 8254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # case module will be None. 8264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module is False: 8274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = None 8284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif module is None: 8294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = inspect.getmodule(obj) 8304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Read the module's source code. This is used by 8324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # DocTestFinder._find_lineno to find the line number for a 8334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # given object's docstring. 8344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 8354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = inspect.getsourcefile(obj) or inspect.getfile(obj) 8364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module is not None: 8374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Supply the module globals in case the module was 8384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # originally loaded via a PEP 302 loader and 8394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # file is not a valid filesystem path 8404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source_lines = linecache.getlines(file, module.__dict__) 8414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 8424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # No access to a loader, so assume it's a normal 8434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # filesystem path 8444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source_lines = linecache.getlines(file) 8454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not source_lines: 8464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source_lines = None 8474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except TypeError: 8484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source_lines = None 8494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Initialize globals, and merge in extraglobs. 8514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if globs is None: 8524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module is None: 8534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = {} 8544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 8554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = module.__dict__.copy() 8564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 8574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = globs.copy() 8584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if extraglobs is not None: 8594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs.update(extraglobs) 8604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if '__name__' not in globs: 8614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs['__name__'] = '__main__' # provide a default module name 8624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Recursively expore `obj`, extracting DocTests. 8644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests = [] 8654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._find(tests, obj, name, module, source_lines, globs, {}) 8664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Sort the tests by alpha order of names, for consistency in 8674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # verbose-mode output. This was a feature of doctest in Pythons 8684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # <= 2.3 that got lost by accident in 2.4. It was repaired in 8694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 2.4.4 and 2.5. 8704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests.sort() 8714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return tests 8724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _from_module(self, module, object): 8744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 8754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return true if the given object is defined in the given 8764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module. 8774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 8784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module is None: 8794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 8804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif inspect.getmodule(object) is not None: 8814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return module is inspect.getmodule(object) 8824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif inspect.isfunction(object): 8834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return module.__dict__ is object.func_globals 8844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif inspect.isclass(object): 8854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return module.__name__ == object.__module__ 8864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif hasattr(object, '__module__'): 8874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return module.__name__ == object.__module__ 8884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif isinstance(object, property): 8894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True # [XX] no way not be sure. 8904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 8914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("object must be a class or function") 8924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _find(self, tests, obj, name, module, source_lines, globs, seen): 8944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 8954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Find tests for the given object and any contained objects, and 8964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm add them to `tests`. 8974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 8984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._verbose: 8994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print 'Finding tests in %s' % name 9004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If we've already processed this object, then ignore it. 9024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if id(obj) in seen: 9034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 9044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm seen[id(obj)] = 1 9054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find a test for this object, and add it to the list of tests. 9074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = self._get_test(obj, name, module, globs, source_lines) 9084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if test is not None: 9094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests.append(test) 9104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Look for tests in a module's contained objects. 9124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.ismodule(obj) and self._recurse: 9134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for valname, val in obj.__dict__.items(): 9144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm valname = '%s.%s' % (name, valname) 9154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Recurse to functions & classes. 9164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ((inspect.isfunction(val) or inspect.isclass(val)) and 9174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._from_module(module, val)): 9184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._find(tests, val, valname, module, source_lines, 9194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs, seen) 9204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Look for tests in a module's __test__ dictionary. 9224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.ismodule(obj) and self._recurse: 9234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for valname, val in getattr(obj, '__test__', {}).items(): 9244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not isinstance(valname, basestring): 9254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("DocTestFinder.find: __test__ keys " 9264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "must be strings: %r" % 9274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (type(valname),)) 9284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not (inspect.isfunction(val) or inspect.isclass(val) or 9294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inspect.ismethod(val) or inspect.ismodule(val) or 9304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm isinstance(val, basestring)): 9314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("DocTestFinder.find: __test__ values " 9324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "must be strings, functions, methods, " 9334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "classes, or modules: %r" % 9344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (type(val),)) 9354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm valname = '%s.__test__.%s' % (name, valname) 9364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._find(tests, val, valname, module, source_lines, 9374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs, seen) 9384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Look for tests in a class's contained objects. 9404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.isclass(obj) and self._recurse: 9414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for valname, val in obj.__dict__.items(): 9424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Special handling for staticmethod/classmethod. 9434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(val, staticmethod): 9444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm val = getattr(obj, valname) 9454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(val, classmethod): 9464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm val = getattr(obj, valname).im_func 9474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Recurse to methods, properties, and nested classes. 9494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ((inspect.isfunction(val) or inspect.isclass(val) or 9504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm isinstance(val, property)) and 9514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._from_module(module, val)): 9524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm valname = '%s.%s' % (name, valname) 9534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._find(tests, val, valname, module, source_lines, 9544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs, seen) 9554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _get_test(self, obj, name, module, globs, source_lines): 9574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 9584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return a DocTest for the given object, if it defines a docstring; 9594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm otherwise, return None. 9604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 9614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Extract the object's docstring. If it doesn't have one, 9624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # then return None (no test for this object). 9634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(obj, basestring): 9644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm docstring = obj 9654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 9664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 9674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if obj.__doc__ is None: 9684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm docstring = '' 9694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 9704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm docstring = obj.__doc__ 9714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not isinstance(docstring, basestring): 9724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm docstring = str(docstring) 9734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except (TypeError, AttributeError): 9744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm docstring = '' 9754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find the docstring's location in the file. 9774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = self._find_lineno(obj, source_lines) 9784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Don't bother if the docstring is empty. 9804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._exclude_empty and not docstring: 9814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return None 9824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Return a DocTest for this object. 9844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module is None: 9854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename = None 9864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 9874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename = getattr(module, '__file__', module.__name__) 9884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if filename[-4:] in (".pyc", ".pyo"): 9894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename = filename[:-1] 9904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._parser.get_doctest(docstring, globs, name, 9914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename, lineno) 9924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _find_lineno(self, obj, source_lines): 9944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 9954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return a line number of the given object's docstring. Note: 9964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm this method assumes that the object has a docstring. 9974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 9984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = None 9994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find the line number for modules. 10014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.ismodule(obj): 10024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = 0 10034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find the line number for classes. 10054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Note: this could be fooled if a class is defined multiple 10064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # times in a single file. 10074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.isclass(obj): 10084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if source_lines is None: 10094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return None 10104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pat = re.compile(r'^\s*class\s*%s\b' % 10114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm getattr(obj, '__name__', '-')) 10124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i, line in enumerate(source_lines): 10134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if pat.match(line): 10144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = i 10154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break 10164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find the line number for functions & methods. 10184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.ismethod(obj): obj = obj.im_func 10194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.isfunction(obj): obj = obj.func_code 10204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.istraceback(obj): obj = obj.tb_frame 10214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.isframe(obj): obj = obj.f_code 10224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if inspect.iscode(obj): 10234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = getattr(obj, 'co_firstlineno', None)-1 10244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find the line number where the docstring starts. Assume 10264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # that it's the first line that begins with a quote mark. 10274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Note: this could be fooled by a multiline function 10284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # signature, where a continuation line begins with a quote 10294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # mark. 10304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if lineno is not None: 10314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if source_lines is None: 10324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return lineno+1 10334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pat = re.compile('(^|.*:)\s*\w*("|\')') 10344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for lineno in range(lineno, len(source_lines)): 10354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if pat.match(source_lines[lineno]): 10364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return lineno 10374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # We couldn't find the line number. 10394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return None 10404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 10424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 5. DocTest Runner 10434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 10444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DocTestRunner: 10464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 10474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A class used to run DocTest test cases, and accumulate statistics. 10484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The `run` method is used to process a single DocTest case. It 10494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm returns a tuple `(f, t)`, where `t` is the number of test cases 10504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tried, and `f` is the number of test cases that failed. 10514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> tests = DocTestFinder().find(_TestClass) 10534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> runner = DocTestRunner(verbose=False) 10544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> tests.sort(key = lambda test: test.name) 10554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> for test in tests: 10564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... print test.name, '->', runner.run(test) 10574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _TestClass -> TestResults(failed=0, attempted=2) 10584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _TestClass.__init__ -> TestResults(failed=0, attempted=2) 10594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _TestClass.get -> TestResults(failed=0, attempted=2) 10604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _TestClass.square -> TestResults(failed=0, attempted=1) 10614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The `summarize` method prints a summary of all the test cases that 10634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm have been run by the runner, and returns an aggregated `(f, t)` 10644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tuple: 10654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> runner.summarize(verbose=1) 10674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4 items passed all tests: 10684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2 tests in _TestClass 10694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2 tests in _TestClass.__init__ 10704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2 tests in _TestClass.get 10714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1 tests in _TestClass.square 10724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7 tests in 4 items. 10734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7 passed and 0 failed. 10744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Test passed. 10754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm TestResults(failed=0, attempted=7) 10764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The aggregated number of tried examples and failed examples is 10784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm also available via the `tries` and `failures` attributes: 10794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> runner.tries 10814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7 10824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> runner.failures 10834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0 10844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The comparison between expected outputs and actual outputs is done 10864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm by an `OutputChecker`. This comparison may be customized with a 10874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm number of option flags; see the documentation for `testmod` for 10884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm more information. If the option flags are insufficient, then the 10894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm comparison may also be customized by passing a subclass of 10904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `OutputChecker` to the constructor. 10914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The test runner's display output can be controlled in two ways. 10934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm First, an output function (`out) can be passed to 10944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `TestRunner.run`; this function will be called with strings that 10954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm should be displayed. It defaults to `sys.stdout.write`. If 10964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm capturing the output is not sufficient, then the display output 10974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm can be also customized by subclassing DocTestRunner, and 10984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm overriding the methods `report_start`, `report_success`, 10994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `report_unexpected_exception`, and `report_failure`. 11004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This divider string is used to separate failure messages, and to 11024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # separate sections of the summary. 11034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DIVIDER = "*" * 70 11044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, checker=None, verbose=None, optionflags=0): 11064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Create a new test runner. 11084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg `checker` is the `OutputChecker` that 11104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm should be used to compare the expected outputs and actual 11114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outputs of doctest examples. 11124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg 'verbose' prints lots of stuff if true, 11144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm only failures if false; by default, it's true iff '-v' is in 11154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.argv. 11164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional argument `optionflags` can be used to control how the 11184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test runner compares expected output to actual output, and how 11194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm it displays failures. See the documentation for `testmod` for 11204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm more information. 11214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._checker = checker or OutputChecker() 11234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if verbose is None: 11244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm verbose = '-v' in sys.argv 11254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._verbose = verbose 11264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.optionflags = optionflags 11274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.original_optionflags = optionflags 11284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Keep track of the examples we've run. 11304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.tries = 0 11314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.failures = 0 11324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._name2ft = {} 11334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Create a fake output target for capturing doctest output. 11354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._fakeout = _SpoofOut() 11364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #///////////////////////////////////////////////////////////////// 11384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Reporting methods 11394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #///////////////////////////////////////////////////////////////// 11404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def report_start(self, out, test, example): 11424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Report that the test runner is about to process the given 11444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm example. (Only displays a message if verbose=True) 11454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._verbose: 11474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if example.want: 11484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out('Trying:\n' + _indent(example.source) + 11494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'Expecting:\n' + _indent(example.want)) 11504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 11514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out('Trying:\n' + _indent(example.source) + 11524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'Expecting nothing\n') 11534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def report_success(self, out, test, example, got): 11554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Report that the given example ran successfully. (Only 11574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm displays a message if verbose=True) 11584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._verbose: 11604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out("ok\n") 11614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def report_failure(self, out, test, example, got): 11634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Report that the given example failed. 11654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out(self._failure_header(test, example) + 11674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._checker.output_difference(example, got, self.optionflags)) 11684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def report_unexpected_exception(self, out, test, example, exc_info): 11704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Report that the given example raised an unexpected exception. 11724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out(self._failure_header(test, example) + 11744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'Exception raised:\n' + _indent(_exception_traceback(exc_info))) 11754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _failure_header(self, test, example): 11774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out = [self.DIVIDER] 11784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if test.filename: 11794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if test.lineno is not None and example.lineno is not None: 11804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = test.lineno + example.lineno + 1 11814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 11824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = '?' 11834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out.append('File "%s", line %s, in %s' % 11844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (test.filename, lineno, test.name)) 11854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 11864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out.append('Line %s, in %s' % (example.lineno+1, test.name)) 11874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out.append('Failed example:') 11884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source = example.source 11894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out.append(_indent(source)) 11904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return '\n'.join(out) 11914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #///////////////////////////////////////////////////////////////// 11934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # DocTest Running 11944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #///////////////////////////////////////////////////////////////// 11954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __run(self, test, compileflags, out): 11974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 11984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Run the examples in `test`. Write the outcome of each example 11994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with one of the `DocTestRunner.report_*` methods, using the 12004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm writer function `out`. `compileflags` is the set of compiler 12014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flags that should be used to execute examples. Return a tuple 12024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `(f, t)`, where `t` is the number of examples tried, and `f` 12034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm is the number of examples that failed. The examples are run 12044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm in the namespace `test.globs`. 12054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 12064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Keep track of the number of failures and tries. 12074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failures = tries = 0 12084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Save the option flags (since option directives can be used 12104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # to modify them). 12114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm original_optionflags = self.optionflags 12124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm SUCCESS, FAILURE, BOOM = range(3) # `outcome` state 12144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm check = self._checker.check_output 12164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Process each example. 12184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for examplenum, example in enumerate(test.examples): 12194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If REPORT_ONLY_FIRST_FAILURE is set, then suppress 12214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # reporting after the first failure. 12224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and 12234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failures > 0) 12244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Merge in the example's options. 12264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.optionflags = original_optionflags 12274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if example.options: 12284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (optionflag, val) in example.options.items(): 12294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if val: 12304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.optionflags |= optionflag 12314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 12324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.optionflags &= ~optionflag 12334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If 'SKIP' is set, then skip this example. 12354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.optionflags & SKIP: 12364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm continue 12374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Record that we started this example. 12394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tries += 1 12404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not quiet: 12414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.report_start(out, test, example) 12424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Use a special filename for compile(), so we can retrieve 12444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # the source code during interactive debugging (see 12454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # __patched_linecache_getlines). 12464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename = '<doctest %s[%d]>' % (test.name, examplenum) 12474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Run the example in the given context (globs), and record 12494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # any exception that gets raised. (But don't intercept 12504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # keyboard interrupts.) 12514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 12524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Don't blink! This is where the user's code gets run. 12534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exec compile(example.source, filename, "single", 12544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm compileflags, 1) in test.globs 12554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.debugger.set_continue() # ==== Example Finished ==== 12564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exception = None 12574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except KeyboardInterrupt: 12584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise 12594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except: 12604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exception = sys.exc_info() 12614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.debugger.set_continue() # ==== Example Finished ==== 12624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm got = self._fakeout.getvalue() # the actual output 12644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._fakeout.truncate(0) 12654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outcome = FAILURE # guilty until proved innocent or insane 12664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If the example executed without raising any exceptions, 12684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # verify its output. 12694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if exception is None: 12704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if check(example.want, got, self.optionflags): 12714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outcome = SUCCESS 12724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The example raised an exception: check if it was expected. 12744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 12754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exc_info = sys.exc_info() 12764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exc_msg = traceback.format_exception_only(*exc_info[:2])[-1] 12774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not quiet: 12784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm got += _exception_traceback(exc_info) 12794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If `example.exc_msg` is None, then we weren't expecting 12814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # an exception. 12824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if example.exc_msg is None: 12834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outcome = BOOM 12844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # We expected an exception: see whether it matches. 12864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif check(example.exc_msg, exc_msg, self.optionflags): 12874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outcome = SUCCESS 12884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Another chance if they didn't care about the detail. 12904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif self.optionflags & IGNORE_EXCEPTION_DETAIL: 12914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg) 12924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg) 12934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if m1 and m2 and check(m1.group(1), m2.group(1), 12944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.optionflags): 12954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outcome = SUCCESS 12964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Report the outcome. 12984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if outcome is SUCCESS: 12994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not quiet: 13004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.report_success(out, test, example, got) 13014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif outcome is FAILURE: 13024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not quiet: 13034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.report_failure(out, test, example, got) 13044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failures += 1 13054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif outcome is BOOM: 13064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not quiet: 13074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.report_unexpected_exception(out, test, example, 13084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exc_info) 13094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failures += 1 13104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 13114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert False, ("unknown outcome", outcome) 13124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Restore the option flags (in case they were modified) 13144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.optionflags = original_optionflags 13154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Record and return the number of failures and tries. 13174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__record_outcome(test, failures, tries) 13184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return TestResults(failures, tries) 13194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __record_outcome(self, test, f, t): 13214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 13224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Record the fact that the given DocTest (`test`) generated `f` 13234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failures out of `t` tried examples. 13244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 13254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f2, t2 = self._name2ft.get(test.name, (0,0)) 13264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._name2ft[test.name] = (f+f2, t+t2) 13274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.failures += f 13284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.tries += t 13294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __LINECACHE_FILENAME_RE = re.compile(r'<doctest ' 13314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r'(?P<name>.+)' 13324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r'\[(?P<examplenum>\d+)\]>$') 13334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __patched_linecache_getlines(self, filename, module_globals=None): 13344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = self.__LINECACHE_FILENAME_RE.match(filename) 13354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if m and m.group('name') == self.test.name: 13364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm example = self.test.examples[int(m.group('examplenum'))] 13374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source = example.source 13384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(source, unicode): 13394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source = source.encode('ascii', 'backslashreplace') 13404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return source.splitlines(True) 13414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 13424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.save_linecache_getlines(filename, module_globals) 13434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def run(self, test, compileflags=None, out=None, clear_globs=True): 13454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 13464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Run the examples in `test`, and display the results using the 13474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm writer function `out`. 13484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The examples are run in the namespace `test.globs`. If 13504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `clear_globs` is true (the default), then this namespace will 13514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm be cleared after the test runs, to help with garbage 13524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm collection. If you would like to examine the namespace after 13534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the test completes, then use `clear_globs=False`. 13544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `compileflags` gives the set of flags that should be used by 13564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the Python compiler when running the examples. If not 13574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm specified, then it will default to the set of future-import 13584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flags that apply to `globs`. 13594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The output of each example is checked using 13614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `DocTestRunner.check_output`, and the results are formatted by 13624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the `DocTestRunner.report_*` methods. 13634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 13644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.test = test 13654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if compileflags is None: 13674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm compileflags = _extract_future_flags(test.globs) 13684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save_stdout = sys.stdout 13704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if out is None: 13714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out = save_stdout.write 13724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout = self._fakeout 13734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Patch pdb.set_trace to restore sys.stdout during interactive 13754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # debugging (so it's not still redirected to self._fakeout). 13764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Note that the interactive output will go to *our* 13774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # save_stdout, even if that's not the real sys.stdout; this 13784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # allows us to write test cases for the set_trace behavior. 13794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save_set_trace = pdb.set_trace 13804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.debugger = _OutputRedirectingPdb(save_stdout) 13814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.debugger.reset() 13824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pdb.set_trace = self.debugger.set_trace 13834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Patch linecache.getlines, so we can see the example's source 13854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # when we're inside the debugger. 13864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.save_linecache_getlines = linecache.getlines 13874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm linecache.getlines = self.__patched_linecache_getlines 13884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Make sure sys.displayhook just prints the value to stdout 13904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save_displayhook = sys.displayhook 13914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.displayhook = sys.__displayhook__ 13924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 13944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.__run(test, compileflags, out) 13954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 13964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout = save_stdout 13974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pdb.set_trace = save_set_trace 13984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm linecache.getlines = self.save_linecache_getlines 13994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.displayhook = save_displayhook 14004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if clear_globs: 14014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test.globs.clear() 14024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #///////////////////////////////////////////////////////////////// 14044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Summarization 14054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #///////////////////////////////////////////////////////////////// 14064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def summarize(self, verbose=None): 14074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 14084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Print a summary of all the test cases that have been run by 14094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm this DocTestRunner, and return a tuple `(f, t)`, where `f` is 14104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the total number of failed examples, and `t` is the total 14114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm number of tried examples. 14124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional `verbose` argument controls how detailed the 14144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm summary is. If the verbosity is not specified, then the 14154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DocTestRunner's verbosity is used. 14164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 14174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if verbose is None: 14184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm verbose = self._verbose 14194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm notests = [] 14204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm passed = [] 14214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failed = [] 14224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm totalt = totalf = 0 14234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for x in self._name2ft.items(): 14244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name, (f, t) = x 14254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert f <= t 14264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm totalt += t 14274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm totalf += f 14284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if t == 0: 14294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm notests.append(name) 14304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif f == 0: 14314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm passed.append( (name, t) ) 14324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 14334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failed.append(x) 14344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if verbose: 14354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if notests: 14364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print len(notests), "items had no tests:" 14374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm notests.sort() 14384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for thing in notests: 14394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print " ", thing 14404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if passed: 14414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print len(passed), "items passed all tests:" 14424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm passed.sort() 14434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for thing, count in passed: 14444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print " %3d tests in %s" % (count, thing) 14454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if failed: 14464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print self.DIVIDER 14474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print len(failed), "items had failures:" 14484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failed.sort() 14494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for thing, (f, t) in failed: 14504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print " %3d of %3d in %s" % (f, t, thing) 14514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if verbose: 14524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print totalt, "tests in", len(self._name2ft), "items." 14534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print totalt - totalf, "passed and", totalf, "failed." 14544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if totalf: 14554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print "***Test Failed***", totalf, "failures." 14564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif verbose: 14574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print "Test passed." 14584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return TestResults(totalf, totalt) 14594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #///////////////////////////////////////////////////////////////// 14614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Backward compatibility cruft to maintain doctest.master. 14624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #///////////////////////////////////////////////////////////////// 14634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def merge(self, other): 14644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d = self._name2ft 14654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for name, (f, t) in other._name2ft.items(): 14664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if name in d: 14674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Don't print here by default, since doing 14684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # so breaks some of the buildbots 14694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #print "*** DocTestRunner.merge: '" + name + "' in both" \ 14704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # " testers; summing outcomes." 14714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f2, t2 = d[name] 14724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f = f + f2 14734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t = t + t2 14744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[name] = f, t 14754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass OutputChecker: 14774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 14784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A class used to check the whether the actual output from a doctest 14794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm example matches the expected output. `OutputChecker` defines two 14804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm methods: `check_output`, which compares a given pair of outputs, 14814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and returns true if they match; and `output_difference`, which 14824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm returns a string describing the differences between two outputs. 14834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 14844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def check_output(self, want, got, optionflags): 14854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 14864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return True iff the actual output from an example (`got`) 14874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm matches the expected output (`want`). These strings are 14884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm always considered to match if they are identical; but 14894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm depending on what option flags the test runner is using, 14904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm several non-exact match types are also possible. See the 14914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm documentation for `TestRunner` for more information about 14924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm option flags. 14934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 14944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Handle the common case first, for efficiency: 14954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # if they're string-identical, always return true. 14964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if got == want: 14974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 14984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The values True and False replaced 1 and 0 as the return 15004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # value for boolean comparisons in Python 2.3. 15014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not (optionflags & DONT_ACCEPT_TRUE_FOR_1): 15024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (got,want) == ("True\n", "1\n"): 15034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 15044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (got,want) == ("False\n", "0\n"): 15054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 15064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # <BLANKLINE> can be used as a special sequence to signify a 15084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used. 15094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not (optionflags & DONT_ACCEPT_BLANKLINE): 15104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Replace <BLANKLINE> in want with a blank line. 15114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER), 15124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '', want) 15134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If a line in got contains only spaces, then remove the 15144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # spaces. 15154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm got = re.sub('(?m)^\s*?$', '', got) 15164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if got == want: 15174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 15184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This flag causes doctest to ignore any differences in the 15204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # contents of whitespace strings. Note that this can be used 15214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # in conjunction with the ELLIPSIS flag. 15224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if optionflags & NORMALIZE_WHITESPACE: 15234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm got = ' '.join(got.split()) 15244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want = ' '.join(want.split()) 15254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if got == want: 15264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 15274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The ELLIPSIS flag says to let the sequence "..." in `want` 15294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # match any substring in `got`. 15304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if optionflags & ELLIPSIS: 15314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if _ellipsis_match(want, got): 15324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 15334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # We didn't find any match; return false. 15354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 15364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Should we do a fancy diff? 15384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _do_a_fancy_diff(self, want, got, optionflags): 15394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Not unless they asked for a fancy diff. 15404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not optionflags & (REPORT_UDIFF | 15414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_CDIFF | 15424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_NDIFF): 15434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 15444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If expected output uses ellipsis, a meaningful fancy diff is 15464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # too hard ... or maybe not. In two real-life failures Tim saw, 15474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # a diff was a major help anyway, so this is commented out. 15484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # [todo] _ellipsis_match() knows which pieces do and don't match, 15494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # and could be the basis for a kick-ass diff in this case. 15504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want: 15514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ## return False 15524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # ndiff does intraline difference marking, so can be useful even 15544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # for 1-line differences. 15554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if optionflags & REPORT_NDIFF: 15564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 15574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The other diff types need at least a few lines to be helpful. 15594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return want.count('\n') > 2 and got.count('\n') > 2 15604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def output_difference(self, example, got, optionflags): 15624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 15634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return a string describing the differences between the 15644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm expected output for a given example (`example`) and the actual 15654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output (`got`). `optionflags` is the set of option flags used 15664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm to compare `want` and `got`. 15674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 15684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want = example.want 15694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If <BLANKLINE>s are being used, then replace blank lines 15704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # with <BLANKLINE> in the actual output string. 15714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not (optionflags & DONT_ACCEPT_BLANKLINE): 15724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got) 15734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check if we should use diff. 15754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._do_a_fancy_diff(want, got, optionflags): 15764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Split want & got into lines. 15774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want_lines = want.splitlines(True) # True == keep line ends 15784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm got_lines = got.splitlines(True) 15794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Use difflib to find their differences. 15804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if optionflags & REPORT_UDIFF: 15814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm diff = difflib.unified_diff(want_lines, got_lines, n=2) 15824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm diff = list(diff)[2:] # strip the diff header 15834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm kind = 'unified diff with -expected +actual' 15844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif optionflags & REPORT_CDIFF: 15854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm diff = difflib.context_diff(want_lines, got_lines, n=2) 15864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm diff = list(diff)[2:] # strip the diff header 15874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm kind = 'context diff with expected followed by actual' 15884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif optionflags & REPORT_NDIFF: 15894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK) 15904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm diff = list(engine.compare(want_lines, got_lines)) 15914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm kind = 'ndiff with -expected +actual' 15924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 15934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert 0, 'Bad diff option' 15944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Remove trailing whitespace on diff output. 15954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm diff = [line.rstrip() + '\n' for line in diff] 15964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'Differences (%s):\n' % kind + _indent(''.join(diff)) 15974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If we're not using diff, then simply list the expected 15994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # output followed by the actual output. 16004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if want and got: 16014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got)) 16024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif want: 16034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'Expected:\n%sGot nothing\n' % _indent(want) 16044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif got: 16054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'Expected nothing\nGot:\n%s' % _indent(got) 16064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 16074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'Expected nothing\nGot nothing\n' 16084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DocTestFailure(Exception): 16104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """A DocTest example has failed in debugging mode. 16114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The exception instance has variables: 16134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - test: the DocTest object being run 16154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - example: the Example object that failed 16174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - got: the actual output 16194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 16204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, test, example, got): 16214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.test = test 16224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.example = example 16234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.got = got 16244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __str__(self): 16264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return str(self.test) 16274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass UnexpectedException(Exception): 16294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """A DocTest example has encountered an unexpected exception 16304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The exception instance has variables: 16324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - test: the DocTest object being run 16344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - example: the Example object that failed 16364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - exc_info: the exception info 16384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 16394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, test, example, exc_info): 16404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.test = test 16414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.example = example 16424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.exc_info = exc_info 16434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __str__(self): 16454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return str(self.test) 16464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DebugRunner(DocTestRunner): 16484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r"""Run doc tests but raise an exception as soon as there is a failure. 16494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If an unexpected exception occurs, an UnexpectedException is raised. 16514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm It contains the test, the example, and the original exception: 16524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> runner = DebugRunner(verbose=False) 16544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', 16554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... {}, 'foo', 'foo.py', 0) 16564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> try: 16574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... runner.run(test) 16584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... except UnexpectedException, failure: 16594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... pass 16604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.test is test 16624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm True 16634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.example.want 16654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '42\n' 16664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> exc_info = failure.exc_info 16684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> raise exc_info[0], exc_info[1], exc_info[2] 16694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Traceback (most recent call last): 16704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 16714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm KeyError 16724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm We wrap the original exception to give the calling application 16744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm access to the test and example information. 16754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the output doesn't match, then a DocTestFailure is raised: 16774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test = DocTestParser().get_doctest(''' 16794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> x = 1 16804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> x 16814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 2 16824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... ''', {}, 'foo', 'foo.py', 0) 16834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> try: 16854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... runner.run(test) 16864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... except DocTestFailure, failure: 16874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... pass 16884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DocTestFailure objects provide access to the test: 16904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.test is test 16924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm True 16934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm As well as to the example: 16954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.example.want 16974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '2\n' 16984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and the actual output: 17004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.got 17024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '1\n' 17034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If a failure or error occurs, the globals are left intact: 17054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> del test.globs['__builtins__'] 17074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test.globs 17084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {'x': 1} 17094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test = DocTestParser().get_doctest(''' 17114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> x = 2 17124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> raise KeyError 17134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... ''', {}, 'foo', 'foo.py', 0) 17144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> runner.run(test) 17164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Traceback (most recent call last): 17174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 17184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm UnexpectedException: <DocTest foo from foo.py:0 (2 examples)> 17194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> del test.globs['__builtins__'] 17214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test.globs 17224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {'x': 2} 17234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm But the globals are cleared if there is no error: 17254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test = DocTestParser().get_doctest(''' 17274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> x = 2 17284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... ''', {}, 'foo', 'foo.py', 0) 17294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> runner.run(test) 17314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm TestResults(failed=0, attempted=1) 17324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test.globs 17344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {} 17354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 17374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def run(self, test, compileflags=None, out=None, clear_globs=True): 17394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = DocTestRunner.run(self, test, compileflags, out, False) 17404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if clear_globs: 17414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test.globs.clear() 17424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return r 17434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def report_unexpected_exception(self, out, test, example, exc_info): 17454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise UnexpectedException(test, example, exc_info) 17464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def report_failure(self, out, test, example, got): 17484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise DocTestFailure(test, example, got) 17494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 17514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 6. Test Functions 17524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 17534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# These should be backwards compatible. 17544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# For backward compatibility, a global instance of a DocTestRunner 17564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# class, updated by testmod. 17574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmaster = None 17584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef testmod(m=None, name=None, globs=None, verbose=None, 17604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm report=True, optionflags=0, extraglobs=None, 17614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise_on_error=False, exclude_empty=False): 17624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """m=None, name=None, globs=None, verbose=None, report=True, 17634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm optionflags=0, extraglobs=None, raise_on_error=False, 17644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exclude_empty=False 17654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Test examples in docstrings in functions and classes reachable 17674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm from module m (or the current module if m is not supplied), starting 17684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with m.__doc__. 17694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Also test examples reachable from dict m.__test__ if it exists and is 17714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm not None. m.__test__ maps names to functions, classes and strings; 17724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm function and class docstrings are tested even if the name is private; 17734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm strings are tested directly, as if they were docstrings. 17744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return (#failures, #tests). 17764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm See help(doctest) for an overview. 17784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "name" gives the name of the module; by default 17804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm use m.__name__. 17814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "globs" gives a dict to be used as the globals 17834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm when executing examples; by default, use m.__dict__. A copy of this 17844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dict is actually used for each docstring, so that each docstring's 17854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm examples start with a clean slate. 17864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "extraglobs" gives a dictionary that should be 17884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm merged into the globals that are used to execute examples. By 17894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm default, no extra globals are used. This is new in 2.4. 17904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "verbose" prints lots of stuff if true, prints 17924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm only failures if false; by default, it's true iff "-v" is in sys.argv. 17934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "report" prints a summary at the end when true, 17954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else prints nothing at the end. In verbose mode, the summary is 17964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm detailed, else very brief (in fact, empty if all tests passed). 17974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "optionflags" or's together module constants, 17994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and defaults to 0. This is new in 2.3. Possible values (see the 18004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm docs for details): 18014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DONT_ACCEPT_TRUE_FOR_1 18034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DONT_ACCEPT_BLANKLINE 18044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NORMALIZE_WHITESPACE 18054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ELLIPSIS 18064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm SKIP 18074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm IGNORE_EXCEPTION_DETAIL 18084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_UDIFF 18094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_CDIFF 18104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_NDIFF 18114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_ONLY_FIRST_FAILURE 18124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "raise_on_error" raises an exception on the 18144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm first unexpected exception or failure. This allows failures to be 18154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm post-mortem debugged. 18164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Advanced tomfoolery: testmod runs methods of a local instance of 18184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class doctest.Tester, then merges the results into (or creates) 18194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm global Tester instance doctest.master. Methods of doctest.master 18204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm can be called directly too, if you want to do something unusual. 18214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Passing report=0 to testmod is especially useful then, to delay 18224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm displaying a summary. Invoke doctest.master.summarize(verbose) 18234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm when you're done fiddling. 18244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 18254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm global master 18264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If no module was given, then use __main__. 18284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if m is None: 18294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # DWA - m will still be None if this wasn't invoked from the command 18304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # line, in which case the following TypeError is about as good an error 18314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # as we should expect 18324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = sys.modules.get('__main__') 18334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check that we were actually given a module. 18354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not inspect.ismodule(m): 18364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError("testmod: module required; %r" % (m,)) 18374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If no name was given, then use the module's name. 18394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if name is None: 18404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = m.__name__ 18414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find, parse, and run all tests in the given module. 18434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finder = DocTestFinder(exclude_empty=exclude_empty) 18444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if raise_on_error: 18464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner = DebugRunner(verbose=verbose, optionflags=optionflags) 18474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 18484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner = DocTestRunner(verbose=verbose, optionflags=optionflags) 18494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for test in finder.find(m, name, globs=globs, extraglobs=extraglobs): 18514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner.run(test) 18524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if report: 18544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner.summarize() 18554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if master is None: 18574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm master = runner 18584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 18594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm master.merge(runner) 18604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return TestResults(runner.failures, runner.tries) 18624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef testfile(filename, module_relative=True, name=None, package=None, 18644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs=None, verbose=None, report=True, optionflags=0, 18654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm extraglobs=None, raise_on_error=False, parser=DocTestParser(), 18664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding=None): 18674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 18684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Test examples in the given file. Return (#failures, #tests). 18694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "module_relative" specifies how filenames 18714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm should be interpreted: 18724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - If "module_relative" is True (the default), then "filename" 18744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm specifies a module-relative path. By default, this path is 18754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm relative to the calling module's directory; but if the 18764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "package" argument is specified, then it is relative to that 18774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm package. To ensure os-independence, "filename" should use 18784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "/" characters to separate path segments, and should not 18794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm be an absolute path (i.e., it may not begin with "/"). 18804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - If "module_relative" is False, then "filename" specifies an 18824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm os-specific path. The path may be absolute or relative (to 18834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the current working directory). 18844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "name" gives the name of the test; by default 18864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm use the file's basename. 18874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword argument "package" is a Python package or the 18894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name of a Python package whose directory should be used as the 18904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm base directory for a module relative filename. If no package is 18914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm specified, then the calling module's directory is used as the base 18924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm directory for module relative filenames. It is an error to 18934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm specify "package" if "module_relative" is False. 18944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "globs" gives a dict to be used as the globals 18964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm when executing examples; by default, use {}. A copy of this dict 18974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm is actually used for each docstring, so that each docstring's 18984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm examples start with a clean slate. 18994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "extraglobs" gives a dictionary that should be 19014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm merged into the globals that are used to execute examples. By 19024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm default, no extra globals are used. 19034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "verbose" prints lots of stuff if true, prints 19054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm only failures if false; by default, it's true iff "-v" is in sys.argv. 19064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "report" prints a summary at the end when true, 19084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else prints nothing at the end. In verbose mode, the summary is 19094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm detailed, else very brief (in fact, empty if all tests passed). 19104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "optionflags" or's together module constants, 19124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and defaults to 0. Possible values (see the docs for details): 19134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DONT_ACCEPT_TRUE_FOR_1 19154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DONT_ACCEPT_BLANKLINE 19164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NORMALIZE_WHITESPACE 19174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ELLIPSIS 19184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm SKIP 19194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm IGNORE_EXCEPTION_DETAIL 19204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_UDIFF 19214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_CDIFF 19224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_NDIFF 19234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REPORT_ONLY_FIRST_FAILURE 19244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "raise_on_error" raises an exception on the 19264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm first unexpected exception or failure. This allows failures to be 19274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm post-mortem debugged. 19284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "parser" specifies a DocTestParser (or 19304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm subclass) that should be used to extract tests from the files. 19314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg "encoding" specifies an encoding that should 19334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm be used to convert the file to unicode. 19344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Advanced tomfoolery: testmod runs methods of a local instance of 19364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class doctest.Tester, then merges the results into (or creates) 19374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm global Tester instance doctest.master. Methods of doctest.master 19384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm can be called directly too, if you want to do something unusual. 19394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Passing report=0 to testmod is especially useful then, to delay 19404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm displaying a summary. Invoke doctest.master.summarize(verbose) 19414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm when you're done fiddling. 19424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 19434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm global master 19444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if package and not module_relative: 19464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("Package may only be specified for module-" 19474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "relative paths.") 19484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Relativize the path 19504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm text, filename = _load_testfile(filename, package, module_relative) 19514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If no name was given, then use the file's name. 19534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if name is None: 19544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = os.path.basename(filename) 19554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Assemble the globals. 19574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if globs is None: 19584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = {} 19594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 19604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = globs.copy() 19614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if extraglobs is not None: 19624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs.update(extraglobs) 19634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if '__name__' not in globs: 19644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs['__name__'] = '__main__' 19654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if raise_on_error: 19674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner = DebugRunner(verbose=verbose, optionflags=optionflags) 19684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 19694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner = DocTestRunner(verbose=verbose, optionflags=optionflags) 19704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if encoding is not None: 19724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm text = text.decode(encoding) 19734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Read the file, convert it to a test, and run it. 19754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = parser.get_doctest(text, globs, name, filename, 0) 19764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner.run(test) 19774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if report: 19794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner.summarize() 19804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if master is None: 19824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm master = runner 19834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 19844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm master.merge(runner) 19854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return TestResults(runner.failures, runner.tries) 19874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef run_docstring_examples(f, globs, verbose=False, name="NoName", 19894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm compileflags=None, optionflags=0): 19904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 19914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Test examples in the given object's docstring (`f`), using `globs` 19924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm as globals. Optional argument `name` is used in failure messages. 19934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the optional argument `verbose` is true, then generate output 19944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm even if there are no failures. 19954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `compileflags` gives the set of flags that should be used by the 19974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Python compiler when running the examples. If not specified, then 19984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm it will default to the set of future-import flags that apply to 19994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm `globs`. 20004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Optional keyword arg `optionflags` specifies options for the 20024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testing and output. See the documentation for `testmod` for more 20034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm information. 20044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 20054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find, parse, and run all tests in the given module. 20064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finder = DocTestFinder(verbose=verbose, recurse=False) 20074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner = DocTestRunner(verbose=verbose, optionflags=optionflags) 20084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for test in finder.find(f, name, globs=globs): 20094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner.run(test, compileflags=compileflags) 20104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 20124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 7. Tester 20134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 20144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# This is provided only for backwards compatibility. It's not 20154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# actually used in any way. 20164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Tester: 20184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, mod=None, globs=None, verbose=None, optionflags=0): 20194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm warnings.warn("class Tester is deprecated; " 20214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "use class doctest.DocTestRunner instead", 20224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DeprecationWarning, stacklevel=2) 20234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if mod is None and globs is None: 20244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError("Tester.__init__: must specify mod or globs") 20254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if mod is not None and not inspect.ismodule(mod): 20264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError("Tester.__init__: mod must be a module; %r" % 20274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (mod,)) 20284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if globs is None: 20294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = mod.__dict__ 20304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.globs = globs 20314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.verbose = verbose 20334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.optionflags = optionflags 20344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.testfinder = DocTestFinder() 20354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.testrunner = DocTestRunner(verbose=verbose, 20364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm optionflags=optionflags) 20374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def runstring(self, s, name): 20394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = DocTestParser().get_doctest(s, self.globs, name, None, None) 20404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.verbose: 20414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print "Running string", name 20424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (f,t) = self.testrunner.run(test) 20434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.verbose: 20444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print f, "of", t, "examples failed in string", name 20454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return TestResults(f,t) 20464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def rundoc(self, object, name=None, module=None): 20484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f = t = 0 20494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests = self.testfinder.find(object, name, module=module, 20504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs=self.globs) 20514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for test in tests: 20524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (f2, t2) = self.testrunner.run(test) 20534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (f,t) = (f+f2, t+t2) 20544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return TestResults(f,t) 20554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def rundict(self, d, name, module=None): 20574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import types 20584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = types.ModuleType(name) 20594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m.__dict__.update(d) 20604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module is None: 20614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = False 20624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.rundoc(m, name, module) 20634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def run__test__(self, d, name): 20654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import types 20664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = types.ModuleType(name) 20674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m.__test__ = d 20684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.rundoc(m, name) 20694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def summarize(self, verbose=None): 20714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.testrunner.summarize(verbose) 20724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def merge(self, other): 20744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.testrunner.merge(other.testrunner) 20754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 20774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 8. Unittest Support 20784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 20794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_unittest_reportflags = 0 20814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef set_unittest_reportflags(flags): 20834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Sets the unittest option flags. 20844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The old flag is returned so that a runner could restore the old 20864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value if it wished to: 20874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> import doctest 20894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> old = doctest._unittest_reportflags 20904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> doctest.set_unittest_reportflags(REPORT_NDIFF | 20914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... REPORT_ONLY_FIRST_FAILURE) == old 20924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm True 20934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> doctest._unittest_reportflags == (REPORT_NDIFF | 20954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... REPORT_ONLY_FIRST_FAILURE) 20964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm True 20974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Only reporting flags can be set: 20994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> doctest.set_unittest_reportflags(ELLIPSIS) 21014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Traceback (most recent call last): 21024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 21034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ValueError: ('Only reporting flags allowed', 8) 21044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> doctest.set_unittest_reportflags(old) == (REPORT_NDIFF | 21064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... REPORT_ONLY_FIRST_FAILURE) 21074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm True 21084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 21094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm global _unittest_reportflags 21104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (flags & REPORTING_FLAGS) != flags: 21124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("Only reporting flags allowed", flags) 21134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm old = _unittest_reportflags 21144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _unittest_reportflags = flags 21154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return old 21164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DocTestCase(unittest.TestCase): 21194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, test, optionflags=0, setUp=None, tearDown=None, 21214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm checker=None): 21224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unittest.TestCase.__init__(self) 21244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._dt_optionflags = optionflags 21254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._dt_checker = checker 21264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._dt_test = test 21274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._dt_setUp = setUp 21284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._dt_tearDown = tearDown 21294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def setUp(self): 21314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = self._dt_test 21324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._dt_setUp is not None: 21344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._dt_setUp(test) 21354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def tearDown(self): 21374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = self._dt_test 21384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self._dt_tearDown is not None: 21404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._dt_tearDown(test) 21414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test.globs.clear() 21434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def runTest(self): 21454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = self._dt_test 21464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm old = sys.stdout 21474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm new = StringIO() 21484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm optionflags = self._dt_optionflags 21494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not (optionflags & REPORTING_FLAGS): 21514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The option flags don't include any reporting flags, 21524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # so add the default reporting flags 21534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm optionflags |= _unittest_reportflags 21544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner = DocTestRunner(optionflags=optionflags, 21564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm checker=self._dt_checker, verbose=False) 21574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 21594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner.DIVIDER = "-"*70 21604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failures, tries = runner.run( 21614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test, out=new.write, clear_globs=False) 21624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 21634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout = old 21644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if failures: 21664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise self.failureException(self.format_failure(new.getvalue())) 21674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def format_failure(self, err): 21694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = self._dt_test 21704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if test.lineno is None: 21714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = 'unknown line number' 21724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 21734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lineno = '%s' % test.lineno 21744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lname = '.'.join(test.name.split('.')[-1:]) 21754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return ('Failed doctest test for %s\n' 21764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ' File "%s", line %s, in %s\n\n%s' 21774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm % (test.name, test.filename, lineno, lname, err) 21784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ) 21794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def debug(self): 21814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r"""Run the test case without results and without catching exceptions 21824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The unit test framework includes a debug method on test cases 21844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and test suites to support post-mortem debugging. The test code 21854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm is run in such a way that errors are not caught. This way a 21864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm caller can catch the errors and initiate post-mortem debugging. 21874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The DocTestCase provides a debug method that raises 21894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm UnexpectedException errors if there is an unexpected 21904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exception: 21914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', 21934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... {}, 'foo', 'foo.py', 0) 21944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> case = DocTestCase(test) 21954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> try: 21964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... case.debug() 21974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... except UnexpectedException, failure: 21984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... pass 21994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The UnexpectedException contains the test, the example, and 22014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the original exception: 22024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.test is test 22044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm True 22054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.example.want 22074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '42\n' 22084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> exc_info = failure.exc_info 22104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> raise exc_info[0], exc_info[1], exc_info[2] 22114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Traceback (most recent call last): 22124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 22134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm KeyError 22144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the output doesn't match, then a DocTestFailure is raised: 22164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> test = DocTestParser().get_doctest(''' 22184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> x = 1 22194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> x 22204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 2 22214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... ''', {}, 'foo', 'foo.py', 0) 22224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> case = DocTestCase(test) 22234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> try: 22254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... case.debug() 22264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... except DocTestFailure, failure: 22274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... pass 22284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DocTestFailure objects provide access to the test: 22304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.test is test 22324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm True 22334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm As well as to the example: 22354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.example.want 22374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '2\n' 22384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and the actual output: 22404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> failure.got 22424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '1\n' 22434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 22454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.setUp() 22474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner = DebugRunner(optionflags=self._dt_optionflags, 22484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm checker=self._dt_checker, verbose=False) 22494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm runner.run(self._dt_test, clear_globs=False) 22504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.tearDown() 22514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def id(self): 22534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._dt_test.name 22544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __repr__(self): 22564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = self._dt_test.name.split('.') 22574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return "%s (%s)" % (name[-1], '.'.join(name[:-1])) 22584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __str__ = __repr__ 22604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def shortDescription(self): 22624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return "Doctest: " + self._dt_test.name 22634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass SkipDocTestCase(DocTestCase): 22654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self): 22664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DocTestCase.__init__(self, None) 22674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def setUp(self): 22694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.skipTest("DocTestSuite will not work with -O2 and above") 22704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_skip(self): 22724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 22734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def shortDescription(self): 22754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return "Skipping tests from %s" % module.__name__ 22764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, 22784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm **options): 22794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 22804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Convert doctest tests for a module to a unittest test suite. 22814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This converts each documentation string in a module that 22834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm contains doctest tests to a unittest test case. If any of the 22844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests in a doc string fail, then the test case fails. An exception 22854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm is raised showing the name of the file containing the test and a 22864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (sometimes approximate) line number. 22874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The `module` argument provides the module to be tested. The argument 22894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm can be either a module or a module name. 22904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If no argument is given, the calling module is used. 22924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A number of options may be provided as keyword arguments: 22944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setUp 22964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A set-up function. This is called before running the 22974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests in each file. The setUp function will be passed a DocTest 22984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object. The setUp function can access the test globals as the 22994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs attribute of the test passed. 23004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tearDown 23024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A tear-down function. This is called after running the 23034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests in each file. The tearDown function will be passed a DocTest 23044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object. The tearDown function can access the test globals as the 23054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs attribute of the test passed. 23064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs 23084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A dictionary containing initial global variables for the tests. 23094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm optionflags 23114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A set of doctest option flags expressed as an integer. 23124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 23134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if test_finder is None: 23154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test_finder = DocTestFinder() 23164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = _normalize_module(module) 23184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests = test_finder.find(module, globs=globs, extraglobs=extraglobs) 23194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not tests and sys.flags.optimize >=2: 23214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Skip doctests when running with -O2 23224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm suite = unittest.TestSuite() 23234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm suite.addTest(SkipDocTestCase()) 23244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return suite 23254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif not tests: 23264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Why do we want to do this? Because it reveals a bug that might 23274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # otherwise be hidden. 23284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError(module, "has no tests") 23294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests.sort() 23314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm suite = unittest.TestSuite() 23324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for test in tests: 23344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(test.examples) == 0: 23354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm continue 23364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not test.filename: 23374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename = module.__file__ 23384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if filename[-4:] in (".pyc", ".pyo"): 23394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filename = filename[:-1] 23404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test.filename = filename 23414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm suite.addTest(DocTestCase(test, **options)) 23424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return suite 23444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DocFileCase(DocTestCase): 23464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def id(self): 23484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return '_'.join(self._dt_test.name.split('.')) 23494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __repr__(self): 23514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self._dt_test.filename 23524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __str__ = __repr__ 23534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def format_failure(self, err): 23554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return ('Failed doctest test for %s\n File "%s", line 0\n\n%s' 23564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm % (self._dt_test.name, self._dt_test.filename, err) 23574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ) 23584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef DocFileTest(path, module_relative=True, package=None, 23604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs=None, parser=DocTestParser(), 23614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding=None, **options): 23624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if globs is None: 23634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = {} 23644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 23654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = globs.copy() 23664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if package and not module_relative: 23684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("Package may only be specified for module-" 23694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "relative paths.") 23704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Relativize the path. 23724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm doc, path = _load_testfile(path, package, module_relative) 23734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if "__file__" not in globs: 23754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs["__file__"] = path 23764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Find the file and read it. 23784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = os.path.basename(path) 23794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If an encoding is specified, use it to convert the file to unicode 23814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if encoding is not None: 23824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm doc = doc.decode(encoding) 23834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Convert it to a test, and wrap it in a DocFileCase. 23854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = parser.get_doctest(doc, globs, name, path, 0) 23864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return DocFileCase(test, **options) 23874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef DocFileSuite(*paths, **kw): 23894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """A unittest suite for one or more doctest files. 23904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The path to each doctest file is given as a string; the 23924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm interpretation of that string depends on the keyword argument 23934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "module_relative". 23944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A number of options may be provided as keyword arguments: 23964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module_relative 23984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If "module_relative" is True, then the given file paths are 23994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm interpreted as os-independent module-relative paths. By 24004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm default, these paths are relative to the calling module's 24014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm directory; but if the "package" argument is specified, then 24024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm they are relative to that package. To ensure os-independence, 24034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "filename" should use "/" characters to separate path 24044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm segments, and may not be an absolute path (i.e., it may not 24054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm begin with "/"). 24064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If "module_relative" is False, then the given file paths are 24084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm interpreted as os-specific paths. These paths may be absolute 24094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm or relative (to the current working directory). 24104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm package 24124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A Python package or the name of a Python package whose directory 24134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm should be used as the base directory for module relative paths. 24144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If "package" is not specified, then the calling module's 24154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm directory is used as the base directory for module relative 24164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filenames. It is an error to specify "package" if 24174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "module_relative" is False. 24184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setUp 24204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A set-up function. This is called before running the 24214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests in each file. The setUp function will be passed a DocTest 24224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object. The setUp function can access the test globals as the 24234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs attribute of the test passed. 24244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tearDown 24264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A tear-down function. This is called after running the 24274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests in each file. The tearDown function will be passed a DocTest 24284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object. The tearDown function can access the test globals as the 24294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs attribute of the test passed. 24304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs 24324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A dictionary containing initial global variables for the tests. 24334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm optionflags 24354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A set of doctest option flags expressed as an integer. 24364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm parser 24384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A DocTestParser (or subclass) that should be used to extract 24394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests from the files. 24404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding 24424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm An encoding that will be used to convert the files to unicode. 24434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 24444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm suite = unittest.TestSuite() 24454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # We do this here so that _normalize_module is called at the right 24474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # level. If it were called in DocFileTest, then this function 24484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # would be the caller and we might guess the package incorrectly. 24494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if kw.get('module_relative', True): 24504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm kw['package'] = _normalize_module(kw.get('package')) 24514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for path in paths: 24534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm suite.addTest(DocFileTest(path, **kw)) 24544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return suite 24564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 24584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 9. Debugging Support 24594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 24604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef script_from_examples(s): 24624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r"""Extract script from text with examples. 24634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Converts text with examples to a Python script. Example input is 24654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm converted to regular code. Example output and all other words 24664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm are converted to comments: 24674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> text = ''' 24694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... Here are examples of simple math. 24704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 24714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... Python has super accurate integer addition 24724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 24734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> 2 + 2 24744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 5 24754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 24764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... And very friendly error messages: 24774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 24784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> 1/0 24794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... To Infinity 24804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... And 24814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... Beyond 24824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 24834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... You can use logic if you want: 24844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 24854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... >>> if 0: 24864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... ... blah 24874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... ... blah 24884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... ... 24894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... 24904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... Ho hum 24914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ... ''' 24924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> print script_from_examples(text) 24944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Here are examples of simple math. 24954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 24964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Python has super accurate integer addition 24974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 24984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2 + 2 24994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Expected: 25004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ## 5 25014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 25024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # And very friendly error messages: 25034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 25044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1/0 25054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Expected: 25064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ## To Infinity 25074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ## And 25084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ## Beyond 25094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 25104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # You can use logic if you want: 25114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 25124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if 0: 25134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm blah 25144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm blah 25154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 25164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Ho hum 25174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm <BLANKLINE> 25184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 25194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output = [] 25204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for piece in DocTestParser().parse(s): 25214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(piece, Example): 25224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Add the example's source code (strip trailing NL) 25234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output.append(piece.source[:-1]) 25244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Add the expected output: 25254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm want = piece.want 25264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if want: 25274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output.append('# Expected:') 25284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output += ['## '+l for l in want.split('\n')[:-1]] 25294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 25304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Add non-example text. 25314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output += [_comment_line(l) 25324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for l in piece.split('\n')[:-1]] 25334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Trim junk on both ends. 25354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while output and output[-1] == '#': 25364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output.pop() 25374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while output and output[0] == '#': 25384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output.pop(0) 25394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Combine the output, and return it. 25404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Add a courtesy newline to prevent exec from choking (see bug #1172785) 25414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return '\n'.join(output) + '\n' 25424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef testsource(module, name): 25444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Extract the test sources from a doctest docstring as a script. 25454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Provide the module (or dotted name of the module) containing the 25474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test to be debugged and the name (within the module) of the object 25484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with the doc string with tests to be debugged. 25494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 25504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = _normalize_module(module) 25514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tests = DocTestFinder().find(module) 25524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = [t for t in tests if t.name == name] 25534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not test: 25544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError(name, "not found in tests") 25554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test = test[0] 25564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testsrc = script_from_examples(test.docstring) 25574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return testsrc 25584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef debug_src(src, pm=False, globs=None): 25604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Debug a single doctest docstring, in argument `src`'""" 25614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testsrc = script_from_examples(src) 25624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm debug_script(testsrc, pm, globs) 25634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef debug_script(src, pm=False, globs=None): 25654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Debug a test script. `src` is the script, as a string." 25664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import pdb 25674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Note that tempfile.NameTemporaryFile() cannot be used. As the 25694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # docs say, a file so created cannot be opened by name a second time 25704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # on modern Windows boxes, and execfile() needs to open it. 25714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm srcfilename = tempfile.mktemp(".py", "doctestdebug") 25724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f = open(srcfilename, 'w') 25734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f.write(src) 25744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f.close() 25754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 25774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if globs: 25784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = globs.copy() 25794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 25804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm globs = {} 25814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if pm: 25834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 25844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm execfile(srcfilename, globs, globs) 25854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except: 25864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print sys.exc_info()[1] 25874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pdb.post_mortem(sys.exc_info()[2]) 25884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 25894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Note that %r is vital here. '%s' instead can, e.g., cause 25904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # backslashes to get treated as metacharacters on Windows. 25914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pdb.run("execfile(%r)" % srcfilename, globs, globs) 25924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 25944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm os.remove(srcfilename) 25954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef debug(module, name, pm=False): 25974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Debug a single doctest docstring. 25984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Provide the module (or dotted name of the module) containing the 26004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test to be debugged and the name (within the module) of the object 26014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with the docstring with tests to be debugged. 26024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 26034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = _normalize_module(module) 26044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testsrc = testsource(module, name) 26054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm debug_script(testsrc, pm, module.__dict__) 26064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 26084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## 10. Example Usage 26094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm###################################################################### 26104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass _TestClass: 26114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 26124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A pointless class, for sanity-checking of docstring testing. 26134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Methods: 26154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm square() 26164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm get() 26174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> _TestClass(13).get() + _TestClass(-12).get() 26194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1 26204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> hex(_TestClass(13).square().get()) 26214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '0xa9' 26224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 26234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, val): 26254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """val -> _TestClass object with associated value val. 26264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> t = _TestClass(123) 26284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> print t.get() 26294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 123 26304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 26314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.val = val 26334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def square(self): 26354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """square() -> square TestClass's associated value 26364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> _TestClass(13).square().get() 26384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 169 26394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 26404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.val = self.val ** 2 26424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self 26434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def get(self): 26454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """get() -> return TestClass's associated value. 26464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> x = _TestClass(-42) 26484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> print x.get() 26494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm -42 26504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 26514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.val 26534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__test__ = {"_TestClass": _TestClass, 26554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "string": r""" 26564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Example of a string object, searched as-is. 26574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> x = 1; y = 2 26584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> x + y, x * y 26594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (3, 2) 26604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """, 26614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "bool-int equivalence": r""" 26634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm In 2.2, boolean expressions displayed 26644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0 or 1. By default, we still accept 26654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm them. This can be disabled by passing 26664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DONT_ACCEPT_TRUE_FOR_1 to the new 26674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm optionflags argument. 26684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> 4 == 4 26694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1 26704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> 4 == 4 26714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm True 26724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> 4 > 4 26734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0 26744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> 4 > 4 26754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm False 26764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """, 26774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "blank lines": r""" 26794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Blank lines can be marked with <BLANKLINE>: 26804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> print 'foo\n\nbar\n' 26814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm foo 26824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm <BLANKLINE> 26834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm bar 26844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm <BLANKLINE> 26854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """, 26864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "ellipsis": r""" 26884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the ellipsis flag is used, then '...' can be used to 26894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elide substrings in the desired output: 26904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> print range(1000) #doctest: +ELLIPSIS 26914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [0, 1, 2, ..., 999] 26924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """, 26934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 26944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "whitespace normalization": r""" 26954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the whitespace normalization flag is used, then 26964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm differences in whitespace are ignored. 26974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> print range(30) #doctest: +NORMALIZE_WHITESPACE 26984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 26994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 27, 28, 29] 27014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """, 27024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 27034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 27044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 27054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _test(): 27064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-'] 27074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not testfiles: 27084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = os.path.basename(sys.argv[0]) 27094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if '__loader__' in globals(): # python -m 27104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name, _ = os.path.splitext(name) 27114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print("usage: {0} [-v] file ...".format(name)) 27124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 2 27134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for filename in testfiles: 27144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if filename.endswith(".py"): 27154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # It is a module -- insert its dir into sys.path and try to 27164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # import it. If it is part of a package, that possibly 27174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # won't work because of package imports. 27184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dirname, filename = os.path.split(filename) 27194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.path.insert(0, dirname) 27204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = __import__(filename[:-3]) 27214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del sys.path[0] 27224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failures, _ = testmod(m) 27234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 27244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm failures, _ = testfile(filename, module_relative=False) 27254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if failures: 27264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 1 27274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0 27284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 27294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 27304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__": 27314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.exit(_test()) 2732