Merge pull request #4908 from blueyed/pdb-pm-enter-hook
pdb: trigger pytest_enter_pdb hook with post-mortem
This commit is contained in:
commit
fa8a658458
|
@ -0,0 +1 @@
|
||||||
|
The ``pytest_enter_pdb`` hook gets called with post-mortem (``--pdb``).
|
|
@ -359,8 +359,7 @@ class CaptureFixture(object):
|
||||||
self._captured_err = self.captureclass.EMPTY_BUFFER
|
self._captured_err = self.captureclass.EMPTY_BUFFER
|
||||||
|
|
||||||
def _start(self):
|
def _start(self):
|
||||||
# Start if not started yet
|
if self._capture is None:
|
||||||
if getattr(self, "_capture", None) is None:
|
|
||||||
self._capture = MultiCapture(
|
self._capture = MultiCapture(
|
||||||
out=True, err=True, in_=False, Capture=self.captureclass
|
out=True, err=True, in_=False, Capture=self.captureclass
|
||||||
)
|
)
|
||||||
|
@ -390,11 +389,13 @@ class CaptureFixture(object):
|
||||||
|
|
||||||
def _suspend(self):
|
def _suspend(self):
|
||||||
"""Suspends this fixture's own capturing temporarily."""
|
"""Suspends this fixture's own capturing temporarily."""
|
||||||
self._capture.suspend_capturing()
|
if self._capture is not None:
|
||||||
|
self._capture.suspend_capturing()
|
||||||
|
|
||||||
def _resume(self):
|
def _resume(self):
|
||||||
"""Resumes this fixture's own capturing temporarily."""
|
"""Resumes this fixture's own capturing temporarily."""
|
||||||
self._capture.resume_capturing()
|
if self._capture is not None:
|
||||||
|
self._capture.resume_capturing()
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def disabled(self):
|
def disabled(self):
|
||||||
|
|
|
@ -213,6 +213,17 @@ class pytestPDB(object):
|
||||||
self._pytest_capman.suspend_global_capture(in_=True)
|
self._pytest_capman.suspend_global_capture(in_=True)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def get_stack(self, f, t):
|
||||||
|
stack, i = super(PytestPdbWrapper, self).get_stack(f, t)
|
||||||
|
if f is None:
|
||||||
|
# Find last non-hidden frame.
|
||||||
|
i = max(0, len(stack) - 1)
|
||||||
|
while i and stack[i][0].f_locals.get(
|
||||||
|
"__tracebackhide__", False
|
||||||
|
):
|
||||||
|
i -= 1
|
||||||
|
return stack, i
|
||||||
|
|
||||||
_pdb = PytestPdbWrapper(**kwargs)
|
_pdb = PytestPdbWrapper(**kwargs)
|
||||||
cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config, pdb=_pdb)
|
cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config, pdb=_pdb)
|
||||||
else:
|
else:
|
||||||
|
@ -299,22 +310,8 @@ def _postmortem_traceback(excinfo):
|
||||||
return excinfo._excinfo[2]
|
return excinfo._excinfo[2]
|
||||||
|
|
||||||
|
|
||||||
def _find_last_non_hidden_frame(stack):
|
|
||||||
i = max(0, len(stack) - 1)
|
|
||||||
while i and stack[i][0].f_locals.get("__tracebackhide__", False):
|
|
||||||
i -= 1
|
|
||||||
return i
|
|
||||||
|
|
||||||
|
|
||||||
def post_mortem(t):
|
def post_mortem(t):
|
||||||
class Pdb(pytestPDB._pdb_cls, object):
|
p = pytestPDB._init_pdb()
|
||||||
def get_stack(self, f, t):
|
|
||||||
stack, i = super(Pdb, self).get_stack(f, t)
|
|
||||||
if f is None:
|
|
||||||
i = _find_last_non_hidden_frame(stack)
|
|
||||||
return stack, i
|
|
||||||
|
|
||||||
p = Pdb()
|
|
||||||
p.reset()
|
p.reset()
|
||||||
p.interaction(None, t)
|
p.interaction(None, t)
|
||||||
if p.quitting:
|
if p.quitting:
|
||||||
|
|
|
@ -745,7 +745,8 @@ class TestPDB(object):
|
||||||
["E NameError: *xxx*", "*! *Exit: Quitting debugger !*"] # due to EOF
|
["E NameError: *xxx*", "*! *Exit: Quitting debugger !*"] # due to EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_enter_leave_pdb_hooks_are_called(self, testdir):
|
@pytest.mark.parametrize("post_mortem", (False, True))
|
||||||
|
def test_enter_leave_pdb_hooks_are_called(self, post_mortem, testdir):
|
||||||
testdir.makeconftest(
|
testdir.makeconftest(
|
||||||
"""
|
"""
|
||||||
mypdb = None
|
mypdb = None
|
||||||
|
@ -774,16 +775,25 @@ class TestPDB(object):
|
||||||
"""
|
"""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
def test_foo():
|
def test_set_trace():
|
||||||
pytest.set_trace()
|
pytest.set_trace()
|
||||||
assert 0
|
assert 0
|
||||||
|
|
||||||
|
def test_post_mortem():
|
||||||
|
assert 0
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
child = testdir.spawn_pytest(str(p1))
|
if post_mortem:
|
||||||
|
child = testdir.spawn_pytest(str(p1) + " --pdb -s -k test_post_mortem")
|
||||||
|
else:
|
||||||
|
child = testdir.spawn_pytest(str(p1) + " -k test_set_trace")
|
||||||
child.expect("enter_pdb_hook")
|
child.expect("enter_pdb_hook")
|
||||||
child.sendline("c")
|
child.sendline("c")
|
||||||
child.expect(r"PDB continue \(IO-capturing resumed\)")
|
if post_mortem:
|
||||||
child.expect("Captured stdout call")
|
child.expect(r"PDB continue")
|
||||||
|
else:
|
||||||
|
child.expect(r"PDB continue \(IO-capturing resumed\)")
|
||||||
|
child.expect("Captured stdout call")
|
||||||
rest = child.read().decode("utf8")
|
rest = child.read().decode("utf8")
|
||||||
assert "leave_pdb_hook" in rest
|
assert "leave_pdb_hook" in rest
|
||||||
assert "1 failed" in rest
|
assert "1 failed" in rest
|
||||||
|
|
Loading…
Reference in New Issue