@@ -89,9 +89,15 @@ cdef class Packer(object):
8989 Additionally tuples will not be serialized as lists.
9090 This is useful when trying to implement accurate serialization
9191 for python types.
92+
93+ :param str unicode_errors:
94+ The error handler for encoding unicode. (default: 'strict')
95+ DO NOT USE THIS!! This option is kept for very specific usage.
9296 """
9397 cdef msgpack_packer pk
9498 cdef object _default
99+ cdef object _berrors
100+ cdef const char * unicode_errors
95101 cdef bint strict_types
96102 cdef bool use_float
97103 cdef bint autoreset
@@ -104,10 +110,8 @@ cdef class Packer(object):
104110 self .pk.buf_size = buf_size
105111 self .pk.length = 0
106112
107- def __init__ (self , default = None ,
108- bint use_single_float = False ,
109- bint autoreset = True ,
110- bint use_bin_type = False ,
113+ def __init__ (self , *, default = None , unicode_errors = None ,
114+ bint use_single_float = False , bint autoreset = True , bint use_bin_type = False ,
111115 bint strict_types = False ):
112116 self .use_float = use_single_float
113117 self .strict_types = strict_types
@@ -118,6 +122,12 @@ cdef class Packer(object):
118122 raise TypeError (" default must be a callable." )
119123 self ._default = default
120124
125+ self ._berrors = unicode_errors
126+ if unicode_errors is None :
127+ self .unicode_errors = NULL
128+ else :
129+ self .unicode_errors = self ._berrors
130+
121131 def __dealloc__ (self ):
122132 PyMem_Free(self .pk.buf)
123133 self .pk.buf = NULL
@@ -183,9 +193,19 @@ cdef class Packer(object):
183193 if ret == 0 :
184194 ret = msgpack_pack_raw_body(& self .pk, rawval, L)
185195 elif PyUnicode_CheckExact(o) if strict_types else PyUnicode_Check(o):
186- ret = msgpack_pack_unicode(& self .pk, o, ITEM_LIMIT);
187- if ret == - 2 :
188- raise ValueError (" unicode string is too large" )
196+ if self .unicode_errors == NULL :
197+ ret = msgpack_pack_unicode(& self .pk, o, ITEM_LIMIT);
198+ if ret == - 2 :
199+ raise ValueError (" unicode string is too large" )
200+ else :
201+ o = PyUnicode_AsEncodedString(o, NULL , self .unicode_errors)
202+ L = Py_SIZE(o)
203+ if L > ITEM_LIMIT:
204+ raise ValueError (" unicode string is too large" )
205+ ret = msgpack_pack_raw(& self .pk, L)
206+ if ret == 0 :
207+ rawval = o
208+ ret = msgpack_pack_raw_body(& self .pk, rawval, L)
189209 elif PyDict_CheckExact(o):
190210 d = < dict > o
191211 L = len (d)
0 commit comments