Skip to content

Commit

Permalink
Merge pull request #3436 from brianmaissy/feature/enter_pdb_on_keyboa…
Browse files Browse the repository at this point in the history
…rd_interrupt

--pdb treats KeyboardInterrupt as exception
  • Loading branch information
nicoddemus authored May 3, 2018
2 parents 7834b45 + 1a880be commit b03b387
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 8 deletions.
2 changes: 1 addition & 1 deletion _pytest/debugging.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def pytest_addoption(parser):
group = parser.getgroup("general")
group._addoption(
'--pdb', dest="usepdb", action="store_true",
help="start the interactive Python debugger on errors.")
help="start the interactive Python debugger on errors or KeyboardInterrupt.")
group._addoption(
'--pdbcls', dest="usepdb_cls", metavar="modulename:classname",
help="start a custom interactive Python debugger on errors. "
Expand Down
12 changes: 8 additions & 4 deletions _pytest/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,24 +176,28 @@ def check_interactive_exception(call, report):
def call_runtest_hook(item, when, **kwds):
hookname = "pytest_runtest_" + when
ihook = getattr(item.ihook, hookname)
return CallInfo(lambda: ihook(item=item, **kwds), when=when)
return CallInfo(lambda: ihook(item=item, **kwds), when=when,
treat_keyboard_interrupt_as_exception=item.config.getvalue("usepdb"))


class CallInfo(object):
""" Result/Exception info a function invocation. """
#: None or ExceptionInfo object.
excinfo = None

def __init__(self, func, when):
def __init__(self, func, when, treat_keyboard_interrupt_as_exception=False):
#: context of invocation: one of "setup", "call",
#: "teardown", "memocollect"
self.when = when
self.start = time()
try:
self.result = func()
except KeyboardInterrupt:
self.stop = time()
raise
if treat_keyboard_interrupt_as_exception:
self.excinfo = ExceptionInfo()
else:
self.stop = time()
raise
except: # noqa
self.excinfo = ExceptionInfo()
self.stop = time()
Expand Down
2 changes: 2 additions & 0 deletions changelog/3299.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The ``--pdb`` option now causes KeyboardInterrupt to enter the debugger, instead of stopping the test session.
On python 2.7, hitting CTRL+C again exits the debugger. On python 3.2 and higher, use CTRL+D.
6 changes: 3 additions & 3 deletions doc/en/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ allows one to drop into the PDB_ prompt via a command line option::

pytest --pdb

This will invoke the Python debugger on every failure. Often you might
only want to do this for the first failing test to understand a certain
failure situation::
This will invoke the Python debugger on every failure (or KeyboardInterrupt).
Often you might only want to do this for the first failing test to understand
a certain failure situation::

pytest -x --pdb # drop to PDB on first failure, then end test session
pytest --pdb --maxfail=3 # drop to PDB for first three failures
Expand Down
8 changes: 8 additions & 0 deletions testing/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ def test_func():
assert rep.failed
assert len(pdblist) == 0

def test_pdb_on_KeyboardInterrupt(self, testdir, pdblist):
rep = runpdb_and_get_report(testdir, """
def test_func():
raise KeyboardInterrupt
""")
assert rep.failed
assert len(pdblist) == 1

def test_pdb_interaction(self, testdir):
p1 = testdir.makepyfile("""
def test_1():
Expand Down

0 comments on commit b03b387

Please sign in to comment.