Commit 356fd19c authored by Jim Fulton's avatar Jim Fulton

Added support for pdb.set_trace.

parent 9dc19c25
...@@ -187,10 +187,12 @@ __all__ = [ ...@@ -187,10 +187,12 @@ __all__ = [
import __future__ import __future__
import sys, traceback, inspect, linecache, os, re, types import sys, traceback, inspect, linecache, os, re, types
import unittest, difflib, tempfile import unittest, difflib, pdb, tempfile
import warnings import warnings
from StringIO import StringIO from StringIO import StringIO
real_pdb_set_trace = pdb.set_trace
# Option constants. # Option constants.
DONT_ACCEPT_TRUE_FOR_1 = 1 << 0 DONT_ACCEPT_TRUE_FOR_1 = 1 << 0
DONT_ACCEPT_BLANKLINE = 1 << 1 DONT_ACCEPT_BLANKLINE = 1 << 1
...@@ -1251,15 +1253,28 @@ class DocTestRunner: ...@@ -1251,15 +1253,28 @@ class DocTestRunner:
""" """
if compileflags is None: if compileflags is None:
compileflags = _extract_future_flags(test.globs) compileflags = _extract_future_flags(test.globs)
if out is None: if out is None:
out = sys.stdout.write out = sys.stdout.write
saveout = sys.stdout saveout = sys.stdout
# Note that don't save away the previous pdb.set_trace. Rather,
# we safe pdb.set_trace on import (see import section above).
# We then call and restore that original cersion. We do it this
# way to make this feature testable. If we kept and called the
# previous version, we'd end up restoring the original stdout,
# which is not what we want.
def set_trace():
sys.stdout = saveout
real_pdb_set_trace()
try: try:
sys.stdout = self._fakeout sys.stdout = self._fakeout
pdb.set_trace = set_trace
return self.__run(test, compileflags, out) return self.__run(test, compileflags, out)
finally: finally:
sys.stdout = saveout sys.stdout = saveout
pdb.set_trace = real_pdb_set_trace
if clear_globs: if clear_globs:
test.globs.clear() test.globs.clear()
......
...@@ -984,6 +984,93 @@ Run the debugger on the docstring, and then restore sys.stdin. ...@@ -984,6 +984,93 @@ Run the debugger on the docstring, and then restore sys.stdin.
""" """
def test_pdb_set_trace():
r"""Using pdb.set_trace from a doctest
You can use pdb.set_trace from a doctest. To do so, you must
retrieve the set_trace function from the pdb module at the time
you use it. The doctest module changes sys,stdout so that it can
capture program output. It also temporarily replaces pdb.set_trace
with a version that restores stdout. This is necessary for you to
see debugger output.
>>> doc = '''
... >>> x = 42
... >>> import pdb; pdb.set_trace()
... '''
>>> test = doctest.DocTest(doc, {}, "foo", "foo.py", 0)
>>> runner = doctest.DocTestRunner(verbose=False)
To demonstrate this, we'll create a fake standard input that
captures our debugger input:
>>> import tempfile
>>> fake_stdin = tempfile.TemporaryFile(mode='w+')
>>> fake_stdin.write('\n'.join([
... 'up', # up out of pdb.set_trace
... 'up', # up again to get out of our wrapper
... 'print x', # print data defined by the example
... 'continue', # stop debugging
... '']))
>>> fake_stdin.seek(0)
>>> real_stdin = sys.stdin
>>> sys.stdin = fake_stdin
>>> doctest: +ELLIPSIS
>>> runner.run(test)
--Return--
> ...set_trace()->None
-> Pdb().set_trace()
(Pdb) > ...set_trace()
-> real_pdb_set_trace()
(Pdb) > <string>(1)?()
(Pdb) 42
(Pdb) (0, 2)
>>> sys.stdin = real_stdin
>>> fake_stdin.close()
You can also put pdb.set_trace in a function called from a test:
>>> def calls_set_trace():
... y=2
... import pdb; pdb.set_trace()
>>> doc = '''
... >>> x=1
... >>> calls_set_trace()
... '''
>>> test = doctest.DocTest(doc, globals(), "foo", "foo.py", 0)
>>> import tempfile
>>> fake_stdin = tempfile.TemporaryFile(mode='w+')
>>> fake_stdin.write('\n'.join([
... 'up', # up out of pdb.set_trace
... 'up', # up again to get out of our wrapper
... 'print y', # print data defined in the function
... 'up', # out of function
... 'print x', # print data defined by the example
... 'continue', # stop debugging
... '']))
>>> fake_stdin.seek(0)
>>> real_stdin = sys.stdin
>>> sys.stdin = fake_stdin
>>> runner.run(test)
--Return--
> ...set_trace()->None
-> Pdb().set_trace()
(Pdb) ...set_trace()
-> real_pdb_set_trace()
(Pdb) > <string>(3)calls_set_trace()
(Pdb) 2
(Pdb) > <string>(1)?()
(Pdb) 1
(Pdb) (0, 2)
>>> doctest: -ELLIPSIS
"""
def test_DocTestSuite(): def test_DocTestSuite():
"""DocTestSuite creates a unittest test suite from a doctest. """DocTestSuite creates a unittest test suite from a doctest.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment