Ctrl-C вылетает Python после импорта scipy.stats
Я использую 64-битный Python 2.7.3 на 64-битной Win7. Я могу надежно завершить работу интерпретатора Python, выполнив это:
>>> from scipy import stats
>>> import time
>>> time.sleep(3)
и нажав Control-C во время сна. KeyboardInterrupt не вызывается; переводчик падает. Следующее напечатано:
forrtl: error (200): program aborting due to control-C event
Image PC Routine Line Source
libifcoremd.dll 00000000045031F8 Unknown Unknown Unknown
libifcoremd.dll 00000000044FC789 Unknown Unknown Unknown
libifcoremd.dll 00000000044E8583 Unknown Unknown Unknown
libifcoremd.dll 000000000445725D Unknown Unknown Unknown
libifcoremd.dll 00000000044672A6 Unknown Unknown Unknown
kernel32.dll 0000000077B74AF3 Unknown Unknown Unknown
kernel32.dll 0000000077B3F56D Unknown Unknown Unknown
ntdll.dll 0000000077C73281 Unknown Unknown Unknown
Это делает невозможным прерывание длительных вычислений scipy.
В поисках «forrtl» и тому подобного я вижу предположения, что проблема такого рода связана с использованием библиотеки Fortran, которая переопределяет обработку Ctrl-C. Я не вижу ошибки на трекере Scipy, но учитывая, что Scipy - это библиотека для использования с Python, я бы посчитал это ошибкой. Это нарушает обработку Python Ctrl-C. Есть ли обходной путь для этого?
Редактировать: следуя совету @ cgohlke, я попытался добавить свой собственный обработчик после импорта scipy.Этот вопрос о связанной проблеме показывает, что добавление обработчика сигнала не работает. Я пытался использовать Windows APISetConsoleCtrlHandler функция через pywin32:
from scipy import stats
import win32api
def doSaneThing(sig, func=None):
print "Here I am"
raise KeyboardInterrupt
win32api.SetConsoleCtrlHandler(doSaneThing, 1)
После этого нажатие Ctrl-C выводит «Вот я», но Python по-прежнему вылетает с ошибкой forrtl. Иногда я также получаю сообщение «Сбой функции ConsoleCtrlHandler», которое быстро исчезает.
Если я запускаю это в IPython, я вижу обычную трассировку Python KeyboardInterrupt перед ошибкой forrtl. Я также вижу обычную трассировку Python, за которой следует ошибка forrtl, если вместо KeyboardInterrupt возникает другая ошибка (например, ValueError):
ValueError Traceback (most recent call last)
<ipython-input-1-08defde66fcb> in doSaneThing(sig, func)
3 def doSaneThing(sig, func=None):
4 print "Here I am"
----> 5 raise ValueError
6 win32api.SetConsoleCtrlHandler(doSaneThing, 1)
ValueError:
forrtl: error (200): program aborting due to control-C event
[etc.]
Кажется, что независимо от того, что делает основной обработчик, он не просто перехватывает Ctrl-C напрямую, но и реагирует на состояние ошибки (ValueError) и сам сбой. Есть ли способ устранить это?