-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-28603: Fix exception chaining for unhashable exceptions #4014
Conversation
LGTM, but the code in Please add a news entry and your name in Misc/ACKS. |
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.)
2abe487
to
9e78d8c
Compare
@serhiy-storchaka thanks! I missed that one in idlelib. I've added another patch to address that instance of the problem, and also updated NEWS and ACKS. |
Thank you @zaneb. I left on to @terryjreedy to approve the new IDLE test. |
Thanks @zaneb for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6. |
…ythonGH-4014) (cherry picked from commit de86073)
GH-4024 is a backport of this pull request to the 3.6 branch. |
The goal is that IDLE print the same traceback as python without IDLE. Testing this more thoroughly is another issue. It is almost good enough for me here that it print something rather than raise, and the test exceeds that minimun. In use, the uncaught TypeError causes the IDLE run process to exit and the IDLE GUI process to start a new run process. |
Compare exceptions by identity rather than equality when checking for loops in the context/cause chain. This allows unhashable exceptions to be processed without error by the traceback module, and ensures that exception chaining can continue even after encountering either an exception that is either unhashable or compares as equal to a different exception in the chain (or both).
https://bugs.python.org/issue28603