[WIP] doctest: lazily instantiate debugger
This commit is contained in:
parent
c4862e333a
commit
db8fdb5260
|
@ -94,6 +94,7 @@ __all__ = [
|
||||||
|
|
||||||
import __future__
|
import __future__
|
||||||
import difflib
|
import difflib
|
||||||
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
import linecache
|
import linecache
|
||||||
import os
|
import os
|
||||||
|
@ -358,24 +359,16 @@ class _OutputRedirectingPdb(pdb.Pdb):
|
||||||
"""
|
"""
|
||||||
def __init__(self, out):
|
def __init__(self, out):
|
||||||
self.__out = out
|
self.__out = out
|
||||||
self.__debugger_used = False
|
|
||||||
# do not play signal games in the pdb
|
# do not play signal games in the pdb
|
||||||
pdb.Pdb.__init__(self, stdout=out, nosigint=True)
|
pdb.Pdb.__init__(self, stdout=out, nosigint=True)
|
||||||
# still use input() to get user input
|
# still use input() to get user input
|
||||||
self.use_rawinput = 1
|
self.use_rawinput = 1
|
||||||
|
|
||||||
def set_trace(self, frame=None):
|
def set_trace(self, frame=None):
|
||||||
self.__debugger_used = True
|
|
||||||
if frame is None:
|
if frame is None:
|
||||||
frame = sys._getframe().f_back
|
frame = sys._getframe().f_back
|
||||||
pdb.Pdb.set_trace(self, frame)
|
pdb.Pdb.set_trace(self, frame)
|
||||||
|
|
||||||
def set_continue(self):
|
|
||||||
# Calling set_continue unconditionally would break unit test
|
|
||||||
# coverage reporting, as Bdb.set_continue calls sys.settrace(None).
|
|
||||||
if self.__debugger_used:
|
|
||||||
pdb.Pdb.set_continue(self)
|
|
||||||
|
|
||||||
def trace_dispatch(self, *args):
|
def trace_dispatch(self, *args):
|
||||||
# Redirect stdout to the given stream.
|
# Redirect stdout to the given stream.
|
||||||
save_stdout = sys.stdout
|
save_stdout = sys.stdout
|
||||||
|
@ -1217,6 +1210,8 @@ class DocTestRunner:
|
||||||
# Create a fake output target for capturing doctest output.
|
# Create a fake output target for capturing doctest output.
|
||||||
self._fakeout = _SpoofOut()
|
self._fakeout = _SpoofOut()
|
||||||
|
|
||||||
|
self.debugger = None
|
||||||
|
|
||||||
#/////////////////////////////////////////////////////////////////
|
#/////////////////////////////////////////////////////////////////
|
||||||
# Reporting methods
|
# Reporting methods
|
||||||
#/////////////////////////////////////////////////////////////////
|
#/////////////////////////////////////////////////////////////////
|
||||||
|
@ -1335,12 +1330,14 @@ class DocTestRunner:
|
||||||
# Don't blink! This is where the user's code gets run.
|
# Don't blink! This is where the user's code gets run.
|
||||||
exec(compile(example.source, filename, "single",
|
exec(compile(example.source, filename, "single",
|
||||||
compileflags, True), test.globs)
|
compileflags, True), test.globs)
|
||||||
|
if self.debugger:
|
||||||
self.debugger.set_continue() # ==== Example Finished ====
|
self.debugger.set_continue() # ==== Example Finished ====
|
||||||
exception = None
|
exception = None
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
exception = sys.exc_info()
|
exception = sys.exc_info()
|
||||||
|
if self.debugger:
|
||||||
self.debugger.set_continue() # ==== Example Finished ====
|
self.debugger.set_continue() # ==== Example Finished ====
|
||||||
|
|
||||||
got = self._fakeout.getvalue() # the actual output
|
got = self._fakeout.getvalue() # the actual output
|
||||||
|
@ -1422,6 +1419,12 @@ class DocTestRunner:
|
||||||
else:
|
else:
|
||||||
return self.save_linecache_getlines(filename, module_globals)
|
return self.save_linecache_getlines(filename, module_globals)
|
||||||
|
|
||||||
|
def _pdb_set_trace(self, stdout):
|
||||||
|
if not self.debugger:
|
||||||
|
self.debugger = _OutputRedirectingPdb(stdout)
|
||||||
|
self.debugger.reset()
|
||||||
|
self.debugger.set_trace(frame=sys._getframe().f_back)
|
||||||
|
|
||||||
def run(self, test, compileflags=None, out=None, clear_globs=True):
|
def run(self, test, compileflags=None, out=None, clear_globs=True):
|
||||||
"""
|
"""
|
||||||
Run the examples in `test`, and display the results using the
|
Run the examples in `test`, and display the results using the
|
||||||
|
@ -1466,9 +1469,7 @@ class DocTestRunner:
|
||||||
# allows us to write test cases for the set_trace behavior.
|
# allows us to write test cases for the set_trace behavior.
|
||||||
save_trace = sys.gettrace()
|
save_trace = sys.gettrace()
|
||||||
save_set_trace = pdb.set_trace
|
save_set_trace = pdb.set_trace
|
||||||
self.debugger = _OutputRedirectingPdb(save_stdout)
|
pdb.set_trace = functools.partial(self._pdb_set_trace, save_stdout)
|
||||||
self.debugger.reset()
|
|
||||||
pdb.set_trace = self.debugger.set_trace
|
|
||||||
|
|
||||||
# Patch linecache.getlines, so we can see the example's source
|
# Patch linecache.getlines, so we can see the example's source
|
||||||
# when we're inside the debugger.
|
# when we're inside the debugger.
|
||||||
|
|
Loading…
Reference in New Issue