[Python-Dev] An interesting exception handling quirk

Nick Coghlan ncoghlan at gmail.com
Sat Oct 19 13:41:17 CEST 2013


I've been looking at Terry's suggestion of using a class based
implementation for contextlib.suppress, and rediscovered why I
suggested Raymond switch the original implementation to using
@contextmanager: recreating the *exact* exception subclass check from
Python is actually difficult these days.

The exception handling only looks for concrete subclasses, ignoring
the dynamic subclass hook:

>>> import abc
>>> class ExceptionABC(abc.ABC, Exception):
...     pass
...
>>> ExceptionABC.register(ZeroDivisionError)
<class 'ZeroDivisionError'>
>>> issubclass(ZeroDivisionError, ExceptionABC)
True
>>> try:
...     1/0
... except ExceptionABC:
...     print("It's a subclass of ExceptionABC!")
... except ZeroDivisionError:
...     print("But not according to the exception handling!")
...
But not according to the exception handling!

I don't actually have a problem with the current behaviour (since
raise and except both enforce a requirement for the types involved to
be concrete subclasses of BaseException), but as far as I'm aware we
don't explicitly state anywhere that if exception handling and an
issubclass check give different answers for whether or not exception A
is a subclass of exception B, then the fault for any resulting
differences in behavious lies with the way A and/or B are defined, not
with the code using issubclass to check for exception inheritance.

Having noticed the discrepancy, I feel like it should be explicitly
recorded somewhere in the language reference, I'm just not sure where.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list