bpo-28603: Fix exception chaining for unhashable exceptions by zaneb · Pull Request #4014 · python/cpython
In the traceback module, TracebackException checks for loops between exceptions to prevent an infinite traceback. It does this by putting the already-seen exception into a set. This means that unhashable exception objects will cause an error - an error that itself can likely not be printed because of the presence of the unhashable exception in the chain. In this case, we don't actually care about equality of the objects as defined by the class designer; we want to check that we don't encounter the self-same exception object, from a chain that is necessarily all in memory at the same time. We can trivially do so by comparing identities instead of equality.
IDLE effectively has its own implementation of traceback.print_exception() to allow it to clean up the tracebacks. Unhashable exceptions caused a TypeError in the exception printer, which caused the shell to restart. This change eliminates the problem by comparing exceptions by identity rather than equality, analagous to how the traceback module now does it.
Previously when printing an exception traceback in PyErr_Display(), it would stop traversing the context/cause chain when it encountered an exception that was either unhashable or compared equal to one already seen in the chain. With this change, we only stop traversing the chain when we encounter the same exception object again (indicating a loop.)
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request
Oct 17, 2017
zaneb
mentioned this pull request
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters