
Hi! I was working on handling some exceptions from external software (e.g. database constraint triggers) switching the handler based on the messages that had been sent. Today we can do something like (running on Python 3.6.5):
try: ... # [...] ... session.commit() # Here it raises! ... # [...] ... except DatabaseError as exc: ... msg = get_db_error_msg_from_exception(exc) ... if msg == "beyond_limit": ... # [...] ... elif msg == "no_funds": ... # [...] ... else: ... raise
That works, but I'd like to do something like:
try: ... # [...] ... except BeyondLimit: ... # [...] ... except NoFunds: ... # [...]
Creating classes to "match" the exception in their __instancecheck__. Well, I tried to do so. A simplified example would be:
class MsgCheckerMeta(type): ... def __instancecheck__(cls, instance): ... return str(instance) == cls.internal ... class ExceptionHasMessage(Exception, metaclass=MsgCheckerMeta): ... internal = "message"
Using these new classes, we would get this:
try: ... raise Exception("message") ... except ExceptionHasMessage: ... print("Yeah!") ... Traceback (most recent call last): File "<stdin>", line 2, in <module> Exception: message
Yet,
isinstance(Exception("message"), ExceptionHasMessage) True try: ... raise Exception("message") ... except Exception as exc: ... print(isinstance(exc, ExceptionHasMessage)) ... True
The idea is to allow catching exceptions beyond checking their MRO, using a class that checks the exception instance by implementing a custom __instancecheck__. -- Danilo J. S. Bellini --------------- "*It is not our business to set up prohibitions, but to arrive at conventions.*" (R. Carnap)