Skip to content

Commit db8fdb5

Browse files
committed
[WIP] doctest: lazily instantiate debugger
1 parent c4862e3 commit db8fdb5

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

Lib/doctest.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ def _test():
9494

9595
import __future__
9696
import difflib
97+
import functools
9798
import inspect
9899
import linecache
99100
import os
@@ -358,24 +359,16 @@ class _OutputRedirectingPdb(pdb.Pdb):
358359
"""
359360
def __init__(self, out):
360361
self.__out = out
361-
self.__debugger_used = False
362362
# do not play signal games in the pdb
363363
pdb.Pdb.__init__(self, stdout=out, nosigint=True)
364364
# still use input() to get user input
365365
self.use_rawinput = 1
366366

367367
def set_trace(self, frame=None):
368-
self.__debugger_used = True
369368
if frame is None:
370369
frame = sys._getframe().f_back
371370
pdb.Pdb.set_trace(self, frame)
372371

373-
def set_continue(self):
374-
# Calling set_continue unconditionally would break unit test
375-
# coverage reporting, as Bdb.set_continue calls sys.settrace(None).
376-
if self.__debugger_used:
377-
pdb.Pdb.set_continue(self)
378-
379372
def trace_dispatch(self, *args):
380373
# Redirect stdout to the given stream.
381374
save_stdout = sys.stdout
@@ -1217,6 +1210,8 @@ def __init__(self, checker=None, verbose=None, optionflags=0):
12171210
# Create a fake output target for capturing doctest output.
12181211
self._fakeout = _SpoofOut()
12191212

1213+
self.debugger = None
1214+
12201215
#/////////////////////////////////////////////////////////////////
12211216
# Reporting methods
12221217
#/////////////////////////////////////////////////////////////////
@@ -1335,13 +1330,15 @@ def __run(self, test, compileflags, out):
13351330
# Don't blink! This is where the user's code gets run.
13361331
exec(compile(example.source, filename, "single",
13371332
compileflags, True), test.globs)
1338-
self.debugger.set_continue() # ==== Example Finished ====
1333+
if self.debugger:
1334+
self.debugger.set_continue() # ==== Example Finished ====
13391335
exception = None
13401336
except KeyboardInterrupt:
13411337
raise
13421338
except:
13431339
exception = sys.exc_info()
1344-
self.debugger.set_continue() # ==== Example Finished ====
1340+
if self.debugger:
1341+
self.debugger.set_continue() # ==== Example Finished ====
13451342

13461343
got = self._fakeout.getvalue() # the actual output
13471344
self._fakeout.truncate(0)
@@ -1422,6 +1419,12 @@ def __patched_linecache_getlines(self, filename, module_globals=None):
14221419
else:
14231420
return self.save_linecache_getlines(filename, module_globals)
14241421

1422+
def _pdb_set_trace(self, stdout):
1423+
if not self.debugger:
1424+
self.debugger = _OutputRedirectingPdb(stdout)
1425+
self.debugger.reset()
1426+
self.debugger.set_trace(frame=sys._getframe().f_back)
1427+
14251428
def run(self, test, compileflags=None, out=None, clear_globs=True):
14261429
"""
14271430
Run the examples in `test`, and display the results using the
@@ -1466,9 +1469,7 @@ def out(s):
14661469
# allows us to write test cases for the set_trace behavior.
14671470
save_trace = sys.gettrace()
14681471
save_set_trace = pdb.set_trace
1469-
self.debugger = _OutputRedirectingPdb(save_stdout)
1470-
self.debugger.reset()
1471-
pdb.set_trace = self.debugger.set_trace
1472+
pdb.set_trace = functools.partial(self._pdb_set_trace, save_stdout)
14721473

14731474
# Patch linecache.getlines, so we can see the example's source
14741475
# when we're inside the debugger.

0 commit comments

Comments
 (0)