Skip to content

Commit 51428c4

Browse files
authored
fallback: pass object_pairs_hook a list of pairs (#744)
1 parent 742cb6d commit 51428c4

2 files changed

Lines changed: 21 additions & 9 deletions

File tree

‎msgpack/fallback.py‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -529,15 +529,15 @@ def _unpack(self, execute=EX_CONSTRUCT):
529529
self._unpack(EX_SKIP)
530530
return
531531
if self._object_pairs_hook is not None:
532-
533-
def _gen():
534-
for _ in range(n):
535-
key = self._unpack(EX_CONSTRUCT)
536-
if self._strict_map_key and type(key) not in (str, bytes):
537-
raise ValueError("%s is not allowed for map key" % str(type(key)))
538-
yield key, self._unpack(EX_CONSTRUCT)
539-
540-
ret = self._object_pairs_hook(_gen())
532+
# Pass a list, as the C extension does, so the whole map is
533+
# consumed even if the hook does not iterate it.
534+
pairs = []
535+
for _ in range(n):
536+
key = self._unpack(EX_CONSTRUCT)
537+
if self._strict_map_key and type(key) not in (str, bytes):
538+
raise ValueError("%s is not allowed for map key" % str(type(key)))
539+
pairs.append((key, self._unpack(EX_CONSTRUCT)))
540+
ret = self._object_pairs_hook(pairs)
541541
else:
542542
ret = {}
543543
for _ in range(n):

‎test/test_obj.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ def test_decode_pairs_hook():
4141
assert unpacked[1] == prod_sum
4242

4343

44+
def test_decode_pairs_hook_receives_list():
45+
def reject_duplicate_keys(pairs):
46+
keys = [k for k, _ in pairs]
47+
assert len(keys) == len(set(keys))
48+
return dict(pairs)
49+
50+
packed = packb([{"a": 1, "b": 2}, 3])
51+
assert unpackb(packed, object_pairs_hook=reject_duplicate_keys) == [{"a": 1, "b": 2}, 3]
52+
assert unpackb(packed, object_pairs_hook=lambda pairs: pairs[0]) == [("a", 1), 3]
53+
assert unpackb(packed, object_pairs_hook=lambda pairs: None) == [None, 3]
54+
55+
4456
def test_only_one_obj_hook():
4557
with raises(TypeError):
4658
unpackb(b"", object_hook=lambda x: x, object_pairs_hook=lambda x: x)

0 commit comments

Comments
 (0)