Consider the following code block:
class MyException(Exception):
__hash__ = None
try:
raise ExceptionGroup("Foo", [
MyException("Bar")
])
except* Exception:
pass
The except*
should catch any number of exceptions of any kind, thrown together as an ExceptionGroup
(or a single exception of any kind if thrown alone, come to that). Instead, an unhandled TypeError
occurs during handling of our ExceptionGroup
, allegedly at "line -1" of our module:
Exception Group Traceback (most recent call last):
| File "C:\Users\Josep\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_62.py", line 6, in <module>
| raise ExceptionGroup("Foo", [
| ExceptionGroup: Foo (1 sub-exception)
- ---------------- 1 ----------------
| MyException: Bar
------------------------------------
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Josep\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_62.py", line -1, in <module>
TypeError: unhashable type: 'MyException'
(If we replace the except* Exception
with something more specific, say except* ValueError
or except* MyException
, the same thing happens. If we try to just raise a single MyException
and catch it normally with except MyException
, that works fine.)
Normal except
clauses don't care whether exceptions are hashable. I could not find this quirk of except*
documented in PEP-654 or the Python 3.11 release notes. Is this intended behavior, or is it simply a bug in the Python implementation I'm using?
(For those who want to reproduce this behavior, I'm using Python 3.11.0, 64-bit, on Windows.)
CodePudding user response:
This was reported at https://github.com/python/cpython/issues/99181 and we have a PR to fix it. Should be fixed in 3.11.1.
CodePudding user response:
I wouldn't really call it a bug; it's the programmer fault for breaking the promise Exception
class makes (implementing __hash__
method); therefore it's programmer who is responsible for making sure things work as intended after doing this. After all, would you call following snippet a "bug" or "programmer mistake"?
class MyInt(int):
__hash__ = None
d = {}
d[MyInt(2)] = 2 # TypeError: unhashable type: 'MyInt'
Yours example isn't much different.