Barry Warsaw wrote:
Exception +- KeyboardInterrupt +- GeneratorExit +- SystemExit +- StopIteration +- Error | +- ImportError | +- (etc.) | +- Warning +- UserWarning +- (etc.)
Use defined errors should inherit from Error, not Exception. With this, "except Exception" would be a synonym for bare except, while "except Error" would be the standard idiom for letting non-error exceptions pass through.
I don't know whether this is possible for Python 2.5, but I think it should be what we strive for for Py3K, and I do not think BaseException is at all necessary.
The main problems I have with the idea are the fact that a large fraction of the user-defined exceptions out there already inherit from Exception (and this has been pushed for a long time as the right thing to do) and the fact that "except Exception:" has also been pushed for years as the preferred alternative to a bare "except:".
Rather than trying to change course midstream, I like the fact that the PEP 352 hierarchy introduces BaseException to bring the language itself into line with what people have already been taught. Breaking things in Py3k is all well and good, but breaking them gratuitously is something else entirely :)
I also agree with the point made during the PEP 348/352 discussions that StopIteration reaching any except clause that isn't specifically expecting it is an error. Direct calls to an iterator's next method need to expect the StopIteration and decide how to handle it - not handling it is a bug.
For KeyboardInterrupt/SystemExit/GeneratorExit, it is clear that the standard behaviour should be to reraise them - the entire point of those exceptions is to shut down an entire call stack. StopIteration, on the other hand, merely indicates that a particular iterator has completed, not that the entire stack of iterators should be shut down.