jcrist · GitHub

@worksbyfriday

In Python 3.14, CPython added hash caching to tuples (gh-131525).
PyTupleObject gained an ob_hash field that is checked by tuple_hash()
before computing: if ob_hash != -1, the cached value is returned
immediately.
When msgspec allocates NamedTuples via tp_alloc (which zero-initializes
memory via calloc), ob_hash is set to 0 — a valid cached hash value.
This causes hash() to return 0 for all msgspec-deserialized NamedTuples,
breaking their use as dictionary keys and in sets.
The fix resets ob_hash to -1 ("not yet computed") immediately after
tp_alloc in all three NamedTuple construction sites: msgpack decoder,
JSON decoder, and convert. The reset is conditional on PY314_PLUS and
compiles to a no-op on earlier Python versions.
Fixes msgspec#967

Read the original on github.com ↗