Repository navigation
Conversation
Python runs its SIGINT handler only between bytecodes. While the main thread waited in the engine for query(), execute() or query_as_arrow(), Ctrl-C therefore took effect only after the query had finished: a 15 s query ran to the end before KeyboardInterrupt appeared. During such a wait on the main thread, a scoped SIGINT handler now interrupts the connection's query and then calls Python's own handler. Once the call returns, the pending signal is raised as KeyboardInterrupt instead of the engine's "Interrupted." error, and the connection stays usable. The handler is installed only while Python's default handler (KeyboardInterrupt) is active, so a custom SIGINT handler keeps its behaviour, and only on POSIX systems. That check goes through the driver's import cache and never fails a query, e.g. one run during interpreter shutdown. A Ctrl-C that lands while the query is still compiling is dropped by the engine, as any interrupt is; a second Ctrl-C stops the query. The engine interrupts a connection, not a query: if the main thread's call is waiting behind another thread's query on the same connection, Ctrl-C stops that query instead, and the main thread's query runs before KeyboardInterrupt is raised. The new tests send SIGINT one second into a long query through query(), execute() with parameters and query_as_arrow(), and expect KeyboardInterrupt within seconds; they fail on main. A custom handler test checks that the query then still finishes and the handler runs. The C-API backend calls the engine through ctypes and is not covered, so the interrupt tests are listed in capi_xfails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This work was produced with the help of language models.
Python runs its SIGINT handler only between bytecodes, so while the main thread waited in the engine for
query(),execute()orquery_as_arrow(), Ctrl-C took effect only after the query finished: a 15 s query ran to the end beforeKeyboardInterruptappeared.Fix. During such a wait on the main thread, a scoped SIGINT handler interrupts the connection's query and calls Python's own handler; once the call returns, the pending signal becomes
KeyboardInterruptinstead of the engine'sInterrupted.error. It is installed only while Python's default handler is active, so custom handlers are untouched. A Ctrl-C during compile is dropped by the engine; a second one stops the query.Known limitation: the engine interrupts a connection, not a query. If the main thread's call waits behind another thread's query on the same connection, Ctrl-C stops that query instead, and the main thread's query runs before
KeyboardInterruptis raised. Pybind backend on POSIX only; the C-API backend (ctypes) is not covered.Tests. Three tests send SIGINT one second into a long query (
query(), parameterizedexecute(),query_as_arrow()) and expectKeyboardInterruptwithin seconds and a usable connection afterwards; they fail onmain, pass here on pybind and are xfailed on C-API. A custom-handler test checks the query still finishes and the handler runs. Full suites: no new failures.Fixes #62