6
6
7
7
8
8
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
10
10
# StringBuilder is fastest.
11
11
from __pypy__ import newlist_hint
12
12
@@ -606,6 +606,9 @@ def tell(self):
606
606
return self ._stream_offset
607
607
608
608
609
+ _try_default = object ()
610
+
611
+
609
612
class Packer :
610
613
"""
611
614
MessagePack Packer
@@ -679,129 +682,113 @@ def __init__(
679
682
raise TypeError ("default must be callable" )
680
683
self ._default = default
681
684
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
+
682
770
def _pack (
683
771
self ,
684
772
obj ,
685
773
nest_limit = DEFAULT_RECURSE_LIMIT ,
686
- check = isinstance ,
687
- check_type_strict = _check_type_strict ,
688
774
):
689
- default_used = False
775
+ if nest_limit < 0 :
776
+ raise ValueError ("recursion limit exceeded" )
777
+ nest_limit -= 1
778
+
690
779
if self ._strict_types :
691
- check = check_type_strict
780
+ check = _check_type_strict
692
781
list_types = list
693
782
else :
783
+ check = isinstance
694
784
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" )
803
785
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
805
792
806
793
def pack (self , obj ):
807
794
try :
@@ -842,8 +829,8 @@ def pack_map_header(self, n):
842
829
def pack_ext_type (self , typecode , data ):
843
830
if not isinstance (typecode , int ):
844
831
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" )
847
834
if not isinstance (data , bytes ):
848
835
raise TypeError ("data must have bytes type" )
849
836
L = len (data )
@@ -865,7 +852,7 @@ def pack_ext_type(self, typecode, data):
865
852
self ._buffer .write (b"\xc8 " + struct .pack (">H" , L ))
866
853
else :
867
854
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 ))
869
856
self ._buffer .write (data )
870
857
871
858
def _pack_array_header (self , n ):
0 commit comments