The question is, whether, given
class Base:pass class MyExc(Base, Exception):pass
it would be valid to write
try: foo() # raises MyExc except Base: pass
The "except Base:" class would of course be illegal because Base doesn't derive from Exception. (Although the error might only be detected when MyExc is raised -- but PyChecker could do better.) But the statement "raise MyExc" would be perfectly legal, and could be caught either with "except MyExc" or "except Exception".
If that ought to be allowed, I fail to see the rationale to require that exceptions be derived from Exception: The rationale could be "all exceptions are primarily instances of Exception" - yet in this case, Base is the primary class, and Exception is just a mix-in that plays no further role in this case of exception handling.
I have never heard of the concept "primarily an instance of". I also don't understand why that should be the rule.
If you want to allow Base in the except clause, but do allow Base as
^^^^^ Did you mean "disallow"?
the base class of MyExc, I'd be curious what run-time semantics you'd associate with this example.
Before we waste more time on this, let me explain why I like the rule that all exception classes be derived from Exception. It's only a vague liking, and maybe it's not worth making it a rule. I like it because including Exception (or one of its well-known subclasses) in the base class is a clue to the reader that a particular class declaration is used as an exception. AFAIK this is the only reason why Java has a similar rule; C++ does not, and lets you throw any class.
I can't see any implementation benefits from the requirement. It sounds like you can't either -- or else you would have pointed them out by now. So maybe we shouldn't bother with this rule, and then we should take the recommendation out of the documentation. But I still kind of like it, for the reason I explained in the previous paragraph.
--Guido van Rossum (home page: http://www.python.org/%7Eguido/)