Вы не можете использовать consoleHandler()
здесь, потому что нет консоли . Ядро IPython является «безголовым» дочерним процессом, который выполняет код по запросу, направляемый внешним интерфейсом Jupyter.
Чтобы прервать работающее ядро IPython, интерфейс Jupyter использует сигнал SIGINT
. Это делается как на POSIX, так и на Windows; в Windows Jupyter использует дополнительную инфраструктуру, построенную на CreateEventA
, SetEvent
и WaitForMultipleObjects
для достижения того же результата, что и вызов POSIX os.killpg(PID, SIGINT)
; отдельный поток опрашивает событие и запускает сигнал SIGINT
в основном потоке.
Обратите внимание, что ядро IPython явно восстанавливает обработчик сигналов Python по умолчанию для каждого сообщения, которое оно обрабатывает. См. Реализации ipykernel.kernelbase.Kernel
для методов pre_
и post_handler_hook
:
self.saved_sigint_handler = signal(SIGINT, default_int_handler)
и
signal(SIGINT, self.saved_sigint_handler)
Эти два перехвата выполняются до и после каждого обработчика сообщений (поэтому для каждое сообщение, отправляемое веб-интерфейсом процессу ядра , включая , выполняет сообщения ).
Это signal.default_int_handler
, которое вызывает KeyboardInterrupt
в главном потоке Python. Если ваш код должен обнаруживать прерывания, он должен будет регистрировать свой собственный обработчик signal
каждый раз, когда IPython запускает ячейку.
В качестве примечания: автономный интерактивный интерпретатор Python не использует SetConsoleCtrlHandler
для обнаружения прерываний клавиатуры либо ; единственное место, которое используется в исходном коде Python, находится в py
пусковой установке , и только тогда, чтобы заглушить управляющие коды с помощью обработчика, который всегда возвращает TRUE
. Вместо этого Python полагается на Windows, отправляющую сигнал SIGINT
всем подключенным процессам консоли для активного окна консоли .