Ctrl-C trava o Python após importar scipy.stats
Estou executando o Python 2.7.3 de 64 bits no Win7 de 64 bits. Eu posso travar de forma confiável o interpretador Python fazendo isso:
>>> from scipy import stats
>>> import time
>>> time.sleep(3)
e pressionando Control-C durante o sono. Um KeyboardInterrupt não é gerado; o intérprete trava. O seguinte é impresso:
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
Isso torna impossível interromper os cálculos de longa duração.
Pesquisando por "forrtl" e coisas assim, vejo sugestões de que esse tipo de problema se deva ao uso de uma biblioteca Fortran que substitui o controle Ctrl-C. Eu não vejo um bug no trackerbut Scipy dado que Scipy é uma biblioteca para uso com Python, eu consideraria isso um bug. Isso quebra o manuseio do Ctrl-C pelo Python. Existe alguma solução para isso?
Editar: Seguindo a sugestão do @ cgohlke, tentei adicionar meu próprio manipulador depois de importar o scipy.Essa questão sobre um problema relacionado mostra que adicionar um manipulador de sinal não funciona. Eu tentei usar a API do WindowsSetConsoleCtrlHandler função via pywin32:
from scipy import stats
import win32api
def doSaneThing(sig, func=None):
print "Here I am"
raise KeyboardInterrupt
win32api.SetConsoleCtrlHandler(doSaneThing, 1)
Depois disso, pressionar Ctrl-C imprime "Here i am", mas o Python ainda falha com o erro forrtl. Às vezes eu também recebo uma mensagem dizendo "Falha na função ConsoleCtrlHandler", que desaparece rapidamente.
Se eu executar isso no IPython, posso ver um traceback normal do Python KeyboardInterrupt antes do erro forrtl. Eu também vejo um traceback normal do Python seguido pelo erro forrtl se eu gerar algum outro erro em vez de KeyboardInterrupt (por exemplo, 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.]
Parece que o que quer que seja que o manipulador subjacente esteja fazendo, não é apenas capturar Ctrl-C diretamente, mas está reagindo à condição de erro (ValueError) e travando a si mesmo. Existe alguma maneira de eliminar isso?