Skip to content

Commit 3b933f0

Browse files
committed
added distinguish_tuple argument to Packer
This will make precise python types serialization possible.
1 parent 61bac2f commit 3b933f0

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

msgpack/_packer.pyx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ cdef class Packer(object):
5656
Convert unicode to bytes with this encoding. (default: 'utf-8')
5757
:param str unicode_errors:
5858
Error handler for encoding unicode. (default: 'strict')
59+
:param bool distinguish_tuple:
60+
If set to true, tuples will not be serialized as lists
61+
and will be treated as unsupported type. This is useful when trying
62+
to implement accurate serialization for python types.
5963
:param bool use_single_float:
6064
Use single precision float type for float. (default: False)
6165
:param bool autoreset:
@@ -71,6 +75,7 @@ cdef class Packer(object):
7175
cdef object _berrors
7276
cdef char *encoding
7377
cdef char *unicode_errors
78+
cdef bool distinguish_tuple
7479
cdef bool use_float
7580
cdef bint autoreset
7681

@@ -83,10 +88,12 @@ cdef class Packer(object):
8388
self.pk.length = 0
8489

8590
def __init__(self, default=None, encoding='utf-8', unicode_errors='strict',
86-
use_single_float=False, bint autoreset=1, bint use_bin_type=0):
91+
distinguish_tuple=False, use_single_float=False, bint autoreset=1,
92+
bint use_bin_type=0):
8793
"""
8894
"""
8995
self.use_float = use_single_float
96+
self.distinguish_tuple = distinguish_tuple
9097
self.autoreset = autoreset
9198
self.pk.use_bin_type = use_bin_type
9299
if default is not None:
@@ -122,6 +129,7 @@ cdef class Packer(object):
122129
cdef dict d
123130
cdef size_t L
124131
cdef int default_used = 0
132+
cdef bool distinguish_tuple = self.distinguish_tuple
125133

126134
if nest_limit < 0:
127135
raise PackValueError("recursion limit exceeded.")
@@ -204,7 +212,7 @@ cdef class Packer(object):
204212
raise ValueError("EXT data is too large")
205213
ret = msgpack_pack_ext(&self.pk, longval, L)
206214
ret = msgpack_pack_raw_body(&self.pk, rawval, L)
207-
elif PyTuple_Check(o) or PyList_Check(o):
215+
elif (PyTuple_Check(o) and not distinguish_tuple) or PyList_Check(o):
208216
L = len(o)
209217
if L > (2**32)-1:
210218
raise ValueError("list is too large")

msgpack/fallback.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,10 @@ class Packer(object):
485485
Convert unicode to bytes with this encoding. (default: 'utf-8')
486486
:param str unicode_errors:
487487
Error handler for encoding unicode. (default: 'strict')
488+
:param bool distinguish_tuple:
489+
If set to true, tuples will not be serialized as lists
490+
and will be treated as unsupported type. This is useful when trying
491+
to implement accurate serialization for python types.
488492
:param bool use_single_float:
489493
Use single precision float type for float. (default: False)
490494
:param bool autoreset:
@@ -495,7 +499,9 @@ class Packer(object):
495499
It also enable str8 type for unicode.
496500
"""
497501
def __init__(self, default=None, encoding='utf-8', unicode_errors='strict',
498-
use_single_float=False, autoreset=True, use_bin_type=False):
502+
distinguish_tuple=False, use_single_float=False, autoreset=True,
503+
use_bin_type=False):
504+
self._distinguish_tuple = distinguish_tuple
499505
self._use_float = use_single_float
500506
self._autoreset = autoreset
501507
self._use_bin_type = use_bin_type
@@ -509,6 +515,7 @@ def __init__(self, default=None, encoding='utf-8', unicode_errors='strict',
509515

510516
def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, isinstance=isinstance):
511517
default_used = False
518+
list_type = list if self._distinguish_tuple else (list, tuple)
512519
while True:
513520
if nest_limit < 0:
514521
raise PackValueError("recursion limit exceeded")
@@ -599,7 +606,7 @@ def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, isinstance=isinstance):
599606
self._buffer.write(struct.pack("b", code))
600607
self._buffer.write(data)
601608
return
602-
if isinstance(obj, (list, tuple)):
609+
if isinstance(obj, list_type):
603610
n = len(obj)
604611
self._fb_pack_array_header(n)
605612
for i in xrange(n):

0 commit comments

Comments
 (0)