Allow passing a custom Pdb subclass via --pdbcls.
This obviates the need for plugins such as `pytest-ipdb`; instead one can simply call `py.test --pdb=IPython.core.debugger:Pdb`
This commit is contained in:
parent
7a2058e3db
commit
6383b53ad9
1
AUTHORS
1
AUTHORS
|
@ -10,6 +10,7 @@ Anatoly Bubenkoff
|
||||||
Andreas Zeidler
|
Andreas Zeidler
|
||||||
Andy Freeland
|
Andy Freeland
|
||||||
Anthon van der Neut
|
Anthon van der Neut
|
||||||
|
Antony Lee
|
||||||
Armin Rigo
|
Armin Rigo
|
||||||
Aron Curzon
|
Aron Curzon
|
||||||
Aviv Palivoda
|
Aviv Palivoda
|
||||||
|
|
|
@ -185,7 +185,8 @@
|
||||||
Before, you only got exceptions later from ``argparse`` library,
|
Before, you only got exceptions later from ``argparse`` library,
|
||||||
giving no clue about the actual reason for double-added options.
|
giving no clue about the actual reason for double-added options.
|
||||||
|
|
||||||
*
|
* Allow passing a custom debugger class (e.g. ``IPython.core.debugger:Pdb``
|
||||||
|
via ``--pdbcls``.
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
|
|
|
@ -8,21 +8,32 @@ import pytest
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
group = parser.getgroup("general")
|
group = parser.getgroup("general")
|
||||||
group._addoption('--pdb',
|
group._addoption(
|
||||||
action="store_true", dest="usepdb", default=False,
|
'--pdb', dest="usepdb", action="store_true",
|
||||||
help="start the interactive Python debugger on errors.")
|
help="start the interactive Python debugger on errors.")
|
||||||
|
group._addoption(
|
||||||
|
'--pdbcls', dest="usepdb_cls", metavar="modulename:classname",
|
||||||
|
help="start a custom interactive Python debugger on errors.")
|
||||||
|
|
||||||
def pytest_namespace():
|
def pytest_namespace():
|
||||||
return {'set_trace': pytestPDB().set_trace}
|
return {'set_trace': pytestPDB().set_trace}
|
||||||
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
if config.getvalue("usepdb"):
|
if config.getvalue("usepdb") or config.getvalue("usepdb_cls"):
|
||||||
config.pluginmanager.register(PdbInvoke(), 'pdbinvoke')
|
config.pluginmanager.register(PdbInvoke(), 'pdbinvoke')
|
||||||
|
if config.getvalue("usepdb_cls"):
|
||||||
|
modname, classname = config.getvalue("usepdb_cls").split(":")
|
||||||
|
__import__(modname)
|
||||||
|
pdb_cls = getattr(sys.modules[modname], classname)
|
||||||
|
else:
|
||||||
|
pdb_cls = pdb.Pdb
|
||||||
|
pytestPDB._pdb_cls = pdb_cls
|
||||||
|
|
||||||
old = (pdb.set_trace, pytestPDB._pluginmanager)
|
old = (pdb.set_trace, pytestPDB._pluginmanager)
|
||||||
def fin():
|
def fin():
|
||||||
pdb.set_trace, pytestPDB._pluginmanager = old
|
pdb.set_trace, pytestPDB._pluginmanager = old
|
||||||
pytestPDB._config = None
|
pytestPDB._config = None
|
||||||
|
pytestPDB._pdb_cls = pdb.Pdb
|
||||||
pdb.set_trace = pytest.set_trace
|
pdb.set_trace = pytest.set_trace
|
||||||
pytestPDB._pluginmanager = config.pluginmanager
|
pytestPDB._pluginmanager = config.pluginmanager
|
||||||
pytestPDB._config = config
|
pytestPDB._config = config
|
||||||
|
@ -32,6 +43,7 @@ class pytestPDB:
|
||||||
""" Pseudo PDB that defers to the real pdb. """
|
""" Pseudo PDB that defers to the real pdb. """
|
||||||
_pluginmanager = None
|
_pluginmanager = None
|
||||||
_config = None
|
_config = None
|
||||||
|
_pdb_cls = pdb.Pdb
|
||||||
|
|
||||||
def set_trace(self):
|
def set_trace(self):
|
||||||
""" invoke PDB set_trace debugging, dropping any IO capturing. """
|
""" invoke PDB set_trace debugging, dropping any IO capturing. """
|
||||||
|
@ -45,7 +57,7 @@ class pytestPDB:
|
||||||
tw.line()
|
tw.line()
|
||||||
tw.sep(">", "PDB set_trace (IO-capturing turned off)")
|
tw.sep(">", "PDB set_trace (IO-capturing turned off)")
|
||||||
self._pluginmanager.hook.pytest_enter_pdb(config=self._config)
|
self._pluginmanager.hook.pytest_enter_pdb(config=self._config)
|
||||||
pdb.Pdb().set_trace(frame)
|
self._pdb_cls().set_trace(frame)
|
||||||
|
|
||||||
|
|
||||||
class PdbInvoke:
|
class PdbInvoke:
|
||||||
|
@ -98,7 +110,7 @@ def _find_last_non_hidden_frame(stack):
|
||||||
|
|
||||||
|
|
||||||
def post_mortem(t):
|
def post_mortem(t):
|
||||||
class Pdb(pdb.Pdb):
|
class Pdb(pytestPDB._pdb_cls):
|
||||||
def get_stack(self, f, t):
|
def get_stack(self, f, t):
|
||||||
stack, i = pdb.Pdb.get_stack(self, f, t)
|
stack, i = pdb.Pdb.get_stack(self, f, t)
|
||||||
if f is None:
|
if f is None:
|
||||||
|
|
Loading…
Reference in New Issue