]> granicus.if.org Git - python/commitdiff
This started as a spelling and whitespace cleanup. The comment for
authorTim Peters <tim.peters@gmail.com>
Mon, 9 Aug 2004 15:43:47 +0000 (15:43 +0000)
committerTim Peters <tim.peters@gmail.com>
Mon, 9 Aug 2004 15:43:47 +0000 (15:43 +0000)
the set_trace fiddling didn't make sense to me, and I ended up reworking
that part of the code.  We really do want to save and restore
pdb.set_trace, so that each dynamically nested level of doctest gets
sys.stdout fiddled to what's appropriate for *it*.  The only "trick"
really needed is that these layers of set_trace wrappers each call the
original pdb.set_trace (instead of the current pdb.set_trace).

Lib/doctest.py
Lib/test/test_doctest.py

index 5dd0bae40be13ce81706420776cd4e6a44120a5a..724a3ad616cdf7d80b3edeb33653611e8ef9fd03 100644 (file)
@@ -1254,27 +1254,30 @@ class DocTestRunner:
         if compileflags is None:
             compileflags = _extract_future_flags(test.globs)
 
+        save_stdout = sys.stdout
         if out is None:
-            out = sys.stdout.write
-        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.
+            out = save_stdout.write
+        sys.stdout = self._fakeout
+
+        # Patch pdb.set_trace to restore sys.stdout, so that interactive
+        # debugging output is visible (not still redirected to self._fakeout).
+        # Note that we run "the real" pdb.set_trace (captured at doctest
+        # import time) in our replacement.  Because the current run() may
+        # run another doctest (and so on), the current pdb.set_trace may be
+        # our set_trace function, which changes sys.stdout.  If we called
+        # a chain of those, we wouldn't be left with the save_stdout
+        # *this* run() invocation wants.
         def set_trace():
-            sys.stdout = saveout
+            sys.stdout = save_stdout
             real_pdb_set_trace()
 
+        save_set_trace = pdb.set_trace
+        pdb.set_trace = set_trace
         try:
-            sys.stdout = self._fakeout
-            pdb.set_trace = set_trace
             return self.__run(test, compileflags, out)
         finally:
-            sys.stdout = saveout
-            pdb.set_trace = real_pdb_set_trace
+            sys.stdout = save_stdout
+            pdb.set_trace = save_set_trace
             if clear_globs:
                 test.globs.clear()
 
index 130cf048a1dc59f4175cc7a6823865d9879f985d..28b72cb5bcfb51dd0b451b5479acd1e5427b74d0 100644 (file)
@@ -987,11 +987,11 @@ 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
+    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
+    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 = '''
@@ -1041,8 +1041,7 @@ def test_pdb_set_trace():
       ... >>> 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