Merge branch 'master' of https://github.com/faerot/msgpack-python into pramukta-default_function_on_int_overflow

This commit is contained in:
INADA Naoki 2015-11-10 01:52:52 +09:00
commit e9a47cbd35
2 changed files with 52 additions and 20 deletions

View file

@ -601,6 +601,13 @@ class Packer(object):
Convert unicode to bytes with this encoding. (default: 'utf-8')
:param str unicode_errors:
Error handler for encoding unicode. (default: 'strict')
:param bool precise_mode:
If set to true, types will be checked to be exact. Derived classes
from serializeable types will not be serialized and will be
treated as unsupported type and forwarded to default.
Additionally tuples will not be serialized as lists.
This is useful when trying to implement accurate serialization
for python types.
:param bool use_single_float:
Use single precision float type for float. (default: False)
:param bool autoreset:
@ -611,7 +618,9 @@ class Packer(object):
It also enable str8 type for unicode.
"""
def __init__(self, default=None, encoding='utf-8', unicode_errors='strict',
use_single_float=False, autoreset=True, use_bin_type=False):
precise_mode=False, use_single_float=False, autoreset=True,
use_bin_type=False):
self._precise_mode = precise_mode
self._use_float = use_single_float
self._autoreset = autoreset
self._use_bin_type = use_bin_type
@ -623,18 +632,30 @@ class Packer(object):
raise TypeError("default must be callable")
self._default = default
def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, isinstance=isinstance):
def _check_precise(obj, t, type=type, tuple=tuple):
if type(t) is tuple:
return type(obj) in t
else:
return type(obj) is t
def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT,
check=isinstance, check_precise=_check_precise):
default_used = False
if self._precise_mode:
check = check_precise
list_types = list
else:
list_types = (list, tuple)
while True:
if nest_limit < 0:
raise PackValueError("recursion limit exceeded")
if obj is None:
return self._buffer.write(b"\xc0")
if isinstance(obj, bool):
if check(obj, bool):
if obj:
return self._buffer.write(b"\xc3")
return self._buffer.write(b"\xc2")
if isinstance(obj, int_types):
if check(obj, int_types):
if 0 <= obj < 0x80:
return self._buffer.write(struct.pack("B", obj))
if -0x20 <= obj < 0:
@ -660,7 +681,7 @@ class Packer(object):
default_used = True
continue
raise PackValueError("Integer value out of range")
if self._use_bin_type and isinstance(obj, bytes):
if self._use_bin_type and check(obj, bytes):
n = len(obj)
if n <= 0xff:
self._buffer.write(struct.pack('>BB', 0xc4, n))
@ -671,8 +692,8 @@ class Packer(object):
else:
raise PackValueError("Bytes is too large")
return self._buffer.write(obj)
if isinstance(obj, (Unicode, bytes)):
if isinstance(obj, Unicode):
if check(obj, (Unicode, bytes)):
if check(obj, Unicode):
if self._encoding is None:
raise TypeError(
"Can't encode unicode string: "
@ -690,11 +711,11 @@ class Packer(object):
else:
raise PackValueError("String is too large")
return self._buffer.write(obj)
if isinstance(obj, float):
if check(obj, float):
if self._use_float:
return self._buffer.write(struct.pack(">Bf", 0xca, obj))
return self._buffer.write(struct.pack(">Bd", 0xcb, obj))
if isinstance(obj, ExtType):
if check(obj, ExtType):
code = obj.code
data = obj.data
assert isinstance(code, int)
@ -719,13 +740,13 @@ class Packer(object):
self._buffer.write(struct.pack("b", code))
self._buffer.write(data)
return
if isinstance(obj, (list, tuple)):
if check(obj, list_types):
n = len(obj)
self._fb_pack_array_header(n)
for i in xrange(n):
self._pack(obj[i], nest_limit - 1)
return
if isinstance(obj, dict):
if check(obj, dict):
return self._fb_pack_map_pairs(len(obj), dict_iteritems(obj),
nest_limit - 1)
if not default_used and self._default is not None: