Handle KeyboardInterrupt and SystemExit at collection time (#12191)
This commit is contained in:
parent
4c5298c395
commit
97610067ac
1
AUTHORS
1
AUTHORS
|
@ -36,6 +36,7 @@ Andrey Paramonov
|
||||||
Andrzej Klajnert
|
Andrzej Klajnert
|
||||||
Andrzej Ostrowski
|
Andrzej Ostrowski
|
||||||
Andy Freeland
|
Andy Freeland
|
||||||
|
Anita Hammer
|
||||||
Anthon van der Neut
|
Anthon van der Neut
|
||||||
Anthony Shaw
|
Anthony Shaw
|
||||||
Anthony Sottile
|
Anthony Sottile
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Keyboard interrupts and system exits are now properly handled during the test collection.
|
|
@ -393,7 +393,9 @@ def pytest_make_collect_report(collector: Collector) -> CollectReport:
|
||||||
|
|
||||||
return list(collector.collect())
|
return list(collector.collect())
|
||||||
|
|
||||||
call = CallInfo.from_call(collect, "collect")
|
call = CallInfo.from_call(
|
||||||
|
collect, "collect", reraise=(KeyboardInterrupt, SystemExit)
|
||||||
|
)
|
||||||
longrepr: Union[None, Tuple[str, int, str], str, TerminalRepr] = None
|
longrepr: Union[None, Tuple[str, int, str], str, TerminalRepr] = None
|
||||||
if not call.excinfo:
|
if not call.excinfo:
|
||||||
outcome: Literal["passed", "skipped", "failed"] = "passed"
|
outcome: Literal["passed", "skipped", "failed"] = "passed"
|
||||||
|
|
|
@ -7,6 +7,7 @@ import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import textwrap
|
import textwrap
|
||||||
from typing import List
|
from typing import List
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
from _pytest.assertion.util import running_on_ci
|
from _pytest.assertion.util import running_on_ci
|
||||||
from _pytest.config import ExitCode
|
from _pytest.config import ExitCode
|
||||||
|
@ -1856,3 +1857,33 @@ def test_do_not_collect_symlink_siblings(
|
||||||
# Ensure we collect it only once if we pass the symlinked directory.
|
# Ensure we collect it only once if we pass the symlinked directory.
|
||||||
result = pytester.runpytest(symlink_path, "-sv")
|
result = pytester.runpytest(symlink_path, "-sv")
|
||||||
result.assert_outcomes(passed=1)
|
result.assert_outcomes(passed=1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"exception_class, msg",
|
||||||
|
[
|
||||||
|
(KeyboardInterrupt, "*!!! KeyboardInterrupt !!!*"),
|
||||||
|
(SystemExit, "INTERNALERROR> SystemExit"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_respect_system_exceptions(
|
||||||
|
pytester: Pytester,
|
||||||
|
exception_class: Type[BaseException],
|
||||||
|
msg: str,
|
||||||
|
):
|
||||||
|
head = "Before exception"
|
||||||
|
tail = "After exception"
|
||||||
|
ensure_file(pytester.path / "test_eggs.py").write_text(
|
||||||
|
f"print('{head}')", encoding="UTF-8"
|
||||||
|
)
|
||||||
|
ensure_file(pytester.path / "test_ham.py").write_text(
|
||||||
|
f"raise {exception_class.__name__}()", encoding="UTF-8"
|
||||||
|
)
|
||||||
|
ensure_file(pytester.path / "test_spam.py").write_text(
|
||||||
|
f"print('{tail}')", encoding="UTF-8"
|
||||||
|
)
|
||||||
|
|
||||||
|
result = pytester.runpytest_subprocess("-s")
|
||||||
|
result.stdout.fnmatch_lines([f"*{head}*"])
|
||||||
|
result.stdout.fnmatch_lines([msg])
|
||||||
|
result.stdout.no_fnmatch_line(f"*{tail}*")
|
||||||
|
|
Loading…
Reference in New Issue