Skip to content

Commit 26a9d23

Browse files
committed
Handle quitting from pdb with --trace
This raises ``outcomes.exit`` via ``set_quit``, and ``post_mortem`` directly already. It merges ``test_pdb_interaction``, ``test_pdb_print_captured_stdout``, and ``test_pdb_print_captured_stderr`` into ``test_pdb_print_captured_stdout_and_stderr`` (clarity and performance, especially since pexpect tests are slow).
1 parent 283d824 commit 26a9d23

File tree

3 files changed

+46
-55
lines changed

3 files changed

+46
-55
lines changed

changelog/4280.bugfix.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Handle quitting from pdb with ``--trace`` and parametrized tests by exiting pytest.
2+
3+
Using ``[q]uit`` when in pdb will now exit pytest, instead of continue to run
4+
the remaining tests.

src/_pytest/debugging.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ def do_continue(self, arg):
118118

119119
do_c = do_cont = do_continue
120120

121+
def set_quit(self):
122+
super(_PdbWrapper, self).set_quit()
123+
outcomes.exit("Quitting debugger")
124+
121125
def setup(self, f, tb):
122126
"""Suspend on setup().
123127
@@ -210,8 +214,7 @@ def _enter_pdb(node, excinfo, rep):
210214
tw.sep(">", "entering PDB")
211215
tb = _postmortem_traceback(excinfo)
212216
rep._pdbshown = True
213-
if post_mortem(tb):
214-
outcomes.exit("Quitting debugger")
217+
post_mortem(tb)
215218
return rep
216219

217220

@@ -242,4 +245,5 @@ def get_stack(self, f, t):
242245
p = Pdb()
243246
p.reset()
244247
p.interaction(None, t)
245-
return p.quitting
248+
if p.quitting:
249+
outcomes.exit("Quitting debugger")

testing/test_pdb.py

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -147,29 +147,6 @@ def test_func():
147147
assert rep.failed
148148
assert len(pdblist) == 1
149149

150-
def test_pdb_interaction(self, testdir):
151-
p1 = testdir.makepyfile(
152-
"""
153-
def test_1():
154-
i = 0
155-
assert i == 1
156-
157-
def test_not_called_due_to_quit():
158-
pass
159-
"""
160-
)
161-
child = testdir.spawn_pytest("--pdb %s" % p1)
162-
child.expect(".*def test_1")
163-
child.expect(".*i = 0")
164-
child.expect("Pdb")
165-
child.sendeof()
166-
rest = child.read().decode("utf8")
167-
assert "= 1 failed in" in rest
168-
assert "def test_1" not in rest
169-
assert "Exit: Quitting debugger" in rest
170-
assert "PDB continue (IO-capturing resumed)" not in rest
171-
self.flush(child)
172-
173150
@staticmethod
174151
def flush(child):
175152
if platform.system() == "Darwin":
@@ -214,40 +191,32 @@ def test_one(self):
214191
child.sendeof()
215192
self.flush(child)
216193

217-
def test_pdb_print_captured_stdout(self, testdir):
194+
def test_pdb_print_captured_stdout_and_stderr(self, testdir):
218195
p1 = testdir.makepyfile(
219196
"""
220197
def test_1():
198+
import sys
199+
sys.stderr.write("get\\x20rekt")
221200
print("get\\x20rekt")
222201
assert False
202+
203+
def test_not_called_due_to_quit():
204+
pass
223205
"""
224206
)
225207
child = testdir.spawn_pytest("--pdb %s" % p1)
226208
child.expect("captured stdout")
227209
child.expect("get rekt")
228-
child.expect("Pdb")
229-
child.sendeof()
230-
rest = child.read().decode("utf8")
231-
assert "1 failed" in rest
232-
assert "get rekt" not in rest
233-
self.flush(child)
234-
235-
def test_pdb_print_captured_stderr(self, testdir):
236-
p1 = testdir.makepyfile(
237-
"""
238-
def test_1():
239-
import sys
240-
sys.stderr.write("get\\x20rekt")
241-
assert False
242-
"""
243-
)
244-
child = testdir.spawn_pytest("--pdb %s" % p1)
245210
child.expect("captured stderr")
246211
child.expect("get rekt")
212+
child.expect("traceback")
213+
child.expect("def test_1")
247214
child.expect("Pdb")
248215
child.sendeof()
249216
rest = child.read().decode("utf8")
250-
assert "1 failed" in rest
217+
assert "Exit: Quitting debugger" in rest
218+
assert "= 1 failed in" in rest
219+
assert "def test_1" not in rest
251220
assert "get rekt" not in rest
252221
self.flush(child)
253222

@@ -375,15 +344,17 @@ def test_1():
375344
i = 0
376345
print("hello17")
377346
pytest.set_trace()
378-
x = 3
347+
i == 1
348+
assert 0
379349
"""
380350
)
381351
child = testdir.spawn_pytest(str(p1))
382-
child.expect("test_1")
383-
child.expect("x = 3")
352+
child.expect(r"test_1\(\)")
353+
child.expect("i == 1")
384354
child.expect("Pdb")
385-
child.sendeof()
355+
child.sendline("c")
386356
rest = child.read().decode("utf-8")
357+
assert "AssertionError" in rest
387358
assert "1 failed" in rest
388359
assert "def test_1" in rest
389360
assert "hello17" in rest # out is captured
@@ -424,9 +395,9 @@ def test_1():
424395
child.expect("Pdb")
425396
child.sendeof()
426397
rest = child.read().decode("utf8")
427-
assert "1 failed" in rest
398+
assert "no tests ran" in rest
428399
assert "reading from stdin while output" not in rest
429-
assert "BdbQuit" in rest
400+
assert "BdbQuit" not in rest
430401
self.flush(child)
431402

432403
def test_pdb_and_capsys(self, testdir):
@@ -518,6 +489,7 @@ def test_1():
518489
print("hello18")
519490
pytest.set_trace()
520491
x = 4
492+
assert 0
521493
"""
522494
)
523495
child = testdir.spawn_pytest(str(p1))
@@ -530,11 +502,11 @@ def test_1():
530502
child.expect(r"PDB set_trace \(IO-capturing turned off\)")
531503
child.expect("x = 4")
532504
child.expect("Pdb")
533-
child.sendeof()
505+
child.sendline("c")
534506
child.expect("_ test_1 _")
535507
child.expect("def test_1")
536-
child.expect("Captured stdout call")
537508
rest = child.read().decode("utf8")
509+
assert "Captured stdout call" in rest
538510
assert "hello17" in rest # out is captured
539511
assert "hello18" in rest # out is captured
540512
assert "1 failed" in rest
@@ -826,15 +798,26 @@ def test_trace_sets_breakpoint(self, testdir):
826798
"""
827799
def test_1():
828800
assert True
801+
802+
def test_2():
803+
pass
804+
805+
def test_3():
806+
pass
829807
"""
830808
)
831809
child = testdir.spawn_pytest("--trace " + str(p1))
832810
child.expect("test_1")
833811
child.expect("Pdb")
834-
child.sendeof()
812+
child.sendline("c")
813+
child.expect("test_2")
814+
child.expect("Pdb")
815+
child.sendline("q")
816+
child.expect_exact("Exit: Quitting debugger")
835817
rest = child.read().decode("utf8")
836-
assert "1 passed" in rest
818+
assert "1 passed in" in rest
837819
assert "reading from stdin while output" not in rest
820+
assert "Exit: Quitting debugger" in child.before.decode("utf8")
838821
TestPDB.flush(child)
839822

840823

0 commit comments

Comments
 (0)