Skip to content

Commit 3a39b73

Browse files
authored
fix(iqb_exception): don't suppress KeyboardInterrupt (#124)
This diff ensures that hitting `^C` immediately interrupts the scripting code no matter what it is doing. Useful to interrupt a BigQuery query in a long batch immediately as opposed to have all of them started and interrupted while running, which burns the daily allowance (happened yesterday).
1 parent 5beddc9 commit 3a39b73

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

library/src/iqb/scripting/iqb_exception.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ def __enter__(self):
3131
return self
3232

3333
def __exit__(self, exc_type, exc_value, traceback):
34+
if exc_type is None:
35+
return False
36+
if issubclass(exc_type, KeyboardInterrupt):
37+
return False
3438
if exc_type:
3539
log.error("operation failed: %s", exc_value)
3640
_ = traceback

library/tests/iqb/scripting/iqb_exception_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from unittest.mock import patch
44

5+
import pytest
6+
57
from iqb.scripting import iqb_exception
68

79

@@ -29,3 +31,17 @@ def test_exception_sets_failed_and_logs(self) -> None:
2931
log.error.assert_called_once()
3032
assert log.error.call_args[0][0] == "operation failed: %s"
3133
assert str(log.error.call_args[0][1]) == "boom"
34+
35+
def test_keyboard_interrupt_not_suppressed(self) -> None:
36+
interceptor = iqb_exception.Interceptor()
37+
38+
with (
39+
patch("iqb.scripting.iqb_exception.log") as log,
40+
pytest.raises(KeyboardInterrupt),
41+
interceptor,
42+
):
43+
raise KeyboardInterrupt()
44+
45+
assert interceptor.failed is False
46+
assert interceptor.exitcode() == 0
47+
log.error.assert_not_called()

0 commit comments

Comments
 (0)