[Python-Dev] New/Old class exception pitfall

Alexander Belopolsky alexander.belopolsky at gmail.com
Mon Mar 17 23:35:46 CET 2008

While discussing issue2291, I presented the following argument:

Consider the following code:

class x:
class y(x):
 raise y
except y:
 print "a"
 print "b"

It prints 'b'. Now, suppose in preparation for 3.0 transition someone
adds "__metaclass__ = type" to the module with that code. The result:
it prints 'a'. Since the difference in behavior is in error handling
code, which in my experience is often not thoroughly tested, the bug
introduced by a seemingly innocuous move from old to new style classes
is likely to trigger in the worst possible moment. (For example a wrong
roll-back logic is applied after a failed database commit.)
""" http://bugs.python.org/msg63584

This issue is only partially alleviated by the -3 warning because the warning
is not issued unless the error condition raising a new style class not deriving
from BaseException is actually tested for.

It is my understanding that subclass check is skipped for new style classes
not derived from BaseException in order to enable the identity check when a
string exception is caught.

With the deprecation of string exceptions, this logic is hard to justify.

In any case, I believe this issue is either code or documentation bug:

Exceptions are identified by class instances. The except clause is
selected depending on the class of the instance: it must reference the class of
the instance or a base class thereof.
""" http://docs.python.org/dev/reference/executionmodel.html#id2

I don't see anything in the documentation that would suggest that old and new
class instances should behave differently.

More information about the Python-Dev mailing list