Skip to content

Commit fb2300f

Browse files
committed
main: wrap_session: handle exit.Exception with notify_exception
Fixes #6257. Via blueyed#132.
1 parent 63c9ad0 commit fb2300f

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

changelog/6257.improvement.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Handle `exit.Exception` raised in `notify_exception` (via `pytest_internalerror`), e.g. when quitting pdb from post mortem.

src/_pytest/main.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,17 @@ def wrap_session(config, doit):
212212
config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
213213
session.exitstatus = exitstatus
214214
except: # noqa
215-
excinfo = _pytest._code.ExceptionInfo.from_current()
216-
config.notify_exception(excinfo, config.option)
217215
session.exitstatus = ExitCode.INTERNAL_ERROR
218-
if excinfo.errisinstance(SystemExit):
219-
sys.stderr.write("mainloop: caught unexpected SystemExit!\n")
216+
excinfo = _pytest._code.ExceptionInfo.from_current()
217+
try:
218+
config.notify_exception(excinfo, config.option)
219+
except exit.Exception as exc:
220+
if exc.returncode is not None:
221+
session.exitstatus = exc.returncode
222+
sys.stderr.write("{}: {}\n".format(type(exc).__name__, exc))
223+
else:
224+
if excinfo.errisinstance(SystemExit):
225+
sys.stderr.write("mainloop: caught unexpected SystemExit!\n")
220226

221227
finally:
222228
excinfo = None # Explicitly break reference cycle.

testing/test_main.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import pytest
2+
from _pytest.main import ExitCode
3+
4+
5+
@pytest.mark.parametrize("ret_exc", ((None, ValueError), (42, SystemExit)))
6+
def test_wrap_session_notify_exception(ret_exc, testdir):
7+
returncode, exc = ret_exc
8+
c1 = testdir.makeconftest(
9+
"""
10+
import pytest
11+
12+
def pytest_sessionstart():
13+
raise {exc}("boom")
14+
15+
def pytest_internalerror(excrepr, excinfo):
16+
pytest.exit("exiting after %s..." % excinfo.typename, returncode={returncode!r})
17+
""".format(
18+
returncode=returncode, exc=exc.__name__
19+
)
20+
)
21+
result = testdir.runpytest()
22+
if returncode:
23+
assert result.ret == returncode
24+
else:
25+
assert result.ret == ExitCode.INTERNAL_ERROR
26+
result.stdout.lines[0] == "INTERNALERROR> Traceback (most recent call last):"
27+
result.stdout.lines[-3:] == [
28+
'INTERNALERROR> File "{}", line 2, in pytest_sessionstart'.format(c1),
29+
"INTERNALERROR> raise ValueError",
30+
"INTERNALERROR> ValueError: boom",
31+
]
32+
assert result.stderr.lines == ["Exit: exiting after {}...".format(exc.__name__)]

0 commit comments

Comments
 (0)