blob: 0cdc83e367d80bc4bbe14fbfa994c28438ca0cbc [file] [log] [blame]
Ved-vampir2c2f2e92015-03-18 18:02:25 +03001# u-msgpack-python v2.0 - vsergeev at gmail
2# https://github.com/vsergeev/u-msgpack-python
3#
4# u-msgpack-python is a lightweight MessagePack serializer and deserializer
5# module, compatible with both Python 2 and 3, as well CPython and PyPy
6# implementations of Python. u-msgpack-python is fully compliant with the
7# latest MessagePack specification.com/msgpack/msgpack/blob/master/spec.md). In
8# particular, it supports the new binary, UTF-8 string, and application ext
9# types.
10#
11# MIT License
12#
13# Copyright (c) 2013-2014 Ivan A. Sergeev
14#
15# Permission is hereby granted, free of charge, to any person obtaining a copy
16# of this software and associated documentation files (the "Software"), to deal
17# in the Software without restriction, including without limitation the rights
18# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19# copies of the Software, and to permit persons to whom the Software is
20# furnished to do so, subject to the following conditions:
21#
22# The above copyright notice and this permission notice shall be included in
23# all copies or substantial portions of the Software.
24#
25# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31# THE SOFTWARE.
32#
33"""
34u-msgpack-python v2.0 - vsergeev at gmail
35https://github.com/vsergeev/u-msgpack-python
36
37u-msgpack-python is a lightweight MessagePack serializer and deserializer
38module, compatible with both Python 2 and 3, as well CPython and PyPy
39implementations of Python. u-msgpack-python is fully compliant with the
40latest MessagePack specification.com/msgpack/msgpack/blob/master/spec.md). In
41particular, it supports the new binary, UTF-8 string, and application ext
42types.
43
44License: MIT
45"""
46
47__version__ = "2.0"
48"Module version string"
49
50version = (2,0)
51"Module version tuple"
52
53import struct
54import collections
55import sys
56import io
57
58################################################################################
59### Ext Class
60################################################################################
61
62# Extension type for application-defined types and data
63class Ext:
64 """
65 The Ext class facilitates creating a serializable extension object to store
66 an application-defined type and data byte array.
67 """
68
69 def __init__(self, type, data):
70 """
71 Construct a new Ext object.
72
73 Args:
74 type: application-defined type integer from 0 to 127
75 data: application-defined data byte array
76
77 Raises:
78 TypeError:
79 Specified ext type is outside of 0 to 127 range.
80
81 Example:
82 >>> foo = umsgpack.Ext(0x05, b"\x01\x02\x03")
83 >>> umsgpack.packb({u"special stuff": foo, u"awesome": True})
84 '\x82\xa7awesome\xc3\xadspecial stuff\xc7\x03\x05\x01\x02\x03'
85 >>> bar = umsgpack.unpackb(_)
86 >>> print(bar["special stuff"])
87 Ext Object (Type: 0x05, Data: 01 02 03)
88 >>>
89 """
90 # Application ext type should be 0 <= type <= 127
91 if not isinstance(type, int) or not (type >= 0 and type <= 127):
92 raise TypeError("ext type out of range")
93 # Check data is type bytes
94 elif sys.version_info[0] == 3 and not isinstance(data, bytes):
95 raise TypeError("ext data is not type \'bytes\'")
96 elif sys.version_info[0] == 2 and not isinstance(data, str):
97 raise TypeError("ext data is not type \'str\'")
98 self.type = type
99 self.data = data
100
101 def __eq__(self, other):
102 """
103 Compare this Ext object with another for equality.
104 """
105 return (isinstance(other, self.__class__) and
106 self.type == other.type and
107 self.data == other.data)
108
109 def __ne__(self, other):
110 """
111 Compare this Ext object with another for inequality.
112 """
113 return not self.__eq__(other)
114
115 def __str__(self):
116 """
117 String representation of this Ext object.
118 """
119 s = "Ext Object (Type: 0x%02x, Data: " % self.type
120 for i in range(min(len(self.data), 8)):
121 if i > 0:
122 s += " "
123 if isinstance(self.data[i], int):
124 s += "%02x" % (self.data[i])
125 else:
126 s += "%02x" % ord(self.data[i])
127 if len(self.data) > 8:
128 s += " ..."
129 s += ")"
130 return s
131
132################################################################################
133### Exceptions
134################################################################################
135
136# Base Exception classes
137class PackException(Exception):
138 "Base class for exceptions encountered during packing."
139 pass
140class UnpackException(Exception):
141 "Base class for exceptions encountered during unpacking."
142 pass
143
144# Packing error
145class UnsupportedTypeException(PackException):
146 "Object type not supported for packing."
147 pass
148
149# Unpacking error
150class InsufficientDataException(UnpackException):
151 "Insufficient data to unpack the encoded object."
152 pass
153class InvalidStringException(UnpackException):
154 "Invalid UTF-8 string encountered during unpacking."
155 pass
156class ReservedCodeException(UnpackException):
157 "Reserved code encountered during unpacking."
158 pass
159class UnhashableKeyException(UnpackException):
160 """
161 Unhashable key encountered during map unpacking.
162 The serialized map cannot be deserialized into a Python dictionary.
163 """
164 pass
165class DuplicateKeyException(UnpackException):
166 "Duplicate key encountered during map unpacking."
167 pass
168
169# Backwards compatibility
170KeyNotPrimitiveException = UnhashableKeyException
171KeyDuplicateException = DuplicateKeyException
172
173################################################################################
174### Exported Functions and Globals
175################################################################################
176
177# Exported functions and variables, set up in __init()
178pack = None
179packb = None
180unpack = None
181unpackb = None
182dump = None
183dumps = None
184load = None
185loads = None
186
187compatibility = False
188"""
189Compatibility mode boolean.
190
191When compatibility mode is enabled, u-msgpack-python will serialize both
192unicode strings and bytes into the old "raw" msgpack type, and deserialize the
193"raw" msgpack type into bytes. This provides backwards compatibility with the
194old MessagePack specification.
195
196Example:
197>>> umsgpack.compatibility = True
198>>>
199>>> umsgpack.packb([u"some string", b"some bytes"])
200b'\x92\xabsome string\xaasome bytes'
201>>> umsgpack.unpackb(_)
202[b'some string', b'some bytes']
203>>>
204"""
205
206################################################################################
207### Packing
208################################################################################
209
210# You may notice struct.pack("B", obj) instead of the simpler chr(obj) in the
211# code below. This is to allow for seamless Python 2 and 3 compatibility, as
212# chr(obj) has a str return type instead of bytes in Python 3, and
213# struct.pack(...) has the right return type in both versions.
214
215def _pack_integer(obj, fp):
216 if obj < 0:
217 if obj >= -32:
218 fp.write(struct.pack("b", obj))
219 elif obj >= -2**(8-1):
220 fp.write(b"\xd0" + struct.pack("b", obj))
221 elif obj >= -2**(16-1):
222 fp.write(b"\xd1" + struct.pack(">h", obj))
223 elif obj >= -2**(32-1):
224 fp.write(b"\xd2" + struct.pack(">i", obj))
225 elif obj >= -2**(64-1):
226 fp.write(b"\xd3" + struct.pack(">q", obj))
227 else:
228 raise UnsupportedTypeException("huge signed int")
229 else:
230 if obj <= 127:
231 fp.write(struct.pack("B", obj))
232 elif obj <= 2**8-1:
233 fp.write(b"\xcc" + struct.pack("B", obj))
234 elif obj <= 2**16-1:
235 fp.write(b"\xcd" + struct.pack(">H", obj))
236 elif obj <= 2**32-1:
237 fp.write(b"\xce" + struct.pack(">I", obj))
238 elif obj <= 2**64-1:
239 fp.write(b"\xcf" + struct.pack(">Q", obj))
240 else:
241 raise UnsupportedTypeException("huge unsigned int")
242
243def _pack_nil(obj, fp):
244 fp.write(b"\xc0")
245
246def _pack_boolean(obj, fp):
247 fp.write(b"\xc3" if obj else b"\xc2")
248
249def _pack_float(obj, fp):
250 if _float_size == 64:
251 fp.write(b"\xcb" + struct.pack(">d", obj))
252 else:
253 fp.write(b"\xca" + struct.pack(">f", obj))
254
255def _pack_string(obj, fp):
256 obj = obj.encode('utf-8')
257 if len(obj) <= 31:
258 fp.write(struct.pack("B", 0xa0 | len(obj)) + obj)
259 elif len(obj) <= 2**8-1:
260 fp.write(b"\xd9" + struct.pack("B", len(obj)) + obj)
261 elif len(obj) <= 2**16-1:
262 fp.write(b"\xda" + struct.pack(">H", len(obj)) + obj)
263 elif len(obj) <= 2**32-1:
264 fp.write(b"\xdb" + struct.pack(">I", len(obj)) + obj)
265 else:
266 raise UnsupportedTypeException("huge string")
267
268def _pack_binary(obj, fp):
269 if len(obj) <= 2**8-1:
270 fp.write(b"\xc4" + struct.pack("B", len(obj)) + obj)
271 elif len(obj) <= 2**16-1:
272 fp.write(b"\xc5" + struct.pack(">H", len(obj)) + obj)
273 elif len(obj) <= 2**32-1:
274 fp.write(b"\xc6" + struct.pack(">I", len(obj)) + obj)
275 else:
276 raise UnsupportedTypeException("huge binary string")
277
278def _pack_oldspec_raw(obj, fp):
279 if len(obj) <= 31:
280 fp.write(struct.pack("B", 0xa0 | len(obj)) + obj)
281 elif len(obj) <= 2**16-1:
282 fp.write(b"\xda" + struct.pack(">H", len(obj)) + obj)
283 elif len(obj) <= 2**32-1:
284 fp.write(b"\xdb" + struct.pack(">I", len(obj)) + obj)
285 else:
286 raise UnsupportedTypeException("huge raw string")
287
288def _pack_ext(obj, fp):
289 if len(obj.data) == 1:
290 fp.write(b"\xd4" + struct.pack("B", obj.type & 0xff) + obj.data)
291 elif len(obj.data) == 2:
292 fp.write(b"\xd5" + struct.pack("B", obj.type & 0xff) + obj.data)
293 elif len(obj.data) == 4:
294 fp.write(b"\xd6" + struct.pack("B", obj.type & 0xff) + obj.data)
295 elif len(obj.data) == 8:
296 fp.write(b"\xd7" + struct.pack("B", obj.type & 0xff) + obj.data)
297 elif len(obj.data) == 16:
298 fp.write(b"\xd8" + struct.pack("B", obj.type & 0xff) + obj.data)
299 elif len(obj.data) <= 2**8-1:
300 fp.write(b"\xc7" + struct.pack("BB", len(obj.data), obj.type & 0xff) + obj.data)
301 elif len(obj.data) <= 2**16-1:
302 fp.write(b"\xc8" + struct.pack(">HB", len(obj.data), obj.type & 0xff) + obj.data)
303 elif len(obj.data) <= 2**32-1:
304 fp.write(b"\xc9" + struct.pack(">IB", len(obj.data), obj.type & 0xff) + obj.data)
305 else:
306 raise UnsupportedTypeException("huge ext data")
307
308def _pack_array(obj, fp):
309 if len(obj) <= 15:
310 fp.write(struct.pack("B", 0x90 | len(obj)))
311 elif len(obj) <= 2**16-1:
312 fp.write(b"\xdc" + struct.pack(">H", len(obj)))
313 elif len(obj) <= 2**32-1:
314 fp.write(b"\xdd" + struct.pack(">I", len(obj)))
315 else:
316 raise UnsupportedTypeException("huge array")
317
318 for e in obj:
319 pack(e, fp)
320
321def _pack_map(obj, fp):
322 if len(obj) <= 15:
323 fp.write(struct.pack("B", 0x80 | len(obj)))
324 elif len(obj) <= 2**16-1:
325 fp.write(b"\xde" + struct.pack(">H", len(obj)))
326 elif len(obj) <= 2**32-1:
327 fp.write(b"\xdf" + struct.pack(">I", len(obj)))
328 else:
329 raise UnsupportedTypeException("huge array")
330
331 for k,v in obj.items():
332 pack(k, fp)
333 pack(v, fp)
334
335########################################
336
337# Pack for Python 2, with 'unicode' type, 'str' type, and 'long' type
338def _pack2(obj, fp):
339 """
340 Serialize a Python object into MessagePack bytes.
341
342 Args:
343 obj: a Python object
344 fp: a .write()-supporting file-like object
345
346 Returns:
347 None.
348
349 Raises:
350 UnsupportedType(PackException):
351 Object type not supported for packing.
352
353 Example:
354 >>> f = open('test.bin', 'w')
355 >>> umsgpack.pack({u"compact": True, u"schema": 0}, f)
356 >>>
357 """
358
359 global compatibility
360
361 if obj is None:
362 _pack_nil(obj, fp)
363 elif isinstance(obj, bool):
364 _pack_boolean(obj, fp)
365 elif isinstance(obj, int) or isinstance(obj, long):
366 _pack_integer(obj, fp)
367 elif isinstance(obj, float):
368 _pack_float(obj, fp)
369 elif compatibility and isinstance(obj, unicode):
370 _pack_oldspec_raw(bytes(obj), fp)
371 elif compatibility and isinstance(obj, bytes):
372 _pack_oldspec_raw(obj, fp)
373 elif isinstance(obj, unicode):
374 _pack_string(obj, fp)
375 elif isinstance(obj, str):
376 _pack_binary(obj, fp)
377 elif isinstance(obj, list) or isinstance(obj, tuple):
378 _pack_array(obj, fp)
379 elif isinstance(obj, dict):
380 _pack_map(obj, fp)
381 elif isinstance(obj, Ext):
382 _pack_ext(obj, fp)
383 else:
384 raise UnsupportedTypeException("unsupported type: %s" % str(type(obj)))
385
386# Pack for Python 3, with unicode 'str' type, 'bytes' type, and no 'long' type
387def _pack3(obj, fp):
388 """
389 Serialize a Python object into MessagePack bytes.
390
391 Args:
392 obj: a Python object
393 fp: a .write()-supporting file-like object
394
395 Returns:
396 None.
397
398 Raises:
399 UnsupportedType(PackException):
400 Object type not supported for packing.
401
402 Example:
403 >>> f = open('test.bin', 'w')
404 >>> umsgpack.pack({u"compact": True, u"schema": 0}, fp)
405 >>>
406 """
407 global compatibility
408
409 if obj is None:
410 _pack_nil(obj, fp)
411 elif isinstance(obj, bool):
412 _pack_boolean(obj, fp)
413 elif isinstance(obj, int):
414 _pack_integer(obj, fp)
415 elif isinstance(obj, float):
416 _pack_float(obj, fp)
417 elif compatibility and isinstance(obj, str):
418 _pack_oldspec_raw(obj.encode('utf-8'), fp)
419 elif compatibility and isinstance(obj, bytes):
420 _pack_oldspec_raw(obj, fp)
421 elif isinstance(obj, str):
422 _pack_string(obj, fp)
423 elif isinstance(obj, bytes):
424 _pack_binary(obj, fp)
425 elif isinstance(obj, list) or isinstance(obj, tuple):
426 _pack_array(obj, fp)
427 elif isinstance(obj, dict):
428 _pack_map(obj, fp)
429 elif isinstance(obj, Ext):
430 _pack_ext(obj, fp)
431 else:
432 raise UnsupportedTypeException("unsupported type: %s" % str(type(obj)))
433
434def _packb2(obj):
435 """
436 Serialize a Python object into MessagePack bytes.
437
438 Args:
439 obj: a Python object
440
441 Returns:
442 A 'str' containing serialized MessagePack bytes.
443
444 Raises:
445 UnsupportedType(PackException):
446 Object type not supported for packing.
447
448 Example:
449 >>> umsgpack.packb({u"compact": True, u"schema": 0})
450 '\x82\xa7compact\xc3\xa6schema\x00'
451 >>>
452 """
453 fp = io.BytesIO()
454 _pack2(obj, fp)
455 return fp.getvalue()
456
457def _packb3(obj):
458 """
459 Serialize a Python object into MessagePack bytes.
460
461 Args:
462 obj: a Python object
463
464 Returns:
465 A 'bytes' containing serialized MessagePack bytes.
466
467 Raises:
468 UnsupportedType(PackException):
469 Object type not supported for packing.
470
471 Example:
472 >>> umsgpack.packb({u"compact": True, u"schema": 0})
473 b'\x82\xa7compact\xc3\xa6schema\x00'
474 >>>
475 """
476 fp = io.BytesIO()
477 _pack3(obj, fp)
478 return fp.getvalue()
479
480################################################################################
481### Unpacking
482################################################################################
483
484def _read_except(fp, n):
485 data = fp.read(n)
486 if len(data) < n:
487 raise InsufficientDataException()
488 return data
489
490def _unpack_integer(code, fp):
491 if (ord(code) & 0xe0) == 0xe0:
492 return struct.unpack("b", code)[0]
493 elif code == b'\xd0':
494 return struct.unpack("b", _read_except(fp, 1))[0]
495 elif code == b'\xd1':
496 return struct.unpack(">h", _read_except(fp, 2))[0]
497 elif code == b'\xd2':
498 return struct.unpack(">i", _read_except(fp, 4))[0]
499 elif code == b'\xd3':
500 return struct.unpack(">q", _read_except(fp, 8))[0]
501 elif (ord(code) & 0x80) == 0x00:
502 return struct.unpack("B", code)[0]
503 elif code == b'\xcc':
504 return struct.unpack("B", _read_except(fp, 1))[0]
505 elif code == b'\xcd':
506 return struct.unpack(">H", _read_except(fp, 2))[0]
507 elif code == b'\xce':
508 return struct.unpack(">I", _read_except(fp, 4))[0]
509 elif code == b'\xcf':
510 return struct.unpack(">Q", _read_except(fp, 8))[0]
511 raise Exception("logic error, not int: 0x%02x" % ord(code))
512
513def _unpack_reserved(code, fp):
514 if code == b'\xc1':
515 raise ReservedCodeException("encountered reserved code: 0x%02x" % ord(code))
516 raise Exception("logic error, not reserved code: 0x%02x" % ord(code))
517
518def _unpack_nil(code, fp):
519 if code == b'\xc0':
520 return None
521 raise Exception("logic error, not nil: 0x%02x" % ord(code))
522
523def _unpack_boolean(code, fp):
524 if code == b'\xc2':
525 return False
526 elif code == b'\xc3':
527 return True
528 raise Exception("logic error, not boolean: 0x%02x" % ord(code))
529
530def _unpack_float(code, fp):
531 if code == b'\xca':
532 return struct.unpack(">f", _read_except(fp, 4))[0]
533 elif code == b'\xcb':
534 return struct.unpack(">d", _read_except(fp, 8))[0]
535 raise Exception("logic error, not float: 0x%02x" % ord(code))
536
537def _unpack_string(code, fp):
538 if (ord(code) & 0xe0) == 0xa0:
539 length = ord(code) & ~0xe0
540 elif code == b'\xd9':
541 length = struct.unpack("B", _read_except(fp, 1))[0]
542 elif code == b'\xda':
543 length = struct.unpack(">H", _read_except(fp, 2))[0]
544 elif code == b'\xdb':
545 length = struct.unpack(">I", _read_except(fp, 4))[0]
546 else:
547 raise Exception("logic error, not string: 0x%02x" % ord(code))
548
549 # Always return raw bytes in compatibility mode
550 global compatibility
551 if compatibility:
552 return _read_except(fp, length)
553
554 try:
555 return bytes.decode(_read_except(fp, length), 'utf-8')
556 except UnicodeDecodeError:
557 raise InvalidStringException("unpacked string is not utf-8")
558
559def _unpack_binary(code, fp):
560 if code == b'\xc4':
561 length = struct.unpack("B", _read_except(fp, 1))[0]
562 elif code == b'\xc5':
563 length = struct.unpack(">H", _read_except(fp, 2))[0]
564 elif code == b'\xc6':
565 length = struct.unpack(">I", _read_except(fp, 4))[0]
566 else:
567 raise Exception("logic error, not binary: 0x%02x" % ord(code))
568
569 return _read_except(fp, length)
570
571def _unpack_ext(code, fp):
572 if code == b'\xd4':
573 length = 1
574 elif code == b'\xd5':
575 length = 2
576 elif code == b'\xd6':
577 length = 4
578 elif code == b'\xd7':
579 length = 8
580 elif code == b'\xd8':
581 length = 16
582 elif code == b'\xc7':
583 length = struct.unpack("B", _read_except(fp, 1))[0]
584 elif code == b'\xc8':
585 length = struct.unpack(">H", _read_except(fp, 2))[0]
586 elif code == b'\xc9':
587 length = struct.unpack(">I", _read_except(fp, 4))[0]
588 else:
589 raise Exception("logic error, not ext: 0x%02x" % ord(code))
590
591 return Ext(ord(_read_except(fp, 1)), _read_except(fp, length))
592
593def _unpack_array(code, fp):
594 if (ord(code) & 0xf0) == 0x90:
595 length = (ord(code) & ~0xf0)
596 elif code == b'\xdc':
597 length = struct.unpack(">H", _read_except(fp, 2))[0]
598 elif code == b'\xdd':
599 length = struct.unpack(">I", _read_except(fp, 4))[0]
600 else:
601 raise Exception("logic error, not array: 0x%02x" % ord(code))
602
603 return [_unpack(fp) for i in range(length)]
604
605def _deep_list_to_tuple(obj):
606 if isinstance(obj, list):
607 return tuple([_deep_list_to_tuple(e) for e in obj])
608 return obj
609
610def _unpack_map(code, fp):
611 if (ord(code) & 0xf0) == 0x80:
612 length = (ord(code) & ~0xf0)
613 elif code == b'\xde':
614 length = struct.unpack(">H", _read_except(fp, 2))[0]
615 elif code == b'\xdf':
616 length = struct.unpack(">I", _read_except(fp, 4))[0]
617 else:
618 raise Exception("logic error, not map: 0x%02x" % ord(code))
619
620 d = {}
621 for i in range(length):
622 # Unpack key
623 k = _unpack(fp)
624
625 if isinstance(k, list):
626 # Attempt to convert list into a hashable tuple
627 k = _deep_list_to_tuple(k)
628 elif not isinstance(k, collections.Hashable):
629 raise UnhashableKeyException("encountered unhashable key: %s, %s" % (str(k), str(type(k))))
630 elif k in d:
631 raise DuplicateKeyException("encountered duplicate key: %s, %s" % (str(k), str(type(k))))
632
633 # Unpack value
634 v = _unpack(fp)
635
636 try:
637 d[k] = v
638 except TypeError:
639 raise UnhashableKeyException("encountered unhashable key: %s" % str(k))
640 return d
641
642def _unpack(fp):
643 code = _read_except(fp, 1)
644 return _unpack_dispatch_table[code](code, fp)
645
646########################################
647
648def _unpack2(fp):
649 """
650 Deserialize MessagePack bytes into a Python object.
651
652 Args:
653 fp: a .read()-supporting file-like object
654
655 Returns:
656 A Python object.
657
658 Raises:
659 InsufficientDataException(UnpackException):
660 Insufficient data to unpack the encoded object.
661 InvalidStringException(UnpackException):
662 Invalid UTF-8 string encountered during unpacking.
663 ReservedCodeException(UnpackException):
664 Reserved code encountered during unpacking.
665 UnhashableKeyException(UnpackException):
666 Unhashable key encountered during map unpacking.
667 The serialized map cannot be deserialized into a Python dictionary.
668 DuplicateKeyException(UnpackException):
669 Duplicate key encountered during map unpacking.
670
671 Example:
672 >>> f = open("test.bin")
673 >>> umsgpack.unpackb(f)
674 {u'compact': True, u'schema': 0}
675 >>>
676 """
677 return _unpack(fp)
678
679def _unpack3(fp):
680 """
681 Deserialize MessagePack bytes into a Python object.
682
683 Args:
684 fp: a .read()-supporting file-like object
685
686 Returns:
687 A Python object.
688
689 Raises:
690 InsufficientDataException(UnpackException):
691 Insufficient data to unpack the encoded object.
692 InvalidStringException(UnpackException):
693 Invalid UTF-8 string encountered during unpacking.
694 ReservedCodeException(UnpackException):
695 Reserved code encountered during unpacking.
696 UnhashableKeyException(UnpackException):
697 Unhashable key encountered during map unpacking.
698 The serialized map cannot be deserialized into a Python dictionary.
699 DuplicateKeyException(UnpackException):
700 Duplicate key encountered during map unpacking.
701
702 Example:
703 >>> f = open("test.bin")
704 >>> umsgpack.unpackb(f)
705 {'compact': True, 'schema': 0}
706 >>>
707 """
708 return _unpack(fp)
709
710# For Python 2, expects a str object
711def _unpackb2(s):
712 """
713 Deserialize MessagePack bytes into a Python object.
714
715 Args:
716 s: a 'str' containing serialized MessagePack bytes
717
718 Returns:
719 A Python object.
720
721 Raises:
722 TypeError:
723 Packed data is not type 'str'.
724 InsufficientDataException(UnpackException):
725 Insufficient data to unpack the encoded object.
726 InvalidStringException(UnpackException):
727 Invalid UTF-8 string encountered during unpacking.
728 ReservedCodeException(UnpackException):
729 Reserved code encountered during unpacking.
730 UnhashableKeyException(UnpackException):
731 Unhashable key encountered during map unpacking.
732 The serialized map cannot be deserialized into a Python dictionary.
733 DuplicateKeyException(UnpackException):
734 Duplicate key encountered during map unpacking.
735
736 Example:
737 >>> umsgpack.unpackb(b'\x82\xa7compact\xc3\xa6schema\x00')
738 {u'compact': True, u'schema': 0}
739 >>>
740 """
741 if not isinstance(s, str):
742 raise TypeError("packed data is not type 'str'")
743 return _unpack(io.BytesIO(s))
744
745# For Python 3, expects a bytes object
746def _unpackb3(s):
747 """
748 Deserialize MessagePack bytes into a Python object.
749
750 Args:
751 s: a 'bytes' containing serialized MessagePack bytes
752
753 Returns:
754 A Python object.
755
756 Raises:
757 TypeError:
758 Packed data is not type 'bytes'.
759 InsufficientDataException(UnpackException):
760 Insufficient data to unpack the encoded object.
761 InvalidStringException(UnpackException):
762 Invalid UTF-8 string encountered during unpacking.
763 ReservedCodeException(UnpackException):
764 Reserved code encountered during unpacking.
765 UnhashableKeyException(UnpackException):
766 Unhashable key encountered during map unpacking.
767 The serialized map cannot be deserialized into a Python dictionary.
768 DuplicateKeyException(UnpackException):
769 Duplicate key encountered during map unpacking.
770
771 Example:
772 >>> umsgpack.unpackb(b'\x82\xa7compact\xc3\xa6schema\x00')
773 {'compact': True, 'schema': 0}
774 >>>
775 """
776 if not isinstance(s, bytes):
777 raise TypeError("packed data is not type 'bytes'")
778 return _unpack(io.BytesIO(s))
779
780################################################################################
781### Module Initialization
782################################################################################
783
784def __init():
785 global pack
786 global packb
787 global unpack
788 global unpackb
789 global dump
790 global dumps
791 global load
792 global loads
793 global compatibility
794 global _float_size
795 global _unpack_dispatch_table
796
797 # Compatibility mode for handling strings/bytes with the old specification
798 compatibility = False
799
800 # Auto-detect system float precision
801 if sys.float_info.mant_dig == 53:
802 _float_size = 64
803 else:
804 _float_size = 32
805
806 # Map packb and unpackb to the appropriate version
807 if sys.version_info[0] == 3:
808 pack = _pack3
809 packb = _packb3
810 dump = _pack3
811 dumps = _packb3
812 unpack = _unpack3
813 unpackb = _unpackb3
814 load = _unpack3
815 loads = _unpackb3
816 else:
817 pack = _pack2
818 packb = _packb2
819 dump = _pack2
820 dumps = _packb2
821 unpack = _unpack2
822 unpackb = _unpackb2
823 load = _unpack2
824 loads = _unpackb2
825
826 # Build a dispatch table for fast lookup of unpacking function
827
828 _unpack_dispatch_table = {}
829 # Fix uint
830 for code in range(0, 0x7f+1):
831 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_integer
832 # Fix map
833 for code in range(0x80, 0x8f+1):
834 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_map
835 # Fix array
836 for code in range(0x90, 0x9f+1):
837 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_array
838 # Fix str
839 for code in range(0xa0, 0xbf+1):
840 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_string
841 # Nil
842 _unpack_dispatch_table[b'\xc0'] = _unpack_nil
843 # Reserved
844 _unpack_dispatch_table[b'\xc1'] = _unpack_reserved
845 # Boolean
846 _unpack_dispatch_table[b'\xc2'] = _unpack_boolean
847 _unpack_dispatch_table[b'\xc3'] = _unpack_boolean
848 # Bin
849 for code in range(0xc4, 0xc6+1):
850 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_binary
851 # Ext
852 for code in range(0xc7, 0xc9+1):
853 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_ext
854 # Float
855 _unpack_dispatch_table[b'\xca'] = _unpack_float
856 _unpack_dispatch_table[b'\xcb'] = _unpack_float
857 # Uint
858 for code in range(0xcc, 0xcf+1):
859 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_integer
860 # Int
861 for code in range(0xd0, 0xd3+1):
862 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_integer
863 # Fixext
864 for code in range(0xd4, 0xd8+1):
865 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_ext
866 # String
867 for code in range(0xd9, 0xdb+1):
868 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_string
869 # Array
870 _unpack_dispatch_table[b'\xdc'] = _unpack_array
871 _unpack_dispatch_table[b'\xdd'] = _unpack_array
872 # Map
873 _unpack_dispatch_table[b'\xde'] = _unpack_map
874 _unpack_dispatch_table[b'\xdf'] = _unpack_map
875 # Negative fixint
876 for code in range(0xe0, 0xff+1):
877 _unpack_dispatch_table[struct.pack("B", code)] = _unpack_integer
878
879__init()