Skip to content

Commit eb0c733

Browse files
committed
pdb: fix capturing with recursive debugging
1 parent f06fe43 commit eb0c733

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

src/_pytest/debugging.py

+18-9
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class pytestPDB(object):
7575
_config = None
7676
_pdb_cls = pdb.Pdb
7777
_saved = []
78+
_recursive = 0
7879

7980
@classmethod
8081
def set_trace(cls, set_break=True):
@@ -88,25 +89,33 @@ def set_trace(cls, set_break=True):
8889
capman.suspend_global_capture(in_=True)
8990
tw = _pytest.config.create_terminal_writer(cls._config)
9091
tw.line()
91-
if capman and capman.is_globally_capturing():
92-
tw.sep(">", "PDB set_trace (IO-capturing turned off)")
93-
else:
94-
tw.sep(">", "PDB set_trace")
92+
if cls._recursive == 0:
93+
if capman and capman.is_globally_capturing():
94+
tw.sep(">", "PDB set_trace (IO-capturing turned off)")
95+
else:
96+
tw.sep(">", "PDB set_trace")
9597

9698
class _PdbWrapper(cls._pdb_cls, object):
9799
_pytest_capman = capman
98100
_continued = False
99101

102+
def do_debug(self, arg):
103+
cls._recursive += 1
104+
ret = super(_PdbWrapper, self).do_debug(arg)
105+
cls._recursive -= 1
106+
return ret
107+
100108
def do_continue(self, arg):
101109
ret = super(_PdbWrapper, self).do_continue(arg)
102110
if self._pytest_capman:
103111
tw = _pytest.config.create_terminal_writer(cls._config)
104112
tw.line()
105-
if self._pytest_capman.is_globally_capturing():
106-
tw.sep(">", "PDB continue (IO-capturing resumed)")
107-
else:
108-
tw.sep(">", "PDB continue")
109-
self._pytest_capman.resume_global_capture()
113+
if cls._recursive == 0:
114+
if self._pytest_capman.is_globally_capturing():
115+
tw.sep(">", "PDB continue (IO-capturing resumed)")
116+
else:
117+
tw.sep(">", "PDB continue")
118+
self._pytest_capman.resume_global_capture()
110119
cls._pluginmanager.hook.pytest_leave_pdb(
111120
config=cls._config, pdb=self
112121
)

testing/test_pdb.py

+37
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,43 @@ def test_1():
518518
assert "1 failed" in rest
519519
self.flush(child)
520520

521+
def test_pdb_interaction_continue_recursive(self, testdir):
522+
p1 = testdir.makepyfile(
523+
"""
524+
import pytest
525+
526+
def foo():
527+
print("print_from_foo")
528+
529+
def test_1():
530+
i = 0
531+
print("hello17")
532+
pytest.set_trace()
533+
x = 3
534+
print("hello18")
535+
assert 0
536+
"""
537+
)
538+
child = testdir.spawn_pytest(str(p1))
539+
child.expect(r"PDB set_trace \(IO-capturing turned off\)")
540+
child.expect("test_1")
541+
child.expect("x = 3")
542+
child.expect("Pdb")
543+
child.sendline("debug foo()")
544+
child.expect("ENTERING RECURSIVE DEBUGGER")
545+
child.expect(r"\(\(Pdb")
546+
child.sendline("c")
547+
child.expect("LEAVING RECURSIVE DEBUGGER")
548+
assert b"PDB continue" not in child.before
549+
assert b"print_from_foo" in child.before
550+
child.sendline("c")
551+
child.expect(r"PDB continue \(IO-capturing resumed\)")
552+
rest = child.read().decode("utf8")
553+
assert "hello17" in rest # out is captured
554+
assert "hello18" in rest # out is captured
555+
assert "1 failed" in rest
556+
self.flush(child)
557+
521558
def test_pdb_without_capture(self, testdir):
522559
p1 = testdir.makepyfile(
523560
"""

0 commit comments

Comments
 (0)