It is intentional to avoid (semi) premutation since Twisted is a collaborative multitasking system. Ctrl-C is processed in Python using the SIGINT handler set by the interpreter at startup. The handler sets the flag when it is called. After each byte code is executed, the interpreter checks the flag. If it is installed, KeyboardInterrupt will be raised at that point.
The reactor has its own SIGINT processor. This replaces the behavior of the interpreter handler. The reactor handler initiates a shutdown of the reactor. Since it does not throw an exception, it does not interrupt any code. The loop (or something else) ends, and when control returns to the reactor, it stops.
If you want Ctrl-C (i.e. SIGINT) to raise KeyboardInterrupt, you can simply restore the Python SIGINT handler using the signal module:
signal.signal(signal.SIGINT, signal.default_int_handler)
Note, however, that if you send SIGINT while the code is running from Twisted, and not from your own application code, the behavior is undefined because Twisted does not expect a KeyboardInterrupt interrupt.
source share