u-msgpack-python 2.7.2__py2.py3-none-any.whl → 2.9.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: u-msgpack-python
3
- Version: 2.7.2
3
+ Version: 2.9.0
4
4
  Summary: A portable, lightweight MessagePack serializer and deserializer written in pure Python.
5
5
  Home-page: https://github.com/vsergeev/u-msgpack-python
6
6
  Author: vsergeev
@@ -15,6 +15,17 @@ Classifier: Programming Language :: Python :: 2
15
15
  Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: Implementation :: CPython
17
17
  Classifier: Programming Language :: Python :: Implementation :: PyPy
18
+ Description-Content-Type: text/x-rst
18
19
  License-File: LICENSE
20
+ Dynamic: author
21
+ Dynamic: author-email
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: description-content-type
25
+ Dynamic: home-page
26
+ Dynamic: keywords
27
+ Dynamic: license
28
+ Dynamic: license-file
29
+ Dynamic: summary
19
30
 
20
- u-msgpack-python is a lightweight `MessagePack <http://msgpack.org/>`_ serializer and deserializer module written in pure Python, compatible with both Python 2 and Python 3, as well as CPython and PyPy implementations of Python. u-msgpack-python is fully compliant with the latest `MessagePack specification <https://github.com/msgpack/msgpack/blob/master/spec.md>`_. In particular, it supports the new binary, UTF-8 string, and application-defined ext types. See https://github.com/vsergeev/u-msgpack-python for more information.
31
+ u-msgpack-python is a lightweight `MessagePack <http://msgpack.org/>`_ serializer and deserializer module written in pure Python, compatible with both Python 2 and Python 3, as well as CPython and PyPy implementations of Python. u-msgpack-python is fully compliant with the latest `MessagePack specification <https://github.com/msgpack/msgpack/blob/master/spec.md>`_. In particular, it supports the new binary, UTF-8 string, application-defined ext, and timestamp types. See https://github.com/vsergeev/u-msgpack-python for more information.
@@ -0,0 +1,8 @@
1
+ u_msgpack_python-2.9.0.dist-info/licenses/LICENSE,sha256=kJ7HHWniTZmi0a_g5n8zugdLk8rdZtMLBW_amWg85w4,1099
2
+ umsgpack/__init__.py,sha256=_Z8_0-exPbD9stBK0f45hNhMkmbV5qv6APusRxt89oQ,48613
3
+ umsgpack/__init__.pyi,sha256=Bb8mY8eZzxXvqKOI4nE9wE5xmdRkCOzv3LIg1LhDi6Y,2988
4
+ umsgpack/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ u_msgpack_python-2.9.0.dist-info/METADATA,sha256=WTocwq61KICY7gXP5iOivOxq0expvv6q3vPknwAdNPU,1560
6
+ u_msgpack_python-2.9.0.dist-info/WHEEL,sha256=Uvlg2aNlEKdilsyFSJt1QX5me0eEbCjQzR3nZeFkvy4,109
7
+ u_msgpack_python-2.9.0.dist-info/top_level.txt,sha256=vlKYkefVvMYiE2tS8E4NKGRXIGIWzQq9ar1A0j2avaA,9
8
+ u_msgpack_python-2.9.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.38.0)
2
+ Generator: setuptools (84.2.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2022 vsergeev / Ivan (Vanya) A. Sergeev
1
+ Copyright (c) 2013-2026 vsergeev / Ivan (Vanya) A. Sergeev
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
@@ -1,16 +1,17 @@
1
- # u-msgpack-python v2.7.2 - v at sergeev.io
1
+ # u-msgpack-python v2.9.0 - v at sergeev.io
2
2
  # https://github.com/vsergeev/u-msgpack-python
3
3
  #
4
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
5
+ # module, compatible with both Python 2 and 3, as well as CPython and PyPy
6
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.
7
+ # latest MessagePack specification
8
+ # (https://github.com/msgpack/msgpack/blob/master/spec.md). In particular, it
9
+ # supports the new binary, UTF-8 string, application-defined ext, and
10
+ # timestamp types.
10
11
  #
11
12
  # MIT License
12
13
  #
13
- # Copyright (c) 2013-2022 vsergeev / Ivan (Vanya) A. Sergeev
14
+ # Copyright (c) 2013-2026 vsergeev / Ivan (Vanya) A. Sergeev
14
15
  #
15
16
  # Permission is hereby granted, free of charge, to any person obtaining a copy
16
17
  # of this software and associated documentation files (the "Software"), to deal
@@ -31,20 +32,22 @@
31
32
  # THE SOFTWARE.
32
33
  #
33
34
  """
34
- u-msgpack-python v2.7.2 - v at sergeev.io
35
+ u-msgpack-python v2.9.0 - v at sergeev.io
35
36
  https://github.com/vsergeev/u-msgpack-python
36
37
 
37
38
  u-msgpack-python is a lightweight MessagePack serializer and deserializer
38
- module, compatible with both Python 2 and 3, as well CPython and PyPy
39
+ module, compatible with both Python 2 and 3, as well as CPython and PyPy
39
40
  implementations of Python. u-msgpack-python is fully compliant with the
40
- latest MessagePack specification.com/msgpack/msgpack/blob/master/spec.md). In
41
- particular, it supports the new binary, UTF-8 string, and application ext
41
+ latest MessagePack specification
42
+ (https://github.com/msgpack/msgpack/blob/master/spec.md). In particular, it
43
+ supports the new binary, UTF-8 string, application-defined ext, and timestamp
42
44
  types.
43
45
 
44
46
  License: MIT
45
47
  """
46
48
  import struct
47
49
  import collections
50
+ import functools
48
51
  import datetime
49
52
  import sys
50
53
  import io
@@ -54,10 +57,11 @@ if sys.version_info[0:2] >= (3, 3):
54
57
  else:
55
58
  from collections import Hashable
56
59
 
57
- __version__ = "2.7.2"
60
+
61
+ __version__ = "2.9.0"
58
62
  "Module version string"
59
63
 
60
- version = (2, 7, 2)
64
+ version = (2, 9, 0)
61
65
  "Module version tuple"
62
66
 
63
67
 
@@ -77,24 +81,24 @@ class Ext(object):
77
81
  Construct a new Ext object.
78
82
 
79
83
  Args:
80
- type: application-defined type integer
81
- data: application-defined data byte array
84
+ type (int): application-defined type integer
85
+ data (bytes): application-defined data byte array
82
86
 
83
- TypeError:
84
- Type is not an integer.
85
- ValueError:
86
- Type is out of range of -128 to 127.
87
- TypeError::
88
- Data is not type 'bytes' (Python 3) or not type 'str' (Python 2).
87
+ Raises:
88
+ TypeError:
89
+ Type is not an integer.
90
+ ValueError:
91
+ Type is out of range of -128 to 127.
92
+ TypeError:
93
+ Data is not type 'bytes' (Python 3) or not type 'str' (Python 2).
89
94
 
90
95
  Example:
91
- >>> foo = umsgpack.Ext(5, b"\x01\x02\x03")
92
- >>> umsgpack.packb({u"special stuff": foo, u"awesome": True})
93
- '\x82\xa7awesome\xc3\xadspecial stuff\xc7\x03\x05\x01\x02\x03'
94
- >>> bar = umsgpack.unpackb(_)
95
- >>> print(bar["special stuff"])
96
- Ext Object (Type: 5, Data: 01 02 03)
97
- >>>
96
+ >>> foo = umsgpack.Ext(5, b"\\x01\\x02\\x03")
97
+ >>> umsgpack.packb({u"special stuff": foo, u"awesome": True})
98
+ b'\\x82\\xadspecial stuff\\xc7\\x03\\x05\\x01\\x02\\x03\\xa7awesome\\xc3'
99
+ >>> bar = umsgpack.unpackb(_)
100
+ >>> print(bar["special stuff"])
101
+ Ext Object (Type: 5, Data: 0x01 0x02 0x03)
98
102
  """
99
103
  # Check type is type int and in range
100
104
  if not isinstance(type, int):
@@ -163,7 +167,7 @@ def ext_serializable(ext_type):
163
167
  instance of the application class.
164
168
 
165
169
  Args:
166
- ext_type: application-defined Ext type code
170
+ ext_type (int): application-defined Ext type code
167
171
 
168
172
  Raises:
169
173
  TypeError:
@@ -238,6 +242,10 @@ class DuplicateKeyException(UnpackException):
238
242
  "Duplicate key encountered during map unpacking."
239
243
 
240
244
 
245
+ class MaximumDepthException(UnpackException):
246
+ "Maximum nesting depth exceeded during unpacking."
247
+
248
+
241
249
  # Backwards compatibility
242
250
  KeyNotPrimitiveException = UnhashableKeyException
243
251
  KeyDuplicateException = DuplicateKeyException
@@ -266,13 +274,11 @@ unicode strings and bytes into the old "raw" msgpack type, and deserialize the
266
274
  old MessagePack specification.
267
275
 
268
276
  Example:
269
- >>> umsgpack.compatibility = True
270
- >>>
271
- >>> umsgpack.packb([u"some string", b"some bytes"])
272
- b'\x92\xabsome string\xaasome bytes'
273
- >>> umsgpack.unpackb(_)
274
- [b'some string', b'some bytes']
275
- >>>
277
+ >>> umsgpack.compatibility = True
278
+ >>> umsgpack.packb([u"some string", b"some bytes"])
279
+ b'\\x92\\xabsome string\\xaasome bytes'
280
+ >>> umsgpack.unpackb(_)
281
+ [b'some string', b'some bytes']
276
282
  """
277
283
 
278
284
  ##############################################################################
@@ -444,7 +450,7 @@ def _pack_map(obj, fp, options):
444
450
  elif obj_len < 2**32:
445
451
  fp.write(b"\xdf" + struct.pack(">I", obj_len))
446
452
  else:
447
- raise UnsupportedTypeException("huge array")
453
+ raise UnsupportedTypeException("huge map")
448
454
 
449
455
  for k, v in obj.items():
450
456
  pack(k, fp, **options)
@@ -462,29 +468,26 @@ def _pack2(obj, fp, **options):
462
468
  obj: a Python object
463
469
  fp: a .write()-supporting file-like object
464
470
 
465
- Kwargs:
471
+ Keyword Args:
466
472
  ext_handlers (dict): dictionary of Ext handlers, mapping a custom type
467
473
  to a callable that packs an instance of the type
468
474
  into an Ext object
469
475
  force_float_precision (str): "single" to force packing floats as
470
476
  IEEE-754 single-precision floats,
471
477
  "double" to force packing floats as
472
- IEEE-754 double-precision floats.
478
+ IEEE-754 double-precision floats
473
479
 
474
480
  Returns:
475
- None.
481
+ None
476
482
 
477
483
  Raises:
478
- UnsupportedType(PackException):
484
+ UnsupportedTypeException(PackException):
479
485
  Object type not supported for packing.
480
486
 
481
487
  Example:
482
- >>> f = open('test.bin', 'wb')
483
- >>> umsgpack.pack({u"compact": True, u"schema": 0}, f)
484
- >>>
488
+ >>> f = open('test.bin', 'wb')
489
+ >>> umsgpack.pack({u"compact": True, u"schema": 0}, f)
485
490
  """
486
- global compatibility
487
-
488
491
  ext_handlers = options.get("ext_handlers")
489
492
 
490
493
  if obj is None:
@@ -498,15 +501,15 @@ def _pack2(obj, fp, **options):
498
501
  raise NotImplementedError("Ext serializable class {:s} is missing implementation of packb()".format(repr(obj.__class__)))
499
502
  elif isinstance(obj, bool):
500
503
  _pack_boolean(obj, fp, options)
501
- elif isinstance(obj, (int, long)):
504
+ elif isinstance(obj, (int, long)): # noqa: F821
502
505
  _pack_integer(obj, fp, options)
503
506
  elif isinstance(obj, float):
504
507
  _pack_float(obj, fp, options)
505
- elif compatibility and isinstance(obj, unicode):
508
+ elif compatibility and isinstance(obj, unicode): # noqa: F821
506
509
  _pack_oldspec_raw(bytes(obj), fp, options)
507
510
  elif compatibility and isinstance(obj, bytes):
508
511
  _pack_oldspec_raw(obj, fp, options)
509
- elif isinstance(obj, unicode):
512
+ elif isinstance(obj, unicode): # noqa: F821
510
513
  _pack_string(obj, fp, options)
511
514
  elif isinstance(obj, str):
512
515
  _pack_binary(obj, fp, options)
@@ -549,29 +552,26 @@ def _pack3(obj, fp, **options):
549
552
  obj: a Python object
550
553
  fp: a .write()-supporting file-like object
551
554
 
552
- Kwargs:
555
+ Keyword Args:
553
556
  ext_handlers (dict): dictionary of Ext handlers, mapping a custom type
554
557
  to a callable that packs an instance of the type
555
558
  into an Ext object
556
559
  force_float_precision (str): "single" to force packing floats as
557
560
  IEEE-754 single-precision floats,
558
561
  "double" to force packing floats as
559
- IEEE-754 double-precision floats.
562
+ IEEE-754 double-precision floats
560
563
 
561
564
  Returns:
562
- None.
565
+ None
563
566
 
564
567
  Raises:
565
- UnsupportedType(PackException):
568
+ UnsupportedTypeException(PackException):
566
569
  Object type not supported for packing.
567
570
 
568
571
  Example:
569
- >>> f = open('test.bin', 'wb')
570
- >>> umsgpack.pack({u"compact": True, u"schema": 0}, f)
571
- >>>
572
+ >>> f = open('test.bin', 'wb')
573
+ >>> umsgpack.pack({u"compact": True, u"schema": 0}, f)
572
574
  """
573
- global compatibility
574
-
575
575
  ext_handlers = options.get("ext_handlers")
576
576
 
577
577
  if obj is None:
@@ -635,26 +635,25 @@ def _packb2(obj, **options):
635
635
  Args:
636
636
  obj: a Python object
637
637
 
638
- Kwargs:
638
+ Keyword Args:
639
639
  ext_handlers (dict): dictionary of Ext handlers, mapping a custom type
640
640
  to a callable that packs an instance of the type
641
641
  into an Ext object
642
642
  force_float_precision (str): "single" to force packing floats as
643
643
  IEEE-754 single-precision floats,
644
644
  "double" to force packing floats as
645
- IEEE-754 double-precision floats.
645
+ IEEE-754 double-precision floats
646
646
 
647
647
  Returns:
648
- A 'str' containing serialized MessagePack bytes.
648
+ str: Serialized MessagePack bytes
649
649
 
650
650
  Raises:
651
- UnsupportedType(PackException):
651
+ UnsupportedTypeException(PackException):
652
652
  Object type not supported for packing.
653
653
 
654
654
  Example:
655
- >>> umsgpack.packb({u"compact": True, u"schema": 0})
656
- '\x82\xa7compact\xc3\xa6schema\x00'
657
- >>>
655
+ >>> umsgpack.packb({u"compact": True, u"schema": 0})
656
+ '\\x82\\xa7compact\\xc3\\xa6schema\\x00'
658
657
  """
659
658
  fp = io.BytesIO()
660
659
  _pack2(obj, fp, **options)
@@ -668,26 +667,25 @@ def _packb3(obj, **options):
668
667
  Args:
669
668
  obj: a Python object
670
669
 
671
- Kwargs:
670
+ Keyword Args:
672
671
  ext_handlers (dict): dictionary of Ext handlers, mapping a custom type
673
672
  to a callable that packs an instance of the type
674
673
  into an Ext object
675
674
  force_float_precision (str): "single" to force packing floats as
676
675
  IEEE-754 single-precision floats,
677
676
  "double" to force packing floats as
678
- IEEE-754 double-precision floats.
677
+ IEEE-754 double-precision floats
679
678
 
680
679
  Returns:
681
- A 'bytes' containing serialized MessagePack bytes.
680
+ bytes: Serialized MessagePack bytes
682
681
 
683
682
  Raises:
684
- UnsupportedType(PackException):
683
+ UnsupportedTypeException(PackException):
685
684
  Object type not supported for packing.
686
685
 
687
686
  Example:
688
- >>> umsgpack.packb({u"compact": True, u"schema": 0})
689
- b'\x82\xa7compact\xc3\xa6schema\x00'
690
- >>>
687
+ >>> umsgpack.packb({u"compact": True, u"schema": 0})
688
+ b'\\x82\\xa7compact\\xc3\\xa6schema\\x00'
691
689
  """
692
690
  fp = io.BytesIO()
693
691
  _pack3(obj, fp, **options)
@@ -783,7 +781,6 @@ def _unpack_string(code, fp, options):
783
781
  raise Exception("logic error, not string: 0x{:02x}".format(ord(code)))
784
782
 
785
783
  # Always return raw bytes in compatibility mode
786
- global compatibility
787
784
  if compatibility:
788
785
  return _read_except(fp, length)
789
786
 
@@ -874,7 +871,7 @@ def _unpack_ext_timestamp(ext_data, options):
874
871
  microseconds=microseconds)
875
872
 
876
873
 
877
- def _unpack_array(code, fp, options):
874
+ def _unpack_array(code, fp, options, depth=None):
878
875
  if (ord(code) & 0xf0) == 0x90:
879
876
  length = (ord(code) & ~0xf0)
880
877
  elif code == b'\xdc':
@@ -885,9 +882,12 @@ def _unpack_array(code, fp, options):
885
882
  raise Exception("logic error, not array: 0x{:02x}".format(ord(code)))
886
883
 
887
884
  if options.get('use_tuple'):
888
- return tuple((_unpack(fp, options) for i in xrange(length)))
885
+ return tuple((_unpack(fp, options) if depth is None
886
+ else _unpack_depth(fp, options, depth)
887
+ for i in xrange(length)))
889
888
 
890
- return [_unpack(fp, options) for i in xrange(length)]
889
+ return [_unpack(fp, options) if depth is None
890
+ else _unpack_depth(fp, options, depth) for i in xrange(length)]
891
891
 
892
892
 
893
893
  def _deep_list_to_tuple(obj):
@@ -896,7 +896,7 @@ def _deep_list_to_tuple(obj):
896
896
  return obj
897
897
 
898
898
 
899
- def _unpack_map(code, fp, options):
899
+ def _unpack_map(code, fp, options, depth=None):
900
900
  if (ord(code) & 0xf0) == 0x80:
901
901
  length = (ord(code) & ~0xf0)
902
902
  elif code == b'\xde':
@@ -909,7 +909,8 @@ def _unpack_map(code, fp, options):
909
909
  d = {} if not options.get('use_ordered_dict') else collections.OrderedDict()
910
910
  for _ in xrange(length):
911
911
  # Unpack key
912
- k = _unpack(fp, options)
912
+ k = _unpack(fp, options) if depth is None \
913
+ else _unpack_depth(fp, options, depth)
913
914
 
914
915
  if isinstance(k, list):
915
916
  # Attempt to convert list into a hashable tuple
@@ -922,7 +923,8 @@ def _unpack_map(code, fp, options):
922
923
  "encountered duplicate key: \"{:s}\" ({:s})".format(str(k), str(type(k))))
923
924
 
924
925
  # Unpack value
925
- v = _unpack(fp, options)
926
+ v = _unpack(fp, options) if depth is None \
927
+ else _unpack_depth(fp, options, depth)
926
928
 
927
929
  try:
928
930
  d[k] = v
@@ -936,6 +938,33 @@ def _unpack(fp, options):
936
938
  code = _read_except(fp, 1)
937
939
  return _unpack_dispatch_table[code](code, fp, options)
938
940
 
941
+
942
+ def _unpack_depth(fp, options, depth):
943
+ code = _read_except(fp, 1)
944
+ return _unpack_depth_dispatch_table[code](code, fp, options, depth)
945
+
946
+
947
+ def _limit_depth(unpack_container):
948
+ """Wrap a depth-aware container unpacker to enforce options['max_depth'].
949
+
950
+ depth is passed as a local argument and incremented on entry.
951
+ """
952
+ @functools.wraps(unpack_container)
953
+ def wrapper(code, fp, options, depth):
954
+ depth += 1
955
+ if depth > options['max_depth']:
956
+ raise MaximumDepthException("maximum nesting depth exceeded")
957
+ return unpack_container(code, fp, options, depth)
958
+ return wrapper
959
+
960
+
961
+ def _ignore_depth(unpacker):
962
+ """Adapt a scalar (non-container) unpacker to the depth dispatch signature."""
963
+ @functools.wraps(unpacker)
964
+ def wrapper(code, fp, options, depth):
965
+ return unpacker(code, fp, options)
966
+ return wrapper
967
+
939
968
  ########################################
940
969
 
941
970
 
@@ -946,20 +975,24 @@ def _unpack2(fp, **options):
946
975
  Args:
947
976
  fp: a .read()-supporting file-like object
948
977
 
949
- Kwargs:
978
+ Keyword Args:
950
979
  ext_handlers (dict): dictionary of Ext handlers, mapping integer Ext
951
980
  type to a callable that unpacks an instance of
952
981
  Ext into an object
953
- use_ordered_dict (bool): unpack maps into OrderedDict, instead of
954
- unordered dict (default False)
982
+ use_ordered_dict (bool): unpack maps into OrderedDict, instead of dict
983
+ (default False)
955
984
  use_tuple (bool): unpacks arrays into tuples, instead of lists (default
956
985
  False)
957
986
  allow_invalid_utf8 (bool): unpack invalid strings into instances of
958
- InvalidString, for access to the bytes
959
- (default False)
987
+ :class:`InvalidString`, for access to the
988
+ bytes (default False)
989
+ max_depth (int): maximum nesting depth of arrays/maps to unpack; when
990
+ exceeded, :class:`MaximumDepthException` is raised. If
991
+ None (default), depth is bounded only by the
992
+ interpreter's recursion limit.
960
993
 
961
994
  Returns:
962
- A Python object.
995
+ Python object
963
996
 
964
997
  Raises:
965
998
  InsufficientDataException(UnpackException):
@@ -975,14 +1008,23 @@ def _unpack2(fp, **options):
975
1008
  The serialized map cannot be deserialized into a Python dictionary.
976
1009
  DuplicateKeyException(UnpackException):
977
1010
  Duplicate key encountered during map unpacking.
1011
+ MaximumDepthException(UnpackException):
1012
+ Maximum nesting depth exceeded while unpacking a deeply-nested
1013
+ object, or the configured limit was exceeded (when ``max_depth`` is
1014
+ set).
978
1015
 
979
1016
  Example:
980
- >>> f = open('test.bin', 'rb')
981
- >>> umsgpack.unpackb(f)
982
- {u'compact': True, u'schema': 0}
983
- >>>
1017
+ >>> f = open('test.bin', 'rb')
1018
+ >>> umsgpack.unpack(f)
1019
+ {u'compact': True, u'schema': 0}
984
1020
  """
985
- return _unpack(fp, options)
1021
+ try:
1022
+ return _unpack(fp, options) if options.get('max_depth') is None \
1023
+ else _unpack_depth(fp, options, 0)
1024
+ except RuntimeError as e:
1025
+ if "maximum recursion depth" in str(e):
1026
+ raise MaximumDepthException("maximum nesting depth exceeded")
1027
+ raise
986
1028
 
987
1029
 
988
1030
  def _unpack3(fp, **options):
@@ -992,20 +1034,24 @@ def _unpack3(fp, **options):
992
1034
  Args:
993
1035
  fp: a .read()-supporting file-like object
994
1036
 
995
- Kwargs:
1037
+ Keyword Args:
996
1038
  ext_handlers (dict): dictionary of Ext handlers, mapping integer Ext
997
1039
  type to a callable that unpacks an instance of
998
1040
  Ext into an object
999
- use_ordered_dict (bool): unpack maps into OrderedDict, instead of
1000
- unordered dict (default False)
1041
+ use_ordered_dict (bool): unpack maps into OrderedDict, instead of dict
1042
+ (default False)
1001
1043
  use_tuple (bool): unpacks arrays into tuples, instead of lists (default
1002
1044
  False)
1003
1045
  allow_invalid_utf8 (bool): unpack invalid strings into instances of
1004
- InvalidString, for access to the bytes
1005
- (default False)
1046
+ :class:`InvalidString`, for access to the
1047
+ bytes (default False)
1048
+ max_depth (int): maximum nesting depth of arrays/maps to unpack; when
1049
+ exceeded, :class:`MaximumDepthException` is raised. If
1050
+ None (default), depth is bounded only by the
1051
+ interpreter's recursion limit.
1006
1052
 
1007
1053
  Returns:
1008
- A Python object.
1054
+ Python object
1009
1055
 
1010
1056
  Raises:
1011
1057
  InsufficientDataException(UnpackException):
@@ -1021,14 +1067,21 @@ def _unpack3(fp, **options):
1021
1067
  The serialized map cannot be deserialized into a Python dictionary.
1022
1068
  DuplicateKeyException(UnpackException):
1023
1069
  Duplicate key encountered during map unpacking.
1070
+ MaximumDepthException(UnpackException):
1071
+ Maximum nesting depth exceeded while unpacking a deeply-nested
1072
+ object, or the configured limit was exceeded (when ``max_depth`` is
1073
+ set).
1024
1074
 
1025
1075
  Example:
1026
- >>> f = open('test.bin', 'rb')
1027
- >>> umsgpack.unpackb(f)
1028
- {'compact': True, 'schema': 0}
1029
- >>>
1076
+ >>> f = open('test.bin', 'rb')
1077
+ >>> umsgpack.unpack(f)
1078
+ {'compact': True, 'schema': 0}
1030
1079
  """
1031
- return _unpack(fp, options)
1080
+ try:
1081
+ return _unpack(fp, options) if options.get('max_depth') is None \
1082
+ else _unpack_depth(fp, options, 0)
1083
+ except RecursionError:
1084
+ raise MaximumDepthException("maximum nesting depth exceeded")
1032
1085
 
1033
1086
 
1034
1087
  # For Python 2, expects a str object
@@ -1037,22 +1090,26 @@ def _unpackb2(s, **options):
1037
1090
  Deserialize MessagePack bytes into a Python object.
1038
1091
 
1039
1092
  Args:
1040
- s: a 'str' or 'bytearray' containing serialized MessagePack bytes
1093
+ s (str, bytearray): serialized MessagePack bytes
1041
1094
 
1042
- Kwargs:
1095
+ Keyword Args:
1043
1096
  ext_handlers (dict): dictionary of Ext handlers, mapping integer Ext
1044
1097
  type to a callable that unpacks an instance of
1045
1098
  Ext into an object
1046
- use_ordered_dict (bool): unpack maps into OrderedDict, instead of
1047
- unordered dict (default False)
1099
+ use_ordered_dict (bool): unpack maps into OrderedDict, instead of dict
1100
+ (default False)
1048
1101
  use_tuple (bool): unpacks arrays into tuples, instead of lists (default
1049
1102
  False)
1050
1103
  allow_invalid_utf8 (bool): unpack invalid strings into instances of
1051
- InvalidString, for access to the bytes
1052
- (default False)
1104
+ :class:`InvalidString`, for access to the
1105
+ bytes (default False)
1106
+ max_depth (int): maximum nesting depth of arrays/maps to unpack; when
1107
+ exceeded, :class:`MaximumDepthException` is raised. If
1108
+ None (default), depth is bounded only by the
1109
+ interpreter's recursion limit.
1053
1110
 
1054
1111
  Returns:
1055
- A Python object.
1112
+ Python object
1056
1113
 
1057
1114
  Raises:
1058
1115
  TypeError:
@@ -1070,15 +1127,24 @@ def _unpackb2(s, **options):
1070
1127
  The serialized map cannot be deserialized into a Python dictionary.
1071
1128
  DuplicateKeyException(UnpackException):
1072
1129
  Duplicate key encountered during map unpacking.
1130
+ MaximumDepthException(UnpackException):
1131
+ Maximum nesting depth exceeded while unpacking a deeply-nested
1132
+ object, or the configured limit was exceeded (when ``max_depth`` is
1133
+ set).
1073
1134
 
1074
1135
  Example:
1075
- >>> umsgpack.unpackb(b'\x82\xa7compact\xc3\xa6schema\x00')
1076
- {u'compact': True, u'schema': 0}
1077
- >>>
1136
+ >>> umsgpack.unpackb(b'\\x82\\xa7compact\\xc3\\xa6schema\\x00')
1137
+ {u'compact': True, u'schema': 0}
1078
1138
  """
1079
1139
  if not isinstance(s, (str, bytearray)):
1080
1140
  raise TypeError("packed data must be type 'str' or 'bytearray'")
1081
- return _unpack(io.BytesIO(s), options)
1141
+ try:
1142
+ return _unpack(io.BytesIO(s), options) if options.get('max_depth') is None \
1143
+ else _unpack_depth(io.BytesIO(s), options, 0)
1144
+ except RuntimeError as e:
1145
+ if "maximum recursion depth" in str(e):
1146
+ raise MaximumDepthException("maximum nesting depth exceeded")
1147
+ raise
1082
1148
 
1083
1149
 
1084
1150
  # For Python 3, expects a bytes object
@@ -1087,22 +1153,26 @@ def _unpackb3(s, **options):
1087
1153
  Deserialize MessagePack bytes into a Python object.
1088
1154
 
1089
1155
  Args:
1090
- s: a 'bytes' or 'bytearray' containing serialized MessagePack bytes
1156
+ s (bytes, bytearray): serialized MessagePack bytes
1091
1157
 
1092
- Kwargs:
1158
+ Keyword Args:
1093
1159
  ext_handlers (dict): dictionary of Ext handlers, mapping integer Ext
1094
1160
  type to a callable that unpacks an instance of
1095
1161
  Ext into an object
1096
- use_ordered_dict (bool): unpack maps into OrderedDict, instead of
1097
- unordered dict (default False)
1162
+ use_ordered_dict (bool): unpack maps into OrderedDict, instead of dict
1163
+ (default False)
1098
1164
  use_tuple (bool): unpacks arrays into tuples, instead of lists (default
1099
1165
  False)
1100
1166
  allow_invalid_utf8 (bool): unpack invalid strings into instances of
1101
- InvalidString, for access to the bytes
1102
- (default False)
1167
+ :class:`InvalidString`, for access to the
1168
+ bytes (default False)
1169
+ max_depth (int): maximum nesting depth of arrays/maps to unpack; when
1170
+ exceeded, :class:`MaximumDepthException` is raised. If
1171
+ None (default), depth is bounded only by the
1172
+ interpreter's recursion limit.
1103
1173
 
1104
1174
  Returns:
1105
- A Python object.
1175
+ Python object
1106
1176
 
1107
1177
  Raises:
1108
1178
  TypeError:
@@ -1120,15 +1190,22 @@ def _unpackb3(s, **options):
1120
1190
  The serialized map cannot be deserialized into a Python dictionary.
1121
1191
  DuplicateKeyException(UnpackException):
1122
1192
  Duplicate key encountered during map unpacking.
1193
+ MaximumDepthException(UnpackException):
1194
+ Maximum nesting depth exceeded while unpacking a deeply-nested
1195
+ object, or the configured limit was exceeded (when ``max_depth`` is
1196
+ set).
1123
1197
 
1124
1198
  Example:
1125
- >>> umsgpack.unpackb(b'\x82\xa7compact\xc3\xa6schema\x00')
1126
- {'compact': True, 'schema': 0}
1127
- >>>
1199
+ >>> umsgpack.unpackb(b'\\x82\\xa7compact\\xc3\\xa6schema\\x00')
1200
+ {'compact': True, 'schema': 0}
1128
1201
  """
1129
1202
  if not isinstance(s, (bytes, bytearray)):
1130
1203
  raise TypeError("packed data must be type 'bytes' or 'bytearray'")
1131
- return _unpack(io.BytesIO(s), options)
1204
+ try:
1205
+ return _unpack(io.BytesIO(s), options) if options.get('max_depth') is None \
1206
+ else _unpack_depth(io.BytesIO(s), options, 0)
1207
+ except RecursionError:
1208
+ raise MaximumDepthException("maximum nesting depth exceeded")
1132
1209
 
1133
1210
  #############################################################################
1134
1211
  # Module Initialization
@@ -1204,7 +1281,7 @@ def __init():
1204
1281
  # Build a dispatch table for fast lookup of unpacking function
1205
1282
 
1206
1283
  _unpack_dispatch_table = {}
1207
- # Fix uint
1284
+ # Positive fixint
1208
1285
  for code in range(0, 0x7f + 1):
1209
1286
  _unpack_dispatch_table[struct.pack("B", code)] = _unpack_integer
1210
1287
  # Fix map
@@ -1254,5 +1331,17 @@ def __init():
1254
1331
  for code in range(0xe0, 0xff + 1):
1255
1332
  _unpack_dispatch_table[struct.pack("B", code)] = _unpack_integer
1256
1333
 
1334
+ # Parallel dispatch table for the optional max_depth path. The array/map
1335
+ # entries are the same container functions as the default table, wrapped by
1336
+ # _limit_depth; scalar unpackers are adapted to accept (and ignore) the
1337
+ # depth argument so _unpack() can dispatch uniformly with no per-code switch.
1338
+ global _unpack_depth_dispatch_table
1339
+ _unpack_depth_dispatch_table = {}
1340
+ for code_bytes, unpacker in _unpack_dispatch_table.items():
1341
+ if unpacker is _unpack_array or unpacker is _unpack_map:
1342
+ _unpack_depth_dispatch_table[code_bytes] = _limit_depth(unpacker)
1343
+ else:
1344
+ _unpack_depth_dispatch_table[code_bytes] = _ignore_depth(unpacker)
1345
+
1257
1346
 
1258
1347
  __init()
umsgpack/__init__.pyi ADDED
@@ -0,0 +1,126 @@
1
+ from typing import Any, Callable, Protocol, TypeVar
2
+
3
+ _T = TypeVar("_T")
4
+
5
+ __version__: str
6
+
7
+ version: tuple[int, int, int]
8
+
9
+
10
+ def pack(
11
+ obj: Any,
12
+ fp: _SupportsWrite,
13
+ *,
14
+ ext_handlers: dict[type[Any], Callable[[Any], Ext]] | None = None,
15
+ force_float_precision: str = ...,
16
+ ) -> None: ...
17
+
18
+
19
+ def packb(
20
+ obj: Any,
21
+ *,
22
+ ext_handlers: dict[type[Any], Callable[[Any], Ext]] | None = None,
23
+ force_float_precision: str = ...,
24
+ ) -> bytes: ...
25
+
26
+
27
+ def dump(
28
+ obj: Any,
29
+ fp: _SupportsWrite,
30
+ *,
31
+ ext_handlers: dict[type[Any], Callable[[Any], Ext]] | None = None,
32
+ force_float_precision: str = ...,
33
+ ) -> None: ...
34
+
35
+
36
+ def dumps(
37
+ obj: Any,
38
+ *,
39
+ ext_handlers: dict[type[Any], Callable[[Any], Ext]] | None = None,
40
+ force_float_precision: str = ...,
41
+ ) -> bytes: ...
42
+
43
+
44
+ def unpackb(
45
+ s: bytes | bytearray | memoryview,
46
+ *,
47
+ ext_handlers: dict[int, Callable[[Ext], Any]] | None = None,
48
+ use_ordered_dict: bool = False,
49
+ use_tuple: bool = False,
50
+ allow_invalid_utf8: bool = False,
51
+ max_depth: int | None = None,
52
+ ) -> Any: ...
53
+
54
+
55
+ def unpack(
56
+ fp: _SupportsRead,
57
+ *,
58
+ ext_handlers: dict[int, Callable[[Ext], Any]] | None = None,
59
+ use_ordered_dict: bool = False,
60
+ use_tuple: bool = False,
61
+ allow_invalid_utf8: bool = False,
62
+ max_depth: int | None = None,
63
+ ) -> Any: ...
64
+
65
+
66
+ def loads(
67
+ s: bytes | bytearray | memoryview,
68
+ *,
69
+ ext_handlers: dict[int, Callable[[Ext], Any]] | None = None,
70
+ use_ordered_dict: bool = False,
71
+ use_tuple: bool = False,
72
+ allow_invalid_utf8: bool = False,
73
+ max_depth: int | None = None,
74
+ ) -> Any: ...
75
+
76
+
77
+ def load(
78
+ fp: _SupportsRead,
79
+ *,
80
+ ext_handlers: dict[int, Callable[[Ext], Any]] | None = None,
81
+ use_ordered_dict: bool = False,
82
+ use_tuple: bool = False,
83
+ allow_invalid_utf8: bool = False,
84
+ max_depth: int | None = None,
85
+ ) -> Any: ...
86
+
87
+
88
+ class _SupportsRead(Protocol):
89
+ def read(self, __size: int) -> bytes: ...
90
+
91
+
92
+ class _SupportsWrite(Protocol):
93
+ def write(self, __data: bytes) -> Any: ...
94
+
95
+
96
+ class Ext:
97
+ type: int
98
+ data: bytes
99
+ def __init__(self, type: int, data: bytes) -> None: ...
100
+ def __eq__(self, other: object) -> bool: ...
101
+ def __ne__(self, other: object) -> bool: ...
102
+ def __hash__(self) -> int: ...
103
+
104
+
105
+ class InvalidString(bytes): ...
106
+
107
+
108
+ def ext_serializable(ext_type: int) -> Callable[[type[_T]], type[_T]]: ...
109
+
110
+
111
+ class PackException(Exception): ...
112
+ class UnpackException(Exception): ...
113
+ class UnsupportedTypeException(PackException): ...
114
+ class InsufficientDataException(UnpackException): ...
115
+ class InvalidStringException(UnpackException): ...
116
+ class UnsupportedTimestampException(UnpackException): ...
117
+ class ReservedCodeException(UnpackException): ...
118
+ class UnhashableKeyException(UnpackException): ...
119
+ class DuplicateKeyException(UnpackException): ...
120
+ class MaximumDepthException(UnpackException): ...
121
+
122
+
123
+ KeyNotPrimitiveException = UnhashableKeyException
124
+ KeyDuplicateException = DuplicateKeyException
125
+
126
+ compatibility: bool
umsgpack/py.typed ADDED
File without changes
@@ -1,6 +0,0 @@
1
- umsgpack.py,sha256=VWgh4SBZWK060TEiMp4WJeHMv3gzhDYnr7swCxkGlLM,43450
2
- u_msgpack_python-2.7.2.dist-info/LICENSE,sha256=-Tj-LTt7MpAF1LKFHxBv1DUcpV8INjNay-UjhjEvfzE,1099
3
- u_msgpack_python-2.7.2.dist-info/METADATA,sha256=tdNeKjl9_s0IV_nhLk1rddYv51B6LPp5kxrv1cxcm9g,1306
4
- u_msgpack_python-2.7.2.dist-info/WHEEL,sha256=i6ErtKpGt3EuCna4OpOTBhgJrMWAh_eDBLj9VXrKHUE,110
5
- u_msgpack_python-2.7.2.dist-info/top_level.txt,sha256=vlKYkefVvMYiE2tS8E4NKGRXIGIWzQq9ar1A0j2avaA,9
6
- u_msgpack_python-2.7.2.dist-info/RECORD,,