Merge pull request #4287 from blueyed/pdb-unconfigure-twice

debugging: make pytest_configure re-entrant
This commit is contained in:
Daniel Hahler 2018-11-03 21:09:13 +01:00 committed by GitHub
commit f2b9bbdd4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 7 deletions

View File

@ -0,0 +1 @@
Fix nested usage of debugging plugin (pdb), e.g. with pytester's ``testdir.runpytest``.

View File

@ -47,17 +47,24 @@ def pytest_configure(config):
if config.getvalue("usepdb"):
config.pluginmanager.register(PdbInvoke(), "pdbinvoke")
old = (pdb.set_trace, pytestPDB._pluginmanager)
def fin():
pdb.set_trace, pytestPDB._pluginmanager = old
pytestPDB._config = None
pytestPDB._pdb_cls = pdb.Pdb
pytestPDB._saved.append(
(pdb.set_trace, pytestPDB._pluginmanager, pytestPDB._config, pytestPDB._pdb_cls)
)
pdb.set_trace = pytestPDB.set_trace
pytestPDB._pluginmanager = config.pluginmanager
pytestPDB._config = config
pytestPDB._pdb_cls = pdb_cls
# NOTE: not using pytest_unconfigure, since it might get called although
# pytest_configure was not (if another plugin raises UsageError).
def fin():
(
pdb.set_trace,
pytestPDB._pluginmanager,
pytestPDB._config,
pytestPDB._pdb_cls,
) = pytestPDB._saved.pop()
config._cleanup.append(fin)
@ -67,6 +74,7 @@ class pytestPDB(object):
_pluginmanager = None
_config = None
_pdb_cls = pdb.Pdb
_saved = []
@classmethod
def set_trace(cls, set_break=True):

View File

@ -784,3 +784,30 @@ class TestTraceOption:
assert "1 passed" in rest
assert "reading from stdin while output" not in rest
TestPDB.flush(child)
def test_trace_after_runpytest(testdir):
"""Test that debugging's pytest_configure is re-entrant."""
p1 = testdir.makepyfile(
"""
from _pytest.debugging import pytestPDB
def test_outer(testdir):
from _pytest.debugging import pytestPDB
assert len(pytestPDB._saved) == 1
testdir.runpytest("-k test_inner")
__import__('pdb').set_trace()
def test_inner(testdir):
assert len(pytestPDB._saved) == 2
"""
)
child = testdir.spawn_pytest("-p pytester %s -k test_outer" % p1)
child.expect(r"\(Pdb")
child.sendline("c")
rest = child.read().decode("utf8")
TestPDB.flush(child)
assert child.exitstatus == 0, rest