Skip to content

Commit 5fd803a

Browse files
committedMay 5, 2024
cleanup fallback
1 parent e0f0e14 commit 5fd803a

File tree

1 file changed

+104
-117
lines changed

1 file changed

+104
-117
lines changed
 

‎msgpack/fallback.py

+104-117
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77

88
if hasattr(sys, "pypy_version_info"):
9-
# StringIO is slow on PyPy, StringIO is faster. However: PyPy's own
9+
# cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own
1010
# StringBuilder is fastest.
1111
from __pypy__ import newlist_hint
1212

@@ -606,6 +606,9 @@ def tell(self):
606606
return self._stream_offset
607607

608608

609+
_try_default = object()
610+
611+
609612
class Packer:
610613
"""
611614
MessagePack Packer
@@ -679,129 +682,113 @@ def __init__(
679682
raise TypeError("default must be callable")
680683
self._default = default
681684

685+
def _pack_inner(self, obj, check, list_types, will_default, nest_limit):
686+
if obj is None:
687+
return self._buffer.write(b"\xc0")
688+
if check(obj, bool):
689+
if obj:
690+
return self._buffer.write(b"\xc3")
691+
return self._buffer.write(b"\xc2")
692+
if check(obj, int):
693+
if 0 <= obj < 0x80:
694+
return self._buffer.write(struct.pack("B", obj))
695+
if -0x20 <= obj < 0:
696+
return self._buffer.write(struct.pack("b", obj))
697+
if 0x80 <= obj <= 0xFF:
698+
return self._buffer.write(struct.pack("BB", 0xCC, obj))
699+
if -0x80 <= obj < 0:
700+
return self._buffer.write(struct.pack(">Bb", 0xD0, obj))
701+
if 0xFF < obj <= 0xFFFF:
702+
return self._buffer.write(struct.pack(">BH", 0xCD, obj))
703+
if -0x8000 <= obj < -0x80:
704+
return self._buffer.write(struct.pack(">Bh", 0xD1, obj))
705+
if 0xFFFF < obj <= 0xFFFFFFFF:
706+
return self._buffer.write(struct.pack(">BI", 0xCE, obj))
707+
if -0x80000000 <= obj < -0x8000:
708+
return self._buffer.write(struct.pack(">Bi", 0xD2, obj))
709+
if 0xFFFFFFFF < obj <= 0xFFFFFFFFFFFFFFFF:
710+
return self._buffer.write(struct.pack(">BQ", 0xCF, obj))
711+
if -0x8000000000000000 <= obj < -0x80000000:
712+
return self._buffer.write(struct.pack(">Bq", 0xD3, obj))
713+
if will_default:
714+
return _try_default
715+
raise OverflowError("Integer value out of range")
716+
if check(obj, (bytes, bytearray)):
717+
n = len(obj)
718+
if n >= 2**32:
719+
raise ValueError("%s is too large" % type(obj).__name__)
720+
self._pack_bin_header(n)
721+
return self._buffer.write(obj)
722+
if check(obj, str):
723+
obj = obj.encode("utf-8", self._unicode_errors)
724+
n = len(obj)
725+
if n >= 2**32:
726+
raise ValueError("String is too large")
727+
self._pack_raw_header(n)
728+
return self._buffer.write(obj)
729+
if check(obj, memoryview):
730+
n = obj.nbytes
731+
if n >= 2**32:
732+
raise ValueError("Memoryview is too large")
733+
self._pack_bin_header(n)
734+
return self._buffer.write(obj)
735+
if check(obj, float):
736+
if self._use_float:
737+
return self._buffer.write(struct.pack(">Bf", 0xCA, obj))
738+
return self._buffer.write(struct.pack(">Bd", 0xCB, obj))
739+
if check(obj, (ExtType, Timestamp)):
740+
if check(obj, Timestamp):
741+
code = -1
742+
data = obj.to_bytes()
743+
else:
744+
code = obj.code
745+
data = obj.data
746+
self.pack_ext_type(code, data)
747+
return
748+
if check(obj, list_types):
749+
n = len(obj)
750+
self._pack_array_header(n)
751+
for i in range(n):
752+
self._pack(obj[i], nest_limit)
753+
return
754+
if check(obj, dict):
755+
return self._pack_map_pairs(len(obj), obj.items(), nest_limit)
756+
757+
if self._datetime and check(obj, _DateTime) and obj.tzinfo is not None:
758+
obj = Timestamp.from_datetime(obj)
759+
self.pack_ext_type(-1, obj.to_bytes())
760+
return
761+
762+
if will_default:
763+
return _try_default
764+
765+
if self._datetime and check(obj, _DateTime):
766+
raise ValueError(f"Cannot serialize {obj!r} where tzinfo=None")
767+
768+
raise TypeError(f"Cannot serialize {obj!r}")
769+
682770
def _pack(
683771
self,
684772
obj,
685773
nest_limit=DEFAULT_RECURSE_LIMIT,
686-
check=isinstance,
687-
check_type_strict=_check_type_strict,
688774
):
689-
default_used = False
775+
if nest_limit < 0:
776+
raise ValueError("recursion limit exceeded")
777+
nest_limit -= 1
778+
690779
if self._strict_types:
691-
check = check_type_strict
780+
check = _check_type_strict
692781
list_types = list
693782
else:
783+
check = isinstance
694784
list_types = (list, tuple)
695-
while True:
696-
if nest_limit < 0:
697-
raise ValueError("recursion limit exceeded")
698-
if obj is None:
699-
return self._buffer.write(b"\xc0")
700-
if check(obj, bool):
701-
if obj:
702-
return self._buffer.write(b"\xc3")
703-
return self._buffer.write(b"\xc2")
704-
if check(obj, int):
705-
if 0 <= obj < 0x80:
706-
return self._buffer.write(struct.pack("B", obj))
707-
if -0x20 <= obj < 0:
708-
return self._buffer.write(struct.pack("b", obj))
709-
if 0x80 <= obj <= 0xFF:
710-
return self._buffer.write(struct.pack("BB", 0xCC, obj))
711-
if -0x80 <= obj < 0:
712-
return self._buffer.write(struct.pack(">Bb", 0xD0, obj))
713-
if 0xFF < obj <= 0xFFFF:
714-
return self._buffer.write(struct.pack(">BH", 0xCD, obj))
715-
if -0x8000 <= obj < -0x80:
716-
return self._buffer.write(struct.pack(">Bh", 0xD1, obj))
717-
if 0xFFFF < obj <= 0xFFFFFFFF:
718-
return self._buffer.write(struct.pack(">BI", 0xCE, obj))
719-
if -0x80000000 <= obj < -0x8000:
720-
return self._buffer.write(struct.pack(">Bi", 0xD2, obj))
721-
if 0xFFFFFFFF < obj <= 0xFFFFFFFFFFFFFFFF:
722-
return self._buffer.write(struct.pack(">BQ", 0xCF, obj))
723-
if -0x8000000000000000 <= obj < -0x80000000:
724-
return self._buffer.write(struct.pack(">Bq", 0xD3, obj))
725-
if not default_used and self._default is not None:
726-
obj = self._default(obj)
727-
default_used = True
728-
continue
729-
raise OverflowError("Integer value out of range")
730-
if check(obj, (bytes, bytearray)):
731-
n = len(obj)
732-
if n >= 2**32:
733-
raise ValueError("%s is too large" % type(obj).__name__)
734-
self._pack_bin_header(n)
735-
return self._buffer.write(obj)
736-
if check(obj, str):
737-
obj = obj.encode("utf-8", self._unicode_errors)
738-
n = len(obj)
739-
if n >= 2**32:
740-
raise ValueError("String is too large")
741-
self._pack_raw_header(n)
742-
return self._buffer.write(obj)
743-
if check(obj, memoryview):
744-
n = obj.nbytes
745-
if n >= 2**32:
746-
raise ValueError("Memoryview is too large")
747-
self._pack_bin_header(n)
748-
return self._buffer.write(obj)
749-
if check(obj, float):
750-
if self._use_float:
751-
return self._buffer.write(struct.pack(">Bf", 0xCA, obj))
752-
return self._buffer.write(struct.pack(">Bd", 0xCB, obj))
753-
if check(obj, (ExtType, Timestamp)):
754-
if check(obj, Timestamp):
755-
code = -1
756-
data = obj.to_bytes()
757-
else:
758-
code = obj.code
759-
data = obj.data
760-
assert isinstance(code, int)
761-
assert isinstance(data, bytes)
762-
L = len(data)
763-
if L == 1:
764-
self._buffer.write(b"\xd4")
765-
elif L == 2:
766-
self._buffer.write(b"\xd5")
767-
elif L == 4:
768-
self._buffer.write(b"\xd6")
769-
elif L == 8:
770-
self._buffer.write(b"\xd7")
771-
elif L == 16:
772-
self._buffer.write(b"\xd8")
773-
elif L <= 0xFF:
774-
self._buffer.write(struct.pack(">BB", 0xC7, L))
775-
elif L <= 0xFFFF:
776-
self._buffer.write(struct.pack(">BH", 0xC8, L))
777-
else:
778-
self._buffer.write(struct.pack(">BI", 0xC9, L))
779-
self._buffer.write(struct.pack("b", code))
780-
self._buffer.write(data)
781-
return
782-
if check(obj, list_types):
783-
n = len(obj)
784-
self._pack_array_header(n)
785-
for i in range(n):
786-
self._pack(obj[i], nest_limit - 1)
787-
return
788-
if check(obj, dict):
789-
return self._pack_map_pairs(len(obj), obj.items(), nest_limit - 1)
790-
791-
if self._datetime and check(obj, _DateTime) and obj.tzinfo is not None:
792-
obj = Timestamp.from_datetime(obj)
793-
default_used = 1
794-
continue
795-
796-
if not default_used and self._default is not None:
797-
obj = self._default(obj)
798-
default_used = 1
799-
continue
800-
801-
if self._datetime and check(obj, _DateTime):
802-
raise ValueError(f"Cannot serialize {obj!r} where tzinfo=None")
803785

804-
raise TypeError(f"Cannot serialize {obj!r}")
786+
will_default = bool(self._default)
787+
result = self._pack_inner(obj, check, list_types, will_default, nest_limit)
788+
if will_default and result is _try_default:
789+
obj = self._default(obj)
790+
result = self._pack_inner(obj, check, list_types, False, nest_limit)
791+
return result
805792

806793
def pack(self, obj):
807794
try:
@@ -842,8 +829,8 @@ def pack_map_header(self, n):
842829
def pack_ext_type(self, typecode, data):
843830
if not isinstance(typecode, int):
844831
raise TypeError("typecode must have int type.")
845-
if not 0 <= typecode <= 127:
846-
raise ValueError("typecode should be 0-127")
832+
if not -128 <= typecode <= 127:
833+
raise ValueError("typecode should be >=-128, <=127")
847834
if not isinstance(data, bytes):
848835
raise TypeError("data must have bytes type")
849836
L = len(data)
@@ -865,7 +852,7 @@ def pack_ext_type(self, typecode, data):
865852
self._buffer.write(b"\xc8" + struct.pack(">H", L))
866853
else:
867854
self._buffer.write(b"\xc9" + struct.pack(">I", L))
868-
self._buffer.write(struct.pack("B", typecode))
855+
self._buffer.write(struct.pack("b", typecode))
869856
self._buffer.write(data)
870857

871858
def _pack_array_header(self, n):

0 commit comments

Comments
 (0)