diff --git a/msgpack/fallback.py b/msgpack/fallback.py index 0cbd8733..5d41f766 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -521,10 +521,11 @@ def _unpack(self, execute=EX_CONSTRUCT): ret = newlist_hint(n) for i in range(n): ret.append(self._unpack(EX_CONSTRUCT)) + if not self._use_list: + ret = tuple(ret) if self._list_hook is not None: ret = self._list_hook(ret) - # TODO is the interaction between `list_hook` and `use_list` ok? - return ret if self._use_list else tuple(ret) + return ret if typ == TYPE_MAP: if execute == EX_SKIP: for i in range(n): diff --git a/test/test_obj.py b/test/test_obj.py index 1866bc67..2ea97d86 100644 --- a/test/test_obj.py +++ b/test/test_obj.py @@ -1,8 +1,10 @@ #!/usr/bin/env python +from io import BytesIO + from pytest import raises -from msgpack import packb, unpackb +from msgpack import Unpacker, packb, unpackb def _decode_complex(obj): @@ -74,6 +76,29 @@ def test_array_hook(): assert unpacked == "123" +def test_array_hook_with_use_list_false(): + seen = [] + + def hook(items): + seen.append(items) + return {"items": items} + + packed = packb([1, 2]) + expected = {"items": (1, 2)} + assert unpackb(packed, use_list=False, list_hook=hook) == expected + + stream = packed + packb(3) + unpackers = [ + Unpacker(use_list=False, list_hook=hook), + Unpacker(BytesIO(stream), use_list=False, list_hook=hook), + ] + unpackers[0].feed(stream) + for unpacker in unpackers: + assert unpacker.unpack() == expected + assert unpacker.unpack() == 3 + assert seen == [(1, 2)] * 3 + + class DecodeError(Exception): pass