@@ -101,15 +101,14 @@ def _test():
101
101
import re
102
102
import sys
103
103
import traceback
104
+ import types
104
105
import unittest
105
106
from io import StringIO , IncrementalNewlineDecoder
106
107
from collections import namedtuple
107
108
import _colorize # Used in doctests
108
109
from _colorize import ANSIColors , can_colorize
109
110
110
111
111
- __unittest = True
112
-
113
112
class TestResults (namedtuple ('TestResults' , 'failed attempted' )):
114
113
def __new__ (cls , failed , attempted , * , skipped = 0 ):
115
114
results = super ().__new__ (cls , failed , attempted )
@@ -387,7 +386,7 @@ def __init__(self, out):
387
386
self .__out = out
388
387
self .__debugger_used = False
389
388
# do not play signal games in the pdb
390
- pdb . Pdb . __init__ (self , stdout = out , nosigint = True )
389
+ super (). __init__ (stdout = out , nosigint = True )
391
390
# still use input() to get user input
392
391
self .use_rawinput = 1
393
392
@@ -1280,6 +1279,11 @@ def __init__(self, checker=None, verbose=None, optionflags=0):
1280
1279
# Reporting methods
1281
1280
#/////////////////////////////////////////////////////////////////
1282
1281
1282
+ def report_skip (self , out , test , example ):
1283
+ """
1284
+ Report that the given example was skipped.
1285
+ """
1286
+
1283
1287
def report_start (self , out , test , example ):
1284
1288
"""
1285
1289
Report that the test runner is about to process the given
@@ -1377,6 +1381,8 @@ def __run(self, test, compileflags, out):
1377
1381
1378
1382
# If 'SKIP' is set, then skip this example.
1379
1383
if self .optionflags & SKIP :
1384
+ if not quiet :
1385
+ self .report_skip (out , test , example )
1380
1386
skips += 1
1381
1387
continue
1382
1388
@@ -2274,12 +2280,63 @@ def set_unittest_reportflags(flags):
2274
2280
return old
2275
2281
2276
2282
2283
+ class _DocTestCaseRunner (DocTestRunner ):
2284
+
2285
+ def __init__ (self , * args , test_case , test_result , ** kwargs ):
2286
+ super ().__init__ (* args , ** kwargs )
2287
+ self ._test_case = test_case
2288
+ self ._test_result = test_result
2289
+ self ._examplenum = 0
2290
+
2291
+ def _subTest (self ):
2292
+ subtest = unittest .case ._SubTest (self ._test_case , str (self ._examplenum ), {})
2293
+ self ._examplenum += 1
2294
+ return subtest
2295
+
2296
+ def report_skip (self , out , test , example ):
2297
+ unittest .case ._addSkip (self ._test_result , self ._subTest (), '' )
2298
+
2299
+ def report_success (self , out , test , example , got ):
2300
+ self ._test_result .addSubTest (self ._test_case , self ._subTest (), None )
2301
+
2302
+ def report_unexpected_exception (self , out , test , example , exc_info ):
2303
+ tb = self ._add_traceback (exc_info [2 ], test , example )
2304
+ exc_info = (* exc_info [:2 ], tb )
2305
+ self ._test_result .addSubTest (self ._test_case , self ._subTest (), exc_info )
2306
+
2307
+ def report_failure (self , out , test , example , got ):
2308
+ msg = ('Failed example:\n ' + _indent (example .source ) +
2309
+ self ._checker .output_difference (example , got , self .optionflags ).rstrip ('\n ' ))
2310
+ exc = self ._test_case .failureException (msg )
2311
+ tb = self ._add_traceback (None , test , example )
2312
+ exc_info = (type (exc ), exc , tb )
2313
+ self ._test_result .addSubTest (self ._test_case , self ._subTest (), exc_info )
2314
+
2315
+ def _add_traceback (self , traceback , test , example ):
2316
+ if test .lineno is None or example .lineno is None :
2317
+ lineno = None
2318
+ else :
2319
+ lineno = test .lineno + example .lineno + 1
2320
+ return types .SimpleNamespace (
2321
+ tb_frame = types .SimpleNamespace (
2322
+ f_globals = test .globs ,
2323
+ f_code = types .SimpleNamespace (
2324
+ co_filename = test .filename ,
2325
+ co_name = test .name ,
2326
+ ),
2327
+ ),
2328
+ tb_next = traceback ,
2329
+ tb_lasti = - 1 ,
2330
+ tb_lineno = lineno ,
2331
+ )
2332
+
2333
+
2277
2334
class DocTestCase (unittest .TestCase ):
2278
2335
2279
2336
def __init__ (self , test , optionflags = 0 , setUp = None , tearDown = None ,
2280
2337
checker = None ):
2281
2338
2282
- unittest . TestCase . __init__ (self )
2339
+ super (). __init__ ()
2283
2340
self ._dt_optionflags = optionflags
2284
2341
self ._dt_checker = checker
2285
2342
self ._dt_test = test
@@ -2303,30 +2360,28 @@ def tearDown(self):
2303
2360
test .globs .clear ()
2304
2361
test .globs .update (self ._dt_globs )
2305
2362
2363
+ def run (self , result = None ):
2364
+ self ._test_result = result
2365
+ return super ().run (result )
2366
+
2306
2367
def runTest (self ):
2307
2368
test = self ._dt_test
2308
- old = sys .stdout
2309
- new = StringIO ()
2310
2369
optionflags = self ._dt_optionflags
2370
+ result = self ._test_result
2311
2371
2312
2372
if not (optionflags & REPORTING_FLAGS ):
2313
2373
# The option flags don't include any reporting flags,
2314
2374
# so add the default reporting flags
2315
2375
optionflags |= _unittest_reportflags
2376
+ if getattr (result , 'failfast' , False ):
2377
+ optionflags |= FAIL_FAST
2316
2378
2317
- runner = DocTestRunner (optionflags = optionflags ,
2318
- checker = self ._dt_checker , verbose = False )
2319
-
2320
- try :
2321
- runner .DIVIDER = "-" * 70
2322
- results = runner .run (test , out = new .write , clear_globs = False )
2323
- if results .skipped == results .attempted :
2324
- raise unittest .SkipTest ("all examples were skipped" )
2325
- finally :
2326
- sys .stdout = old
2327
-
2328
- if results .failed :
2329
- raise self .failureException (self .format_failure (new .getvalue ().rstrip ('\n ' )))
2379
+ runner = _DocTestCaseRunner (optionflags = optionflags ,
2380
+ checker = self ._dt_checker , verbose = False ,
2381
+ test_case = self , test_result = result )
2382
+ results = runner .run (test , clear_globs = False )
2383
+ if results .skipped == results .attempted :
2384
+ raise unittest .SkipTest ("all examples were skipped" )
2330
2385
2331
2386
def format_failure (self , err ):
2332
2387
test = self ._dt_test
@@ -2441,7 +2496,7 @@ def shortDescription(self):
2441
2496
class SkipDocTestCase (DocTestCase ):
2442
2497
def __init__ (self , module ):
2443
2498
self .module = module
2444
- DocTestCase .__init__ (self , None )
2499
+ super () .__init__ (None )
2445
2500
2446
2501
def setUp (self ):
2447
2502
self .skipTest ("DocTestSuite will not work with -O2 and above" )
0 commit comments