except block isn't catching exception

Ian Kelly ian.g.kelly at gmail.com
Sat Aug 8 08:56:43 CEST 2015

On Fri, Aug 7, 2015 at 8:44 PM, Chris Angelico <rosuav at gmail.com> wrote:
> The exception isn't happening inside sock.accept(), as I explained. So
> you can't catch it there.

Where does the exception happen then? Your explanation only covered
why the blocking call cannot be interrupted by it, not why the
exception isn't simply raised when the blocking call finishes.

I played around with this and found that if the try...except chain is
wrapped in another outer try statement, then the KeyboardInterrupt
exception does get caught by the outer exception handler as one might
expect. For the inner try statement though, neither any except block
nor the else block is executed, just the finally block. I didn't know
until now that was even possible.

The language reference mentions this in regard to the try statement:

If the evaluation of an expression in the header of an except clause
raises an exception, the original search for a handler is canceled and
a search starts for the new exception in the surrounding code and on
the call stack (it is treated as if the entire try statement raised
the exception).

So my theory as to what's going on here is that sock.accept raises a
socket.timeout exception, but then the KeyboardInterrupt is raised
before the first except block even begins to check the exception type,
and so it's treated as if the "entire try statement" raised
KeyboardInterrupt. Hence it can't be caught there, but only in an
outer try statement.

Whatever the reason, it definitely seems to be an interesting corner case.

More information about the Python-list mailing list