pdb: handle quitting in post_mortem
`help quit` in pdb says: > Quit from the debugger. The program being executed is aborted. But pytest would continue with the next tests, often making it necessary to kill the pytest process when using `--pdb` and trying to cancel the tests using `KeyboardInterrupt` / `Ctrl-C`.
This commit is contained in:
parent
27d2683a02
commit
86c7dcff68
|
@ -1,10 +1,12 @@
|
||||||
""" interactive debugging with PDB, the Python Debugger. """
|
""" interactive debugging with PDB, the Python Debugger. """
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
import os
|
||||||
import pdb
|
import pdb
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
from doctest import UnexpectedException
|
from doctest import UnexpectedException
|
||||||
|
|
||||||
|
from _pytest import outcomes
|
||||||
from _pytest.config import hookimpl
|
from _pytest.config import hookimpl
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -164,8 +166,9 @@ def _enter_pdb(node, excinfo, rep):
|
||||||
rep.toterminal(tw)
|
rep.toterminal(tw)
|
||||||
tw.sep(">", "entering PDB")
|
tw.sep(">", "entering PDB")
|
||||||
tb = _postmortem_traceback(excinfo)
|
tb = _postmortem_traceback(excinfo)
|
||||||
post_mortem(tb)
|
|
||||||
rep._pdbshown = True
|
rep._pdbshown = True
|
||||||
|
if post_mortem(tb):
|
||||||
|
outcomes.exit("Quitting debugger")
|
||||||
return rep
|
return rep
|
||||||
|
|
||||||
|
|
||||||
|
@ -196,3 +199,4 @@ def post_mortem(t):
|
||||||
p = Pdb()
|
p = Pdb()
|
||||||
p.reset()
|
p.reset()
|
||||||
p.interaction(None, t)
|
p.interaction(None, t)
|
||||||
|
return p.quitting
|
||||||
|
|
|
@ -25,6 +25,8 @@ def custom_pdb_calls():
|
||||||
|
|
||||||
# install dummy debugger class and track which methods were called on it
|
# install dummy debugger class and track which methods were called on it
|
||||||
class _CustomPdb(object):
|
class _CustomPdb(object):
|
||||||
|
quitting = False
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
called.append("init")
|
called.append("init")
|
||||||
|
|
||||||
|
@ -142,6 +144,9 @@ class TestPDB(object):
|
||||||
def test_1():
|
def test_1():
|
||||||
i = 0
|
i = 0
|
||||||
assert i == 1
|
assert i == 1
|
||||||
|
|
||||||
|
def test_not_called_due_to_quit():
|
||||||
|
pass
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
child = testdir.spawn_pytest("--pdb %s" % p1)
|
child = testdir.spawn_pytest("--pdb %s" % p1)
|
||||||
|
@ -150,8 +155,9 @@ class TestPDB(object):
|
||||||
child.expect("Pdb")
|
child.expect("Pdb")
|
||||||
child.sendeof()
|
child.sendeof()
|
||||||
rest = child.read().decode("utf8")
|
rest = child.read().decode("utf8")
|
||||||
assert "1 failed" in rest
|
assert "= 1 failed in" in rest
|
||||||
assert "def test_1" not in rest
|
assert "def test_1" not in rest
|
||||||
|
assert "Exit: Quitting debugger" in rest
|
||||||
self.flush(child)
|
self.flush(child)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -321,7 +327,7 @@ class TestPDB(object):
|
||||||
child = testdir.spawn_pytest("--pdb %s" % p1)
|
child = testdir.spawn_pytest("--pdb %s" % p1)
|
||||||
# child.expect(".*import pytest.*")
|
# child.expect(".*import pytest.*")
|
||||||
child.expect("Pdb")
|
child.expect("Pdb")
|
||||||
child.sendeof()
|
child.sendline("c")
|
||||||
child.expect("1 error")
|
child.expect("1 error")
|
||||||
self.flush(child)
|
self.flush(child)
|
||||||
|
|
||||||
|
@ -376,6 +382,7 @@ class TestPDB(object):
|
||||||
rest = child.read().decode("utf8")
|
rest = child.read().decode("utf8")
|
||||||
assert "1 failed" in rest
|
assert "1 failed" in rest
|
||||||
assert "reading from stdin while output" not in rest
|
assert "reading from stdin while output" not in rest
|
||||||
|
assert "BdbQuit" in rest
|
||||||
self.flush(child)
|
self.flush(child)
|
||||||
|
|
||||||
def test_pdb_and_capsys(self, testdir):
|
def test_pdb_and_capsys(self, testdir):
|
||||||
|
@ -518,7 +525,9 @@ class TestPDB(object):
|
||||||
def test_pdb_collection_failure_is_shown(self, testdir):
|
def test_pdb_collection_failure_is_shown(self, testdir):
|
||||||
p1 = testdir.makepyfile("xxx")
|
p1 = testdir.makepyfile("xxx")
|
||||||
result = testdir.runpytest_subprocess("--pdb", p1)
|
result = testdir.runpytest_subprocess("--pdb", p1)
|
||||||
result.stdout.fnmatch_lines(["*NameError*xxx*", "*1 error*"])
|
result.stdout.fnmatch_lines(
|
||||||
|
["E NameError: *xxx*", "*! *Exit: Quitting debugger !*"] # due to EOF
|
||||||
|
)
|
||||||
|
|
||||||
def test_enter_pdb_hook_is_called(self, testdir):
|
def test_enter_pdb_hook_is_called(self, testdir):
|
||||||
testdir.makeconftest(
|
testdir.makeconftest(
|
||||||
|
|
Loading…
Reference in New Issue