Skip to content

Commit cd81370

Browse files
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.
1 parent 0d600a3 commit cd81370

2 files changed

Lines changed: 23 additions & 3 deletions

File tree

msgpack/fallback.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,15 @@ def _unpack(self, execute=EX_CONSTRUCT):
518518
self._unpack(EX_SKIP)
519519
return
520520
if self._object_pairs_hook is not None:
521-
ret = self._object_pairs_hook(
522-
(self._unpack(EX_CONSTRUCT), self._unpack(EX_CONSTRUCT)) for _ in range(n)
523-
)
521+
522+
def _gen():
523+
for _ in range(n):
524+
key = self._unpack(EX_CONSTRUCT)
525+
if self._strict_map_key and type(key) not in (str, bytes):
526+
raise ValueError("%s is not allowed for map key" % str(type(key)))
527+
yield key, self._unpack(EX_CONSTRUCT)
528+
529+
ret = self._object_pairs_hook(_gen())
524530
else:
525531
ret = {}
526532
for _ in range(n):

test/test_except.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,17 @@ def test_strict_map_key():
8989
packed = packb(invalid, use_bin_type=True)
9090
with raises(ValueError):
9191
unpackb(packed, raw=False, strict_map_key=True)
92+
93+
94+
def test_strict_map_key_with_object_pairs_hook():
95+
# strict_map_key should be enforced even when object_pairs_hook is set
96+
invalid = {42: "value"}
97+
packed = packb(invalid, use_bin_type=True)
98+
with raises(ValueError):
99+
unpackb(packed, raw=False, strict_map_key=True, object_pairs_hook=list)
100+
101+
# valid keys (str/bytes) should still work with object_pairs_hook
102+
valid = {"key": "value"}
103+
packed = packb(valid, use_bin_type=True)
104+
result = unpackb(packed, raw=False, strict_map_key=True, object_pairs_hook=list)
105+
assert result == [("key", "value")]

0 commit comments

Comments
 (0)