Skip to content

[rejected AI] LRUCache TypeError on Python 3.14 with unhashable keys - #2256

Closed
sanyamk23 wants to merge 3 commits into
pallets:mainfrom
sanyamk23:fix/issue-2180-xrepo
Closed

sanyamk23 wants to merge 3 commits into
pallets:mainfrom
sanyamk23:fix/issue-2180-xrepo

Conversation

@sanyamk23

@sanyamk23 sanyamk23 commented Aug 31, 2026 •

Copy link
Copy Markdown

Fixes #2180

Python 3.14 raises a TypeError when an unhashable type (e.g. a dict) appears inside a tuple used as a dict key. The LRUCache in jinja2/utils.py uses a plain dict internally, and when a cache key contains an unhashable element, deque.remove() internally calls __hash__ on the key during the linear search, causing a crash.

This fix wraps each key in an _ImmutableKey class that uses object.__hash__ (identity-based hashing), sidestepping the issue entirely. The wrapper is transparent -- keys retrieved from the cache are unwrapped before being returned.

Before: TypeError: cannot use 'tuple' as a dict key (unhashable type: 'dict')
After: Cache works correctly with any key type

sanyamk23 added 3 commits September 1, 2026 00:08
Python 3.14 raises TypeError when deque.remove() calls __hash__ on a key
containing an unhashable type (e.g. dict inside tuple). Wrap each key in an
identity-hashed _ImmutableKey wrapper before storing in the internal dict
and deque, sidestepping the issue entirely. Keys retrieved from the cache
are unwrapped before being returned.

Also update test_pickleable and test_copy to use the public cache API
(.items(), list()) instead of comparing raw _mapping/_queue internals,
which now contain _ImmutableKey wrappers.
test_escaped used hasattr(value, '__html__') which always returns True
for ChainableUndefined since __getattr__ returns self, and self has
__html__. Fix by checking isinstance(value, Markup) instead.
The _ImmutableKey wrapper used identity comparison (is) and always
used object.__hash__, breaking equality for string keys created
fresh on each get_template() call. Fix by using value equality
(==) and try hash(key) first, falling back to identity hash only
for unhashable types.
@davidism

Copy link
Copy Markdown
Member

@davidism davidism closed this Aug 31, 2026
@davidism davidism changed the title fix: LRUCache TypeError on Python 3.14 with unhashable keys [rejected AI] LRUCache TypeError on Python 3.14 with unhashable keys Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeError: cannot use 'tuple' as a dict key in LRUCache on Python 3.14

2 participants