fix: enforce strict_map_key with object_pairs_hook (#673)

This PR makes it so that `self._strict_map_key` is enforced even when
using `_object_pairs_hook` which didn't use to be the case.
This commit is contained in:
Thomas Kowalski 2026-05-12 06:59:40 +02:00 committed by GitHub
parent 0d600a3328
commit cd8137093a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 3 deletions

View file

@ -518,9 +518,15 @@ class Unpacker:
self._unpack(EX_SKIP)
return
if self._object_pairs_hook is not None:
ret = self._object_pairs_hook(
(self._unpack(EX_CONSTRUCT), self._unpack(EX_CONSTRUCT)) for _ in range(n)
)
def _gen():
for _ in range(n):
key = self._unpack(EX_CONSTRUCT)
if self._strict_map_key and type(key) not in (str, bytes):
raise ValueError("%s is not allowed for map key" % str(type(key)))
yield key, self._unpack(EX_CONSTRUCT)
ret = self._object_pairs_hook(_gen())
else:
ret = {}
for _ in range(n):

View file

@ -89,3 +89,17 @@ def test_strict_map_key():
packed = packb(invalid, use_bin_type=True)
with raises(ValueError):
unpackb(packed, raw=False, strict_map_key=True)
def test_strict_map_key_with_object_pairs_hook():
# strict_map_key should be enforced even when object_pairs_hook is set
invalid = {42: "value"}
packed = packb(invalid, use_bin_type=True)
with raises(ValueError):
unpackb(packed, raw=False, strict_map_key=True, object_pairs_hook=list)
# valid keys (str/bytes) should still work with object_pairs_hook
valid = {"key": "value"}
packed = packb(valid, use_bin_type=True)
result = unpackb(packed, raw=False, strict_map_key=True, object_pairs_hook=list)
assert result == [("key", "value")]