-
-
Notifications
You must be signed in to change notification settings - Fork 33.9k
Description
Bug report
Bug description:
This issue was originally reported in the beartype library (Ref: beartype/beartype#610), but investigation suggests it may stem from a change in Python’s annotationlib.ForwardRef implementation.
Starting with Python 3.14.1, deferred annotations (PEP 649) involving self-referential return type is raising: TypeError: unhashable type: 'cell' at decoration time. This worked correctly in Python 3.14.0 and the issue appears to persist in 3.14.2, suggesting a regression.
The error originates from annotationlib.ForwardRef.__hash__, which attempts to hash internal state containing non-hashable cell objects. Although observed via beartype, this may affects any downstream library that hashes ForwardRef objects. The following code seems to be raising the issue:
tuple(sorted(self.__cell__.items())) if isinstance(self.__cell__, dict) else self.__cell__,
Lines 290 to 299 in 1857a40
| def __hash__(self): | |
| return hash(( | |
| self.__forward_arg__, | |
| self.__forward_module__, | |
| id(self.__globals__), # dictionaries are not hashable, so hash by identity | |
| self.__forward_is_class__, | |
| tuple(sorted(self.__cell__.items())) if isinstance(self.__cell__, dict) else self.__cell__, | |
| self.__owner__, | |
| tuple(sorted(self.__extra_names__.items())) if self.__extra_names__ else None, | |
| )) |
Code:
#!pip install beartype==0.22.9
from beartype import beartype
class MyClass:
@beartype
def foo(self) -> MyClass:
return MyClass()
print(MyClass().foo())Observed behavior:
The program fails during decoration with the error: TypeError: unhashable type: 'cell'
File ".../beartype/_check/metadata/hint/hintsane.py", line 242, in __init__
self._hash = hash((hint, hint_recursable_to_depth, typearg_to_hint))
File ".../python3.14/annotationlib.py", line 291, in __hash__
return hash((..., tuple(sorted(self.__extra_names__.items()))))
TypeError: unhashable type: 'cell'
Inspection shows:
>>> self.__cell__
{'__classdict__': <cell at 0x...: dict object>}
>>> tuple(sorted(self.__cell__.items()))
(('__classdict__', <cell at 0x...>),)Since cell objects are not hashable, this causes hash to fail.
Affected Versions:
Python 3.14.1 and 3.14.2
OS Tested on: MacOS
CPython versions tested on:
3.14
Operating systems tested on:
macOS