@@ -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
@@ -2275,12 +2281,63 @@ def set_unittest_reportflags(flags):
2275
2281
return old
2276
2282
2277
2283
2284
+ class _DocTestCaseRunner (DocTestRunner ):
2285
+
2286
+ def __init__ (self , * args , test_case , test_result , ** kwargs ):
2287
+ super ().__init__ (* args , ** kwargs )
2288
+ self ._test_case = test_case
2289
+ self ._test_result = test_result
2290
+ self ._examplenum = 0
2291
+
2292
+ def _subTest (self ):
2293
+ subtest = unittest .case ._SubTest (self ._test_case , str (self ._examplenum ), {})
2294
+ self ._examplenum += 1
2295
+ return subtest
2296
+
2297
+ def report_skip (self , out , test , example ):
2298
+ unittest .case ._addSkip (self ._test_result , self ._subTest (), '' )
2299
+
2300
+ def report_success (self , out , test , example , got ):
2301
+ self ._test_result .addSubTest (self ._test_case , self ._subTest (), None )
2302
+
2303
+ def report_unexpected_exception (self , out , test , example , exc_info ):
2304
+ tb = self ._add_traceback (exc_info [2 ], test , example )
2305
+ exc_info = (* exc_info [:2 ], tb )
2306
+ self ._test_result .addSubTest (self ._test_case , self ._subTest (), exc_info )
2307
+
2308
+ def report_failure (self , out , test , example , got ):
2309
+ msg = ('Failed example:\n ' + _indent (example .source ) +
2310
+ self ._checker .output_difference (example , got , self .optionflags ).rstrip ('\n ' ))
2311
+ exc = self ._test_case .failureException (msg )
2312
+ tb = self ._add_traceback (None , test , example )
2313
+ exc_info = (type (exc ), exc , tb )
2314
+ self ._test_result .addSubTest (self ._test_case , self ._subTest (), exc_info )
2315
+
2316
+ def _add_traceback (self , traceback , test , example ):
2317
+ if test .lineno is None or example .lineno is None :
2318
+ lineno = None
2319
+ else :
2320
+ lineno = test .lineno + example .lineno + 1
2321
+ return types .SimpleNamespace (
2322
+ tb_frame = types .SimpleNamespace (
2323
+ f_globals = test .globs ,
2324
+ f_code = types .SimpleNamespace (
2325
+ co_filename = test .filename ,
2326
+ co_name = test .name ,
2327
+ ),
2328
+ ),
2329
+ tb_next = traceback ,
2330
+ tb_lasti = - 1 ,
2331
+ tb_lineno = lineno ,
2332
+ )
2333
+
2334
+
2278
2335
class DocTestCase (unittest .TestCase ):
2279
2336
2280
2337
def __init__ (self , test , optionflags = 0 , setUp = None , tearDown = None ,
2281
2338
checker = None ):
2282
2339
2283
- unittest . TestCase . __init__ (self )
2340
+ super (). __init__ ()
2284
2341
self ._dt_optionflags = optionflags
2285
2342
self ._dt_checker = checker
2286
2343
self ._dt_test = test
@@ -2304,30 +2361,28 @@ def tearDown(self):
2304
2361
test .globs .clear ()
2305
2362
test .globs .update (self ._dt_globs )
2306
2363
2364
+ def run (self , result = None ):
2365
+ self ._test_result = result
2366
+ return super ().run (result )
2367
+
2307
2368
def runTest (self ):
2308
2369
test = self ._dt_test
2309
- old = sys .stdout
2310
- new = StringIO ()
2311
2370
optionflags = self ._dt_optionflags
2371
+ result = self ._test_result
2312
2372
2313
2373
if not (optionflags & REPORTING_FLAGS ):
2314
2374
# The option flags don't include any reporting flags,
2315
2375
# so add the default reporting flags
2316
2376
optionflags |= _unittest_reportflags
2377
+ if getattr (result , 'failfast' , False ):
2378
+ optionflags |= FAIL_FAST
2317
2379
2318
- runner = DocTestRunner (optionflags = optionflags ,
2319
- checker = self ._dt_checker , verbose = False )
2320
-
2321
- try :
2322
- runner .DIVIDER = "-" * 70
2323
- results = runner .run (test , out = new .write , clear_globs = False )
2324
- if results .skipped == results .attempted :
2325
- raise unittest .SkipTest ("all examples were skipped" )
2326
- finally :
2327
- sys .stdout = old
2328
-
2329
- if results .failed :
2330
- raise self .failureException (self .format_failure (new .getvalue ().rstrip ('\n ' )))
2380
+ runner = _DocTestCaseRunner (optionflags = optionflags ,
2381
+ checker = self ._dt_checker , verbose = False ,
2382
+ test_case = self , test_result = result )
2383
+ results = runner .run (test , clear_globs = False )
2384
+ if results .skipped == results .attempted :
2385
+ raise unittest .SkipTest ("all examples were skipped" )
2331
2386
2332
2387
def format_failure (self , err ):
2333
2388
test = self ._dt_test
@@ -2442,7 +2497,7 @@ def shortDescription(self):
2442
2497
class SkipDocTestCase (DocTestCase ):
2443
2498
def __init__ (self , module ):
2444
2499
self .module = module
2445
- DocTestCase .__init__ (self , None )
2500
+ super () .__init__ (None )
2446
2501
2447
2502
def setUp (self ):
2448
2503
self .skipTest ("DocTestSuite will not work with -O2 and above" )
0 commit comments