I will talk about this explanation and a workaround:
So what I do:
def interrupted(signum, stackframe): log.warning('interrupted > Got signal: %s', signum) menu.quitMenu = True
The problem is that although the menu is notified that it should stop and will do it soon, it will not be able to do it now, as it is stuck in raw_input :
def askUser(self): current_date = datetime.now().isoformat(' ') choice = raw_input('%s > ' % current_date) return choice
So, since twisted removes the default interrupt handler, raw_input does not stop. I still need to press enter after ^C to stop it.
How can I make raw_input be stopped without setting a default interrupt handler, which is the source of problems in a twisted context (since the twisted itself does not expect an interrupt)
I think that the problem is not only related to raw_input : any function that executes for an unlimited time (or longer than the set limit) must somehow be interrupted.
Is there a valid twisted pattern for this?
EDIT
This is the full test code:
from datetime import datetime class Menu: def __init__(self): self.quitMenu = False def showMenu(self): print ''' A) Do A B) Do B ''' def askUser(self): current_date = datetime.now().isoformat(' ') choice = raw_input('%s > Please select option > ' % current_date) print return choice def stopMe(self): self.quitMenu = True def alive(self): return self.quitMenu == False def doMenuOnce(self): self.showMenu() choice = self.askUser() if not self.alive() :
What I can run in two different ways.
The usual way:
menu = Menu() menu.forever()
Pressing ^C immediately stops the program:
A) Do A B) Do B 2013-12-03 11:00:26.288846 > Please select option > ^CTraceback (most recent call last): File "twisted_keyboard_interrupt.py", line 72, in <module> menu.forever() File "twisted_keyboard_interrupt.py", line 43, in forever self.doMenuOnce() File "twisted_keyboard_interrupt.py", line 34, in doMenuOnce choice = self.askUser() File "twisted_keyboard_interrupt.py", line 22, in askUser choice = raw_input('%s > Please select option > ' % current_date) KeyboardInterrupt
As expected.
Twisted path:
menu = Menu() menutw = MenuTwisted(menu) menutw.run()
Pressing ^C will result in:
A) Do A B) Do B 2013-12-03 11:04:18.678219 > Please select option > ^CInterrupted!
But askUser is not really interrupted: I still need to press enter for raw_input to complete.