From ede3a4e850e8d2d3dedbb90eca84bc80a6f6bc27 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 24 Oct 2018 23:27:14 +0200 Subject: [PATCH] pytest_{enter,leave}_pdb: pass through pdb instance --- changelog/2619.feature.rst | 3 +++ src/_pytest/debugging.py | 6 ++++-- src/_pytest/hookspec.py | 6 ++++-- testing/test_pdb.py | 14 ++++++++++++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/changelog/2619.feature.rst b/changelog/2619.feature.rst index df8137a669c..d2ce9c5ed38 100644 --- a/changelog/2619.feature.rst +++ b/changelog/2619.feature.rst @@ -1 +1,4 @@ Resume capturing output after ``continue`` with ``__import__("pdb").set_trace()``. + +This also adds a new ``pytest_leave_pdb`` hook, and passes in ``pdb`` to the +existing ``pytest_enter_pdb`` hook. diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index da35688b9a7..5542fef78fe 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -95,7 +95,6 @@ def set_trace(cls, set_break=True): tw = _pytest.config.create_terminal_writer(cls._config) tw.line() tw.sep(">", "PDB set_trace (IO-capturing turned off)") - cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config) class _PdbWrapper(cls._pdb_cls, object): _pytest_capman = capman @@ -108,7 +107,9 @@ def do_continue(self, arg): tw.line() tw.sep(">", "PDB continue (IO-capturing resumed)") self._pytest_capman.resume_global_capture() - cls._pluginmanager.hook.pytest_leave_pdb(config=cls._config) + cls._pluginmanager.hook.pytest_leave_pdb( + config=cls._config, pdb=self + ) self._continued = True return ret @@ -129,6 +130,7 @@ def setup(self, f, tb): return ret _pdb = _PdbWrapper() + cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config, pdb=_pdb) else: _pdb = cls._pdb_cls() diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py index ae289f0a3d0..6e04557208b 100644 --- a/src/_pytest/hookspec.py +++ b/src/_pytest/hookspec.py @@ -603,19 +603,21 @@ def pytest_exception_interact(node, call, report): """ -def pytest_enter_pdb(config): +def pytest_enter_pdb(config, pdb): """ called upon pdb.set_trace(), can be used by plugins to take special action just before the python debugger enters in interactive mode. :param _pytest.config.Config config: pytest config object + :param pdb.Pdb pdb: Pdb instance """ -def pytest_leave_pdb(config): +def pytest_leave_pdb(config, pdb): """ called when leaving pdb (e.g. with continue after pdb.set_trace()). Can be used by plugins to take special action just after the python debugger leaves interactive mode. :param _pytest.config.Config config: pytest config object + :param pdb.Pdb pdb: Pdb instance """ diff --git a/testing/test_pdb.py b/testing/test_pdb.py index 19f95959caa..3f0f744101e 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -550,16 +550,26 @@ def test_pdb_collection_failure_is_shown(self, testdir): def test_enter_leave_pdb_hooks_are_called(self, testdir): testdir.makeconftest( """ + mypdb = None + def pytest_configure(config): config.testing_verification = 'configured' - def pytest_enter_pdb(config): + def pytest_enter_pdb(config, pdb): assert config.testing_verification == 'configured' print('enter_pdb_hook') - def pytest_leave_pdb(config): + global mypdb + mypdb = pdb + mypdb.set_attribute = "bar" + + def pytest_leave_pdb(config, pdb): assert config.testing_verification == 'configured' print('leave_pdb_hook') + + global mypdb + assert mypdb is pdb + assert mypdb.set_attribute == "bar" """ ) p1 = testdir.makepyfile(