diff --git a/msgpack/fallback.py b/msgpack/fallback.py index b02e47cf..8fcc1d7e 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -529,6 +529,8 @@ def _unpack(self, execute=EX_CONSTRUCT): raise ValueError("%s is not allowed for map key" % str(type(key))) if isinstance(key, str): key = sys.intern(key) + elif type(key) is list: + key = tuple(key) ret[key] = self._unpack(EX_CONSTRUCT) if self._object_hook is not None: ret = self._object_hook(ret) diff --git a/msgpack/unpack.h b/msgpack/unpack.h index 58a2f4f5..28a0b049 100644 --- a/msgpack/unpack.h +++ b/msgpack/unpack.h @@ -198,6 +198,24 @@ static inline int unpack_callback_map_item(unpack_user* u, unsigned int current, } if (PyUnicode_CheckExact(k)) { PyUnicode_InternInPlace(&k); + } else if (PyList_CheckExact(k)) { + Py_ssize_t list_size = PyList_Size(k); + PyObject* tuple = PyTuple_New(list_size); + + if (tuple == NULL) { + return -1; + } + + for (Py_ssize_t i = 0; i < list_size; i++) { + PyObject* item = PyList_GetItem(k, i); + Py_INCREF(item); + if (PyTuple_SetItem(tuple, i, item) != 0) { + Py_DECREF(tuple); + return -1; + } + } + Py_DECREF(k); + k = tuple; } if (u->has_pairs_hook) { msgpack_unpack_object item = PyTuple_Pack(2, k, v); diff --git a/test/test_case.py b/test/test_case.py index c4c615e3..a85634ca 100644 --- a/test/test_case.py +++ b/test/test_case.py @@ -134,3 +134,7 @@ def test_match(): def test_unicode(): assert unpackb(packb("foobar"), use_list=1) == "foobar" + + +def test_dict_tuple_key(): + unpackb(packb({(1, 2): 3}), strict_map_key=False)