<div dir="auto">Would guards (such as from the switch-case discussions) be a good fit?<div dir="auto"><br></div><div dir="auto">try:</div><div dir="auto">    ...</div><div dir="auto">except RuntimeError as e if e.message == "tie":</div><div dir="auto">    ...</div><br><br><div class="gmail_quote" dir="auto"><div dir="ltr">On Thu, May 31, 2018, 00:48 Danilo J. S. Bellini <<a href="mailto:danilo.bellini@gmail.com">danilo.bellini@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi!<br>I was working on handling some exceptions from external software<br>(e.g. database constraint triggers)<br>switching the handler based on the messages that had been sent.<br>Today we can do something like (running on Python 3.6.5):<br><br><div><br></div><div><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">>>> </span>try:<br><span style="font-family:monospace,monospace">... </span>    # [...]<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    session.commit() # Here it raises!<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    # [...]<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>except DatabaseError as exc:<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    msg = get_db_error_msg_from_exception(exc)<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    if msg == "beyond_limit":<br></span></div><div><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>        # [...]<br></span></div><div><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    elif msg == "no_funds":<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>        # [...]<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    else:<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>        raise<br></span></div><br><div><br></div><div>That works, but I'd like to do something like:</div><div><br></div><div><br></div><div><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">>>> </span>try:<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    # [...]<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>except BeyondLimit:<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    # [...]<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>except NoFunds:<br><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span></span> </span>    # [...]<br></span><br></div><div><br></div><div>Creating classes to "match" the exception in their <span style="font-family:monospace,monospace">__instancecheck__</span>.<br></div><div>Well, I tried to do so. A simplified example would be:<br></div><div></div><div><br></div><div><br></div><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">>>> </span></span></span>class MsgCheckerMeta(type):<br><span style="font-family:monospace,monospace">... </span>    def __instancecheck__(cls, instance):<br></span><div><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">... </span>        return str(instance) == cls.internal</span></div><div><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">...</span><br></span></div><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">>>> </span></span></span>class ExceptionHasMessage(Exception, metaclass=<span style="font-family:monospace,monospace">MsgCheckerMeta</span>):<br>...     internal = "message"<br></span><span style="font-family:monospace,monospace"></span><div><br></div><div><br></div><div>Using these new classes, we would get this:</div><div><br></div><div><br></div><span style="font-family:monospace,monospace"></span><span style="font-family:monospace,monospace">>>> try:<br>...     raise Exception("message")<br>... except ExceptionHasMessage:<br>...     print("Yeah!")<br>...<br>Traceback (most recent call last):<br>  File "<stdin>", line 2, in <module><br>Exception: message</span><div><span style="font-family:monospace,monospace"><br></span></div><div><br></div><div>Yet,</div><div><br></div><div><br></div><div><span style="font-family:monospace,monospace">>>> isinstance(Exception("message"), ExceptionHasMessage)<br>True<br>>>> try:<br>...     raise Exception("message")<br>... except Exception as exc:<br>...     print(isinstance(exc, ExceptionHasMessage))<br>...<br>True<br></span><br></div><div><br></div><div></div><div></div>The idea is to allow catching exceptions beyond checking their MRO,<br>using a class that checks the exception instance by implementing<br>a custom <span style="font-family:monospace,monospace">__instancecheck__</span>.<br><br><div>-- <br><div class="m_-7275650982641573717gmail_signature">Danilo J. S. Bellini<br>---------------<br>"<i>It is not our business to set up prohibitions, but to arrive at conventions.</i>" (R. Carnap)<br></div>
</div></div>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank" rel="noreferrer">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div></div>