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