Codebase list python-msgpack / 90be034
Merge tag '1.0.0' into debian/victoria Thomas Goirand 3 years ago
46 changed file(s) with 2082 addition(s) and 1383 deletion(s). Raw diff Collapse all Expand all
0 name: Black
1
2 on: ["push", "pull_request"]
3
4 jobs:
5 black:
6 runs-on: ubuntu-latest
7 steps:
8 - name: Setup Python
9 uses: actions/setup-python@v1
10 with:
11 python-version: '3.x'
12 architecture: 'x64'
13
14 - name: Checkout
15 uses: actions/checkout@v1
16
17 - name: Black Code Formatter
18 run: |
19 pip install black
20 black --diff --check msgpack/ test/ setup.py
0 name: Build and test windows wheels
1 on:
2 push:
3 branches:
4 - master
5 - test
6 pull_request:
7 create:
8
9 jobs:
10 build:
11 runs-on: windows-latest
12 steps:
13 - name: Checkout
14 uses: actions/checkout@v1
15
16 - name: Cythonize
17 shell: bash
18 run: |
19 pip install -U Cython
20 make cython
21 #python setup.py sdist
22
23 - name: Python 3.6 (amd64)
24 env:
25 PYTHON: "py -3.6-64"
26 shell: bash
27 run: |
28 ci/runtests.sh
29
30 - name: Python 3.6 (x86)
31 env:
32 PYTHON: "py -3.6-32"
33 shell: bash
34 run: |
35 ci/runtests.sh
36
37 - name: Python 3.7 (amd64)
38 env:
39 PYTHON: "py -3.7-64"
40 shell: bash
41 run: |
42 ci/runtests.sh
43
44 - name: Python 3.7 (x86)
45 env:
46 PYTHON: "py -3.7-32"
47 shell: bash
48 run: |
49 ci/runtests.sh
50
51 - name: Python 3.8 (amd64)
52 env:
53 PYTHON: "py -3.8-64"
54 shell: bash
55 run: |
56 ci/runtests.sh
57
58 - name: Python 3.8 (x86)
59 env:
60 PYTHON: "py -3.8-32"
61 shell: bash
62 run: |
63 ci/runtests.sh
64
65 - name: Upload Wheels
66 uses: actions/upload-artifact@v1
67 with:
68 name: win-wheels
69 path: ./dist
0 version: ~> 1.0
01 dist: xenial
12 language: python
23 cache: pip
3
4 arch:
5 - amd64
6 - arm64
47 python:
58 # Available Python (PyPy) can be listed by:
69 #
710 # $ aws s3 ls s3://travis-python-archives/binaries/ubuntu/16.04/x86_64/
8 - "2.7"
911 - "3.4"
1012 - "3.5"
1113 - "3.6"
1214 - "3.7"
13 - "3.8-dev"
15 - "3.8"
16 - "3.9-dev"
17
18
19 _pure: &pure
20 install:
21 - pip install -U pip
22 - pip install -U pytest pytest-cov codecov
23 - pip install .
24 script:
25 - pytest --cov=msgpack -v test
1426
1527 matrix:
1628 include:
1729 - name: 32bit build
18 sudo: required
1930 language: python
2031 services:
2132 - docker
2839 - docker pull $DOCKER_IMAGE
2940 script:
3041 - docker run --rm -v `pwd`:/io -w /io $DOCKER_IMAGE /io/docker/runtests.sh
42
43 - arch: arm64
44 name: arm64 32bit build
45 language: python
46 services:
47 - docker
48 env:
49 - DOCKER_IMAGE=quay.io/pypa/manylinux2014_aarch64
50 install:
51 - pip install -U pip
52 - pip install -r requirements.txt
53 - make cython
54 - docker pull $DOCKER_IMAGE
55 script:
56 - docker run --rm -v `pwd`:/io -w /io $DOCKER_IMAGE /io/docker/runtests.sh
57
58 - name: "Python 2 (fallback)"
59 python: "2.7"
60 <<: *pure
61
3162 - name: "pypy2.7"
3263 python: "pypy2.7-7.1.1"
33 install:
34 - pip install -e .
35 script:
36 - py.test -v test
64 <<: *pure
65
3766 - name: "pypy3"
3867 python: "pypy3.6-7.1.1"
39 install:
40 - pip install -e .
41 script:
42 - pytest -v test
43
68 <<: *pure
4469
4570 install:
4671 - pip install -U pip
47 - pip install -U pytest
48 - pip install -r requirements.txt
72 - pip install -U pytest pytest-cov codecov
73 - pip install -r requirements.txt # Cython
4974 - make cython
5075 - pip install -e .
5176
5277 script:
5378 - python -c 'import sys; print(hex(sys.maxsize))'
5479 - python -c 'from msgpack import _cmsgpack'
55 - pytest -v test
56 - MSGPACK_PUREPYTHON=x pytest -v test
80 - pytest --cov=msgpack -v test
81 - MSGPACK_PUREPYTHON=x pytest --cov=msgpack -v test
82
83 after_success:
84 - if [ -f .coverage ]; then
85 codecov;
86 fi
5787
5888 # vim: sw=2 ts=2
0 1.0.0
1 =====
2
3 Release Date: 2020-02-17
4
5 * Remove Python 2 support from the ``msgpack/_cmsgpack``.
6 ``msgpack/fallback`` still supports Python 2.
7 * Remove ``encoding`` option from the Packer and Unpacker.
8 * Unpacker: The default value of ``max_buffer_type`` is changed to 100MiB.
9 * Unpacker: ``strict_map_key`` is True by default now.
10 * Unpacker: String map keys are interned.
11 * Drop old buffer protocol support.
12 * Support Timestamp type.
13 * Support serializing and decerializing ``datetime`` object
14 with tzinfo.
15 * Unpacker: ``Fix Unpacker.read_bytes()`` in fallback implementation. (#352)
16
17
018 0.6.2
119 =====
220
0 # Developer's note
1
2 ## Wheels
3
4 Wheels for macOS and Linux are built on Travis and AppVeyr, in
5 [methane/msgpack-wheels](https://github.com/methane/msgpack-wheels) repository.
6
7 Wheels for Windows are built on Github Actions in this repository.
8
00 include setup.py
11 include COPYING
2 include README.rst
2 include README.md
33 recursive-include msgpack *.h *.c *.pyx *.cpp
44 recursive-include test *.py
00 .PHONY: all
11 all: cython
22 python setup.py build_ext -i -f
3
4 .PHONY: black
5 black:
6 black msgpack/ test/ setup.py
37
48 .PHONY: cython
59 cython:
1822 .PHONY: clean
1923 clean:
2024 rm -rf build
21 rm -f msgpack/_msgpack.cpp
25 rm -f msgpack/_cmsgpack.cpp
26 rm -f msgpack/_cmsgpack.*.so
2227 rm -rf msgpack/__pycache__
2328 rm -rf test/__pycache__
2429
0 # MessagePack for Python
1
2 [![Build Status](https://travis-ci.org/msgpack/msgpack-python.svg?branch=master)](https://travis-ci.org/msgpack/msgpack-python)
3 [![Documentation Status](https://readthedocs.org/projects/msgpack-python/badge/?version=latest)](https://msgpack-python.readthedocs.io/en/latest/?badge=latest)
4
5 ## What's this
6
7 [MessagePack](https://msgpack.org/) is an efficient binary serialization format.
8 It lets you exchange data among multiple languages like JSON.
9 But it's faster and smaller.
10 This package provides CPython bindings for reading and writing MessagePack data.
11
12
13 ## Very important notes for existing users
14
15 ### PyPI package name
16
17 TL;DR: When upgrading from msgpack-0.4 or earlier, don't do `pip install -U msgpack-python`.
18 Do `pip uninstall msgpack-python; pip install msgpack` instead.
19
20 Package name on PyPI was changed to msgpack from 0.5.
21 I upload transitional package (msgpack-python 0.5 which depending on msgpack)
22 for smooth transition from msgpack-python to msgpack.
23
24 Sadly, this doesn't work for upgrade install. After `pip install -U msgpack-python`,
25 msgpack is removed, and `import msgpack` fail.
26
27
28 ### Compatibility with the old format
29
30 You can use `use_bin_type=False` option to pack `bytes`
31 object into raw type in the old msgpack spec, instead of bin type in new msgpack spec.
32
33 You can unpack old msgpack format using `raw=True` option.
34 It unpacks str (raw) type in msgpack into Python bytes.
35
36 See note below for detail.
37
38
39 ### Major breaking changes in msgpack 1.0
40
41 * Python 2
42
43 * The extension module does not support Python 2 anymore.
44 The pure Python implementation (`msgpack.fallback`) is used for Python 2.
45
46 * Packer
47
48 * `use_bin_type=True` by default. bytes are encoded in bin type in msgpack.
49 **If you are still sing Python 2, you must use unicode for all string types.**
50 You can use `use_bin_type=False` to encode into old msgpack format.
51 * `encoding` option is removed. UTF-8 is used always.
52
53 * Unpacker
54
55 * `raw=False` by default. It assumes str types are valid UTF-8 string
56 and decode them to Python str (unicode) object.
57 * `encoding` option is removed. You can use `raw=True` to support old format.
58 * Default value of `max_buffer_size` is changed from 0 to 100 MiB.
59 * Default value of `strict_map_key` is changed to True to avoid hashdos.
60 You need to pass `strict_map_key=False` if you have data which contain map keys
61 which type is not bytes or str.
62
63
64 ## Install
65
66
67 $ pip install msgpack
68
69
70 ### Pure Python implementation
71
72 The extension module in msgpack (`msgpack._cmsgpack`) does not support
73 Python 2 and PyPy.
74
75 But msgpack provides a pure Python implementation (`msgpack.fallback`)
76 for PyPy and Python 2.
77
78 Since the [pip](https://pip.pypa.io/) uses the pure Python implementation,
79 Python 2 support will not be dropped in the foreseeable future.
80
81
82 ### Windows
83
84 When you can't use a binary distribution, you need to install Visual Studio
85 or Windows SDK on Windows.
86 Without extension, using pure Python implementation on CPython runs slowly.
87
88
89 ## How to use
90
91 NOTE: In examples below, I use `raw=False` and `use_bin_type=True` for users
92 using msgpack < 1.0. These options are default from msgpack 1.0 so you can omit them.
93
94
95 ### One-shot pack & unpack
96
97 Use `packb` for packing and `unpackb` for unpacking.
98 msgpack provides `dumps` and `loads` as an alias for compatibility with
99 `json` and `pickle`.
100
101 `pack` and `dump` packs to a file-like object.
102 `unpack` and `load` unpacks from a file-like object.
103
104 ```pycon
105 >>> import msgpack
106 >>> msgpack.packb([1, 2, 3], use_bin_type=True)
107 '\x93\x01\x02\x03'
108 >>> msgpack.unpackb(_, raw=False)
109 [1, 2, 3]
110 ```
111
112 `unpack` unpacks msgpack's array to Python's list, but can also unpack to tuple:
113
114 ```pycon
115 >>> msgpack.unpackb(b'\x93\x01\x02\x03', use_list=False, raw=False)
116 (1, 2, 3)
117 ```
118
119 You should always specify the `use_list` keyword argument for backward compatibility.
120 See performance issues relating to `use_list option`_ below.
121
122 Read the docstring for other options.
123
124
125 ### Streaming unpacking
126
127 `Unpacker` is a "streaming unpacker". It unpacks multiple objects from one
128 stream (or from bytes provided through its `feed` method).
129
130 ```py
131 import msgpack
132 from io import BytesIO
133
134 buf = BytesIO()
135 for i in range(100):
136 buf.write(msgpack.packb(i, use_bin_type=True))
137
138 buf.seek(0)
139
140 unpacker = msgpack.Unpacker(buf, raw=False)
141 for unpacked in unpacker:
142 print(unpacked)
143 ```
144
145
146 ### Packing/unpacking of custom data type
147
148 It is also possible to pack/unpack custom data types. Here is an example for
149 `datetime.datetime`.
150
151 ```py
152 import datetime
153 import msgpack
154
155 useful_dict = {
156 "id": 1,
157 "created": datetime.datetime.now(),
158 }
159
160 def decode_datetime(obj):
161 if b'__datetime__' in obj:
162 obj = datetime.datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%S.%f")
163 return obj
164
165 def encode_datetime(obj):
166 if isinstance(obj, datetime.datetime):
167 return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f")}
168 return obj
169
170
171 packed_dict = msgpack.packb(useful_dict, default=encode_datetime, use_bin_type=True)
172 this_dict_again = msgpack.unpackb(packed_dict, object_hook=decode_datetime, raw=False)
173 ```
174
175 `Unpacker`'s `object_hook` callback receives a dict; the
176 `object_pairs_hook` callback may instead be used to receive a list of
177 key-value pairs.
178
179
180 ### Extended types
181
182 It is also possible to pack/unpack custom data types using the **ext** type.
183
184 ```pycon
185 >>> import msgpack
186 >>> import array
187 >>> def default(obj):
188 ... if isinstance(obj, array.array) and obj.typecode == 'd':
189 ... return msgpack.ExtType(42, obj.tostring())
190 ... raise TypeError("Unknown type: %r" % (obj,))
191 ...
192 >>> def ext_hook(code, data):
193 ... if code == 42:
194 ... a = array.array('d')
195 ... a.fromstring(data)
196 ... return a
197 ... return ExtType(code, data)
198 ...
199 >>> data = array.array('d', [1.2, 3.4])
200 >>> packed = msgpack.packb(data, default=default, use_bin_type=True)
201 >>> unpacked = msgpack.unpackb(packed, ext_hook=ext_hook, raw=False)
202 >>> data == unpacked
203 True
204 ```
205
206
207 ### Advanced unpacking control
208
209 As an alternative to iteration, `Unpacker` objects provide `unpack`,
210 `skip`, `read_array_header` and `read_map_header` methods. The former two
211 read an entire message from the stream, respectively de-serialising and returning
212 the result, or ignoring it. The latter two methods return the number of elements
213 in the upcoming container, so that each element in an array, or key-value pair
214 in a map, can be unpacked or skipped individually.
215
216
217 ## Notes
218
219 ### string and binary type
220
221 Early versions of msgpack didn't distinguish string and binary types.
222 The type for representing both string and binary types was named **raw**.
223
224 You can pack into and unpack from this old spec using `use_bin_type=False`
225 and `raw=True` options.
226
227 ```pycon
228 >>> import msgpack
229 >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs'], use_bin_type=False), raw=True)
230 [b'spam', b'eggs']
231 >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs'], use_bin_type=True), raw=False)
232 [b'spam', 'eggs']
233 ```
234
235 ### ext type
236
237 To use the **ext** type, pass `msgpack.ExtType` object to packer.
238
239 ```pycon
240 >>> import msgpack
241 >>> packed = msgpack.packb(msgpack.ExtType(42, b'xyzzy'))
242 >>> msgpack.unpackb(packed)
243 ExtType(code=42, data='xyzzy')
244 ```
245
246 You can use it with `default` and `ext_hook`. See below.
247
248
249 ### Security
250
251 To unpacking data received from unreliable source, msgpack provides
252 two security options.
253
254 `max_buffer_size` (default: `100*1024*1024`) limits the internal buffer size.
255 It is used to limit the preallocated list size too.
256
257 `strict_map_key` (default: `True`) limits the type of map keys to bytes and str.
258 While msgpack spec doesn't limit the types of the map keys,
259 there is a risk of the hashdos.
260 If you need to support other types for map keys, use `strict_map_key=False`.
261
262
263 ### Performance tips
264
265 CPython's GC starts when growing allocated object.
266 This means unpacking may cause useless GC.
267 You can use `gc.disable()` when unpacking large message.
268
269 List is the default sequence type of Python.
270 But tuple is lighter than list.
271 You can use `use_list=False` while unpacking when performance is important.
272
273
274 ## Development
275
276 ### Test
277
278 MessagePack uses `pytest` for testing.
279 Run test with following command:
280
281 ```
282 $ make test
283 ```
+0
-336
README.rst less more
0 ======================
1 MessagePack for Python
2 ======================
3
4 .. image:: https://travis-ci.org/msgpack/msgpack-python.svg?branch=master
5 :target: https://travis-ci.org/msgpack/msgpack-python
6 :alt: Build Status
7
8 .. image:: https://readthedocs.org/projects/msgpack-python/badge/?version=latest
9 :target: https://msgpack-python.readthedocs.io/en/latest/?badge=latest
10 :alt: Documentation Status
11
12
13 What's this
14 -----------
15
16 `MessagePack <https://msgpack.org/>`_ is an efficient binary serialization format.
17 It lets you exchange data among multiple languages like JSON.
18 But it's faster and smaller.
19 This package provides CPython bindings for reading and writing MessagePack data.
20
21
22 Very important notes for existing users
23 ---------------------------------------
24
25 PyPI package name
26 ^^^^^^^^^^^^^^^^^
27
28 TL;DR: When upgrading from msgpack-0.4 or earlier, don't do `pip install -U msgpack-python`.
29 Do `pip uninstall msgpack-python; pip install msgpack` instead.
30
31 Package name on PyPI was changed to msgpack from 0.5.
32 I upload transitional package (msgpack-python 0.5 which depending on msgpack)
33 for smooth transition from msgpack-python to msgpack.
34
35 Sadly, this doesn't work for upgrade install. After `pip install -U msgpack-python`,
36 msgpack is removed and `import msgpack` fail.
37
38
39 Deprecating encoding option
40 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41
42 encoding and unicode_errors options are deprecated.
43
44 In case of packer, use UTF-8 always. Storing other than UTF-8 is not recommended.
45
46 For backward compatibility, you can use ``use_bin_type=False`` and pack ``bytes``
47 object into msgpack raw type.
48
49 In case of unpacker, there is new ``raw`` option. It is ``True`` by default
50 for backward compatibility, but it is changed to ``False`` in near future.
51 You can use ``raw=False`` instead of ``encoding='utf-8'``.
52
53 Planned backward incompatible changes
54 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
55
56 When msgpack 1.0, I planning these breaking changes:
57
58 * packer and unpacker: Remove ``encoding`` and ``unicode_errors`` option.
59 * packer: Change default of ``use_bin_type`` option from False to True.
60 * unpacker: Change default of ``raw`` option from True to False.
61 * unpacker: Reduce all ``max_xxx_len`` options for typical usage.
62 * unpacker: Remove ``write_bytes`` option from all methods.
63
64 To avoid these breaking changes breaks your application, please:
65
66 * Don't use deprecated options.
67 * Pass ``use_bin_type`` and ``raw`` options explicitly.
68 * If your application handle large (>1MB) data, specify ``max_xxx_len`` options too.
69
70
71 Install
72 -------
73
74 ::
75
76 $ pip install msgpack
77
78 PyPy
79 ^^^^
80
81 msgpack provides a pure Python implementation. PyPy can use this.
82
83 Windows
84 ^^^^^^^
85
86 When you can't use a binary distribution, you need to install Visual Studio
87 or Windows SDK on Windows.
88 Without extension, using pure Python implementation on CPython runs slowly.
89
90 For Python 2.7, `Microsoft Visual C++ Compiler for Python 2.7 <https://www.microsoft.com/en-us/download/details.aspx?id=44266>`_
91 is recommended solution.
92
93 For Python 3.5, `Microsoft Visual Studio 2015 <https://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx>`_
94 Community Edition or Express Edition can be used to build extension module.
95
96
97 How to use
98 ----------
99
100 One-shot pack & unpack
101 ^^^^^^^^^^^^^^^^^^^^^^
102
103 Use ``packb`` for packing and ``unpackb`` for unpacking.
104 msgpack provides ``dumps`` and ``loads`` as an alias for compatibility with
105 ``json`` and ``pickle``.
106
107 ``pack`` and ``dump`` packs to a file-like object.
108 ``unpack`` and ``load`` unpacks from a file-like object.
109
110 .. code-block:: pycon
111
112 >>> import msgpack
113 >>> msgpack.packb([1, 2, 3], use_bin_type=True)
114 '\x93\x01\x02\x03'
115 >>> msgpack.unpackb(_, raw=False)
116 [1, 2, 3]
117
118 ``unpack`` unpacks msgpack's array to Python's list, but can also unpack to tuple:
119
120 .. code-block:: pycon
121
122 >>> msgpack.unpackb(b'\x93\x01\x02\x03', use_list=False, raw=False)
123 (1, 2, 3)
124
125 You should always specify the ``use_list`` keyword argument for backward compatibility.
126 See performance issues relating to `use_list option`_ below.
127
128 Read the docstring for other options.
129
130
131 Streaming unpacking
132 ^^^^^^^^^^^^^^^^^^^
133
134 ``Unpacker`` is a "streaming unpacker". It unpacks multiple objects from one
135 stream (or from bytes provided through its ``feed`` method).
136
137 .. code-block:: python
138
139 import msgpack
140 from io import BytesIO
141
142 buf = BytesIO()
143 for i in range(100):
144 buf.write(msgpack.packb(i, use_bin_type=True))
145
146 buf.seek(0)
147
148 unpacker = msgpack.Unpacker(buf, raw=False)
149 for unpacked in unpacker:
150 print(unpacked)
151
152
153 Packing/unpacking of custom data type
154 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
155
156 It is also possible to pack/unpack custom data types. Here is an example for
157 ``datetime.datetime``.
158
159 .. code-block:: python
160
161 import datetime
162 import msgpack
163
164 useful_dict = {
165 "id": 1,
166 "created": datetime.datetime.now(),
167 }
168
169 def decode_datetime(obj):
170 if b'__datetime__' in obj:
171 obj = datetime.datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%S.%f")
172 return obj
173
174 def encode_datetime(obj):
175 if isinstance(obj, datetime.datetime):
176 return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f")}
177 return obj
178
179
180 packed_dict = msgpack.packb(useful_dict, default=encode_datetime, use_bin_type=True)
181 this_dict_again = msgpack.unpackb(packed_dict, object_hook=decode_datetime, raw=False)
182
183 ``Unpacker``'s ``object_hook`` callback receives a dict; the
184 ``object_pairs_hook`` callback may instead be used to receive a list of
185 key-value pairs.
186
187
188 Extended types
189 ^^^^^^^^^^^^^^
190
191 It is also possible to pack/unpack custom data types using the **ext** type.
192
193 .. code-block:: pycon
194
195 >>> import msgpack
196 >>> import array
197 >>> def default(obj):
198 ... if isinstance(obj, array.array) and obj.typecode == 'd':
199 ... return msgpack.ExtType(42, obj.tostring())
200 ... raise TypeError("Unknown type: %r" % (obj,))
201 ...
202 >>> def ext_hook(code, data):
203 ... if code == 42:
204 ... a = array.array('d')
205 ... a.fromstring(data)
206 ... return a
207 ... return ExtType(code, data)
208 ...
209 >>> data = array.array('d', [1.2, 3.4])
210 >>> packed = msgpack.packb(data, default=default, use_bin_type=True)
211 >>> unpacked = msgpack.unpackb(packed, ext_hook=ext_hook, raw=False)
212 >>> data == unpacked
213 True
214
215
216 Advanced unpacking control
217 ^^^^^^^^^^^^^^^^^^^^^^^^^^
218
219 As an alternative to iteration, ``Unpacker`` objects provide ``unpack``,
220 ``skip``, ``read_array_header`` and ``read_map_header`` methods. The former two
221 read an entire message from the stream, respectively de-serialising and returning
222 the result, or ignoring it. The latter two methods return the number of elements
223 in the upcoming container, so that each element in an array, or key-value pair
224 in a map, can be unpacked or skipped individually.
225
226 Each of these methods may optionally write the packed data it reads to a
227 callback function:
228
229 .. code-block:: python
230
231 from io import BytesIO
232
233 def distribute(unpacker, get_worker):
234 nelems = unpacker.read_map_header()
235 for i in range(nelems):
236 # Select a worker for the given key
237 key = unpacker.unpack()
238 worker = get_worker(key)
239
240 # Send the value as a packed message to worker
241 bytestream = BytesIO()
242 unpacker.skip(bytestream.write)
243 worker.send(bytestream.getvalue())
244
245
246 Notes
247 -----
248
249 string and binary type
250 ^^^^^^^^^^^^^^^^^^^^^^
251
252 Early versions of msgpack didn't distinguish string and binary types (like Python 1).
253 The type for representing both string and binary types was named **raw**.
254
255 For backward compatibility reasons, msgpack-python will still default all
256 strings to byte strings, unless you specify the ``use_bin_type=True`` option in
257 the packer. If you do so, it will use a non-standard type called **bin** to
258 serialize byte arrays, and **raw** becomes to mean **str**. If you want to
259 distinguish **bin** and **raw** in the unpacker, specify ``raw=False``.
260
261 Note that Python 2 defaults to byte-arrays over Unicode strings:
262
263 .. code-block:: pycon
264
265 >>> import msgpack
266 >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs']))
267 ['spam', 'eggs']
268 >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs'], use_bin_type=True),
269 raw=False)
270 ['spam', u'eggs']
271
272 This is the same code in Python 3 (same behaviour, but Python 3 has a
273 different default):
274
275 .. code-block:: pycon
276
277 >>> import msgpack
278 >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs']))
279 [b'spam', b'eggs']
280 >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs'], use_bin_type=True),
281 raw=False)
282 [b'spam', 'eggs']
283
284
285 ext type
286 ^^^^^^^^
287
288 To use the **ext** type, pass ``msgpack.ExtType`` object to packer.
289
290 .. code-block:: pycon
291
292 >>> import msgpack
293 >>> packed = msgpack.packb(msgpack.ExtType(42, b'xyzzy'))
294 >>> msgpack.unpackb(packed)
295 ExtType(code=42, data='xyzzy')
296
297 You can use it with ``default`` and ``ext_hook``. See below.
298
299
300 Note about performance
301 ----------------------
302
303 GC
304 ^^
305
306 CPython's GC starts when growing allocated object.
307 This means unpacking may cause useless GC.
308 You can use ``gc.disable()`` when unpacking large message.
309
310 use_list option
311 ^^^^^^^^^^^^^^^
312
313 List is the default sequence type of Python.
314 But tuple is lighter than list.
315 You can use ``use_list=False`` while unpacking when performance is important.
316
317 Python's dict can't use list as key and MessagePack allows array for key of mapping.
318 ``use_list=False`` allows unpacking such message.
319 Another way to unpacking such object is using ``object_pairs_hook``.
320
321
322 Development
323 -----------
324
325 Test
326 ^^^^
327
328 MessagePack uses `pytest` for testing.
329 Run test with following command:
330
331 $ make test
332
333
334 ..
335 vim: filetype=rst
2828 - ci\\runtests.bat
2929 - set PYTHON="C:\\Python37-x64"
3030 - ci\\runtests.bat
31 - set PYTHON="C:\\Python38"
32 - ci\\runtests.bat
33 - set PYTHON="C:\\Python38-x64"
34 - ci\\runtests.bat
3135
3236 after_test:
3337 # This step builds your wheels.
00 from msgpack import fallback
1
12 try:
23 from msgpack import _unpacker, _packer
4
35 has_ext = True
46 except ImportError:
57 has_ext = False
810
911 def profile(name, func):
1012 times = timeit.repeat(func, number=1000, repeat=4)
11 times = ', '.join(["%8f" % t for t in times])
13 times = ", ".join(["%8f" % t for t in times])
1214 print("%-30s %40s" % (name, times))
1315
1416
1719 packer = _packer.Packer()
1820 profile("packing %s (ext)" % name, lambda: packer.pack(data))
1921 packer = fallback.Packer()
20 profile('packing %s (fallback)' % name, lambda: packer.pack(data))
22 profile("packing %s (fallback)" % name, lambda: packer.pack(data))
2123
2224 data = packer.pack(data)
2325 if has_ext:
24 profile('unpacking %s (ext)' % name, lambda: _unpacker.unpackb(data))
25 profile('unpacking %s (fallback)' % name, lambda: fallback.unpackb(data))
26 profile("unpacking %s (ext)" % name, lambda: _unpacker.unpackb(data))
27 profile("unpacking %s (fallback)" % name, lambda: fallback.unpackb(data))
28
2629
2730 def main():
28 simple("integers", [7]*10000)
29 simple("bytes", [b'x'*n for n in range(100)]*10)
30 simple("lists", [[]]*10000)
31 simple("dicts", [{}]*10000)
31 simple("integers", [7] * 10000)
32 simple("bytes", [b"x" * n for n in range(100)] * 10)
33 simple("lists", [[]] * 10000)
34 simple("dicts", [{}] * 10000)
35
3236
3337 main()
11 %PYTHON%\python.exe setup.py build_ext -i
22 %PYTHON%\python.exe setup.py install
33 %PYTHON%\python.exe -c "import sys; print(hex(sys.maxsize))"
4 %PYTHON%\python.exe -c "from msgpack import _packer, _unpacker"
4 %PYTHON%\python.exe -c "from msgpack import _cmsgpack"
55 %PYTHON%\python.exe setup.py bdist_wheel
66 %PYTHON%\python.exe -m pytest -v test
77 SET EL=%ERRORLEVEL%
0 #!/bin/bash
1 set -ex
2 ${PYTHON} -VV
3 ${PYTHON} -m pip install setuptools wheel pytest
4 ${PYTHON} setup.py build_ext -if
5 ${PYTHON} -c "from msgpack import _cmsgpack"
6 ${PYTHON} setup.py bdist_wheel
7 ${PYTHON} -m pytest -v test
00 #!/bin/bash
1 DOCKER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
2 source "$DOCKER_DIR/shared.env"
3
14 set -e -x
25
36 ARCH=`uname -p`
47 echo "arch=$ARCH"
58
6 for V in cp37-cp37m cp36-cp36m cp35-cp35m cp27-cp27m cp27-cp27mu; do
9 for V in "${PYTHON_VERSIONS[@]}"; do
710 PYBIN=/opt/python/$V/bin
811 rm -rf build/ # Avoid lib build by narrow Python is used by wide python
912 $PYBIN/python setup.py bdist_wheel -p manylinux1_${ARCH}
00 #!/bin/bash
1 DOCKER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
2 source "$DOCKER_DIR/shared.env"
3
14 set -e -x
25
3 for V in cp36-cp36m cp35-cp35m cp27-cp27m cp27-cp27mu; do
6 for V in "${PYTHON_VERSIONS[@]}"; do
47 PYBIN=/opt/python/$V/bin
58 $PYBIN/python setup.py install
69 rm -rf build/ # Avoid lib build by narrow Python is used by wide python
0 PYTHON_VERSIONS=(
1 cp38-cp38
2 cp37-cp37m
3 cp36-cp36m
4 cp35-cp35m
5 )
2626
2727 .. autoclass:: ExtType
2828
29 .. autoclass:: Timestamp
30 :members:
31 :special-members: __init__
32
2933 exceptions
3034 ----------
3135
1515 # If extensions (or modules to document with autodoc) are in another directory,
1616 # add these directories to sys.path here. If the directory is relative to the
1717 # documentation root, use os.path.abspath to make it absolute, like shown here.
18 #sys.path.insert(0, os.path.abspath('.'))
18 # sys.path.insert(0, os.path.abspath('.'))
1919
2020 # -- General configuration -----------------------------------------------------
2121
2222 # If your documentation needs a minimal Sphinx version, state it here.
23 #needs_sphinx = '1.0'
23 # needs_sphinx = '1.0'
2424
2525 # Add any Sphinx extension module names here, as strings. They can be extensions
2626 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
27 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']
27 extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode"]
2828
2929 # Add any paths that contain templates here, relative to this directory.
30 templates_path = ['_templates']
30 templates_path = ["_templates"]
3131
3232 # The suffix of source filenames.
33 source_suffix = '.rst'
33 source_suffix = ".rst"
3434
3535 # The encoding of source files.
36 #source_encoding = 'utf-8-sig'
36 # source_encoding = 'utf-8-sig'
3737
3838 # The master toctree document.
39 master_doc = 'index'
39 master_doc = "index"
4040
4141 # General information about the project.
42 project = u'msgpack'
43 copyright = u'2013, INADA Naoki'
42 project = u"msgpack"
43 copyright = u"2013, INADA Naoki"
4444
4545 # The version info for the project you're documenting, acts as replacement for
4646 # |version| and |release|, also used in various other places throughout the
4848 #
4949 # The short X.Y version.
5050 # The full version, including alpha/beta/rc tags.
51 version = release = '0.5'
51 version = release = "0.5"
5252
5353 # The language for content autogenerated by Sphinx. Refer to documentation
5454 # for a list of supported languages.
55 #language = None
55 # language = None
5656
5757 # There are two options for replacing |today|: either, you set today to some
5858 # non-false value, then it is used:
59 #today = ''
59 # today = ''
6060 # Else, today_fmt is used as the format for a strftime call.
61 #today_fmt = '%B %d, %Y'
61 # today_fmt = '%B %d, %Y'
6262 today_fmt = "%Y-%m-%d"
6363
6464 # List of patterns, relative to source directory, that match files and
6565 # directories to ignore when looking for source files.
66 exclude_patterns = ['_build']
66 exclude_patterns = ["_build"]
6767
6868 # The reST default role (used for this markup: `text`) to use for all documents.
69 #default_role = None
69 # default_role = None
7070
7171 # If true, '()' will be appended to :func: etc. cross-reference text.
72 #add_function_parentheses = True
72 # add_function_parentheses = True
7373
7474 # If true, the current module name will be prepended to all description
7575 # unit titles (such as .. function::).
76 #add_module_names = True
76 # add_module_names = True
7777
7878 # If true, sectionauthor and moduleauthor directives will be shown in the
7979 # output. They are ignored by default.
80 #show_authors = False
80 # show_authors = False
8181
8282 # The name of the Pygments (syntax highlighting) style to use.
83 pygments_style = 'sphinx'
83 pygments_style = "sphinx"
8484
8585 # A list of ignored prefixes for module index sorting.
86 #modindex_common_prefix = []
86 # modindex_common_prefix = []
8787
8888
8989 # -- Options for HTML output ---------------------------------------------------
9090
9191 # The theme to use for HTML and HTML Help pages. See the documentation for
9292 # a list of builtin themes.
93 html_theme = 'sphinxdoc'
93 html_theme = "sphinxdoc"
9494
9595 # Theme options are theme-specific and customize the look and feel of a theme
9696 # further. For a list of options available for each theme, see the
9797 # documentation.
98 #html_theme_options = {}
98 # html_theme_options = {}
9999
100100 # Add any paths that contain custom themes here, relative to this directory.
101 #html_theme_path = []
101 # html_theme_path = []
102102
103103 # The name for this set of Sphinx documents. If None, it defaults to
104104 # "<project> v<release> documentation".
105 #html_title = None
105 # html_title = None
106106
107107 # A shorter title for the navigation bar. Default is the same as html_title.
108 #html_short_title = None
108 # html_short_title = None
109109
110110 # The name of an image file (relative to this directory) to place at the top
111111 # of the sidebar.
112 #html_logo = None
112 # html_logo = None
113113
114114 # The name of an image file (within the static path) to use as favicon of the
115115 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
116116 # pixels large.
117 #html_favicon = None
117 # html_favicon = None
118118
119119 # Add any paths that contain custom static files (such as style sheets) here,
120120 # relative to this directory. They are copied after the builtin static files,
121121 # so a file named "default.css" will overwrite the builtin "default.css".
122 html_static_path = ['_static']
122 html_static_path = ["_static"]
123123
124124 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
125125 # using the given strftime format.
126 #html_last_updated_fmt = '%b %d, %Y'
126 # html_last_updated_fmt = '%b %d, %Y'
127127
128128 # If true, SmartyPants will be used to convert quotes and dashes to
129129 # typographically correct entities.
130 #html_use_smartypants = True
130 # html_use_smartypants = True
131131
132132 # Custom sidebar templates, maps document names to template names.
133 #html_sidebars = {}
133 # html_sidebars = {}
134134
135135 # Additional templates that should be rendered to pages, maps page names to
136136 # template names.
137 #html_additional_pages = {}
137 # html_additional_pages = {}
138138
139139 # If false, no module index is generated.
140 #html_domain_indices = True
140 # html_domain_indices = True
141141
142142 # If false, no index is generated.
143 #html_use_index = True
143 # html_use_index = True
144144
145145 # If true, the index is split into individual pages for each letter.
146 #html_split_index = False
146 # html_split_index = False
147147
148148 # If true, links to the reST sources are added to the pages.
149 #html_show_sourcelink = True
149 # html_show_sourcelink = True
150150
151151 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
152 #html_show_sphinx = True
152 # html_show_sphinx = True
153153
154154 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
155 #html_show_copyright = True
155 # html_show_copyright = True
156156
157157 # If true, an OpenSearch description file will be output, and all pages will
158158 # contain a <link> tag referring to it. The value of this option must be the
159159 # base URL from which the finished HTML is served.
160 #html_use_opensearch = ''
160 # html_use_opensearch = ''
161161
162162 # This is the file name suffix for HTML files (e.g. ".xhtml").
163 #html_file_suffix = None
163 # html_file_suffix = None
164164
165165 # Output file base name for HTML help builder.
166 htmlhelp_basename = 'msgpackdoc'
166 htmlhelp_basename = "msgpackdoc"
167167
168168
169169 # -- Options for LaTeX output --------------------------------------------------
170170
171171 latex_elements = {
172 # The paper size ('letterpaper' or 'a4paper').
173 #'papersize': 'letterpaper',
174
175 # The font size ('10pt', '11pt' or '12pt').
176 #'pointsize': '10pt',
177
178 # Additional stuff for the LaTeX preamble.
179 #'preamble': '',
172 # The paper size ('letterpaper' or 'a4paper').
173 #'papersize': 'letterpaper',
174 # The font size ('10pt', '11pt' or '12pt').
175 #'pointsize': '10pt',
176 # Additional stuff for the LaTeX preamble.
177 #'preamble': '',
180178 }
181179
182180 # Grouping the document tree into LaTeX files. List of tuples
183181 # (source start file, target name, title, author, documentclass [howto/manual]).
184182 latex_documents = [
185 ('index', 'msgpack.tex', u'msgpack Documentation',
186 u'Author', 'manual'),
183 ("index", "msgpack.tex", u"msgpack Documentation", u"Author", "manual"),
187184 ]
188185
189186 # The name of an image file (relative to this directory) to place at the top of
190187 # the title page.
191 #latex_logo = None
188 # latex_logo = None
192189
193190 # For "manual" documents, if this is true, then toplevel headings are parts,
194191 # not chapters.
195 #latex_use_parts = False
192 # latex_use_parts = False
196193
197194 # If true, show page references after internal links.
198 #latex_show_pagerefs = False
195 # latex_show_pagerefs = False
199196
200197 # If true, show URL addresses after external links.
201 #latex_show_urls = False
198 # latex_show_urls = False
202199
203200 # Documents to append as an appendix to all manuals.
204 #latex_appendices = []
201 # latex_appendices = []
205202
206203 # If false, no module index is generated.
207 #latex_domain_indices = True
204 # latex_domain_indices = True
208205
209206
210207 # -- Options for manual page output --------------------------------------------
211208
212209 # One entry per manual page. List of tuples
213210 # (source start file, name, description, authors, manual section).
214 man_pages = [
215 ('index', 'msgpack', u'msgpack Documentation',
216 [u'Author'], 1)
217 ]
211 man_pages = [("index", "msgpack", u"msgpack Documentation", [u"Author"], 1)]
218212
219213 # If true, show URL addresses after external links.
220 #man_show_urls = False
214 # man_show_urls = False
221215
222216
223217 # -- Options for Texinfo output ------------------------------------------------
226220 # (source start file, target name, title, author,
227221 # dir menu entry, description, category)
228222 texinfo_documents = [
229 ('index', 'msgpack', u'msgpack Documentation',
230 u'Author', 'msgpack', 'One line description of project.',
231 'Miscellaneous'),
223 (
224 "index",
225 "msgpack",
226 u"msgpack Documentation",
227 u"Author",
228 "msgpack",
229 "One line description of project.",
230 "Miscellaneous",
231 ),
232232 ]
233233
234234 # Documents to append as an appendix to all manuals.
235 #texinfo_appendices = []
235 # texinfo_appendices = []
236236
237237 # If false, no module index is generated.
238 #texinfo_domain_indices = True
238 # texinfo_domain_indices = True
239239
240240 # How to display URL addresses: 'footnote', 'no', or 'inline'.
241 #texinfo_show_urls = 'footnote'
241 # texinfo_show_urls = 'footnote'
242242
243243
244244 # -- Options for Epub output ---------------------------------------------------
245245
246246 # Bibliographic Dublin Core info.
247 epub_title = u'msgpack'
248 epub_author = u'Author'
249 epub_publisher = u'Author'
250 epub_copyright = u'2013, Author'
247 epub_title = u"msgpack"
248 epub_author = u"Author"
249 epub_publisher = u"Author"
250 epub_copyright = u"2013, Author"
251251
252252 # The language of the text. It defaults to the language option
253253 # or en if the language is not set.
254 #epub_language = ''
254 # epub_language = ''
255255
256256 # The scheme of the identifier. Typical schemes are ISBN or URL.
257 #epub_scheme = ''
257 # epub_scheme = ''
258258
259259 # The unique identifier of the text. This can be a ISBN number
260260 # or the project homepage.
261 #epub_identifier = ''
261 # epub_identifier = ''
262262
263263 # A unique identification for the text.
264 #epub_uid = ''
264 # epub_uid = ''
265265
266266 # A tuple containing the cover image and cover page html template filenames.
267 #epub_cover = ()
267 # epub_cover = ()
268268
269269 # HTML files that should be inserted before the pages created by sphinx.
270270 # The format is a list of tuples containing the path and title.
271 #epub_pre_files = []
271 # epub_pre_files = []
272272
273273 # HTML files shat should be inserted after the pages created by sphinx.
274274 # The format is a list of tuples containing the path and title.
275 #epub_post_files = []
275 # epub_post_files = []
276276
277277 # A list of files that should not be packed into the epub file.
278 #epub_exclude_files = []
278 # epub_exclude_files = []
279279
280280 # The depth of the table of contents in toc.ncx.
281 #epub_tocdepth = 3
281 # epub_tocdepth = 3
282282
283283 # Allow duplicate toc entries.
284 #epub_tocdup = True
284 # epub_tocdup = True
00 # coding: utf-8
11 from ._version import version
22 from .exceptions import *
3 from .ext import ExtType, Timestamp
34
4 from collections import namedtuple
5 import os
6 import sys
57
68
7 class ExtType(namedtuple('ExtType', 'code data')):
8 """ExtType represents ext type in msgpack."""
9 def __new__(cls, code, data):
10 if not isinstance(code, int):
11 raise TypeError("code must be int")
12 if not isinstance(data, bytes):
13 raise TypeError("data must be bytes")
14 if not 0 <= code <= 127:
15 raise ValueError("code must be 0~127")
16 return super(ExtType, cls).__new__(cls, code, data)
17
18
19 import os
20 if os.environ.get('MSGPACK_PUREPYTHON'):
9 if os.environ.get("MSGPACK_PUREPYTHON") or sys.version_info[0] == 2:
2110 from .fallback import Packer, unpackb, Unpacker
2211 else:
2312 try:
00 # coding: utf-8
11 #cython: embedsignature=True, c_string_encoding=ascii, language_level=3
2 from cpython.datetime cimport import_datetime, datetime_new
3 import_datetime()
4
5 import datetime
6 cdef object utc = datetime.timezone.utc
7 cdef object epoch = datetime_new(1970, 1, 1, 0, 0, 0, 0, tz=utc)
8
29 include "_packer.pyx"
310 include "_unpacker.pyx"
11
22 from cpython cimport *
33 from cpython.bytearray cimport PyByteArray_Check, PyByteArray_CheckExact
4 from cpython.datetime cimport (
5 PyDateTime_CheckExact, PyDelta_CheckExact,
6 datetime_tzinfo, timedelta_days, timedelta_seconds, timedelta_microseconds,
7 )
48
59 cdef ExtType
6
7 from . import ExtType
10 cdef Timestamp
11
12 from .ext import ExtType, Timestamp
813
914
1015 cdef extern from "Python.h":
3540 int msgpack_pack_bin(msgpack_packer* pk, size_t l)
3641 int msgpack_pack_raw_body(msgpack_packer* pk, char* body, size_t l)
3742 int msgpack_pack_ext(msgpack_packer* pk, char typecode, size_t l)
43 int msgpack_pack_timestamp(msgpack_packer* x, long long seconds, unsigned long nanoseconds);
3844 int msgpack_pack_unicode(msgpack_packer* pk, object o, long long limit)
3945
4046 cdef extern from "buff_converter.h":
7783
7884 :param bool use_bin_type:
7985 Use bin type introduced in msgpack spec 2.0 for bytes.
80 It also enables str8 type for unicode.
81 Current default value is false, but it will be changed to true
82 in future version. You should specify it explicitly.
86 It also enables str8 type for unicode. (default: True)
8387
8488 :param bool strict_types:
8589 If set to true, types will be checked to be exact. Derived classes
9094 for python types.
9195
9296 :param str unicode_errors:
93 Error handler for encoding unicode. (default: 'strict')
94
95 :param str encoding:
96 (deprecated) Convert unicode to bytes with this encoding. (default: 'utf-8')
97 The error handler for encoding unicode. (default: 'strict')
98 DO NOT USE THIS!! This option is kept for very specific usage.
9799 """
98100 cdef msgpack_packer pk
99101 cdef object _default
100 cdef object _bencoding
101102 cdef object _berrors
102 cdef const char *encoding
103103 cdef const char *unicode_errors
104104 cdef bint strict_types
105 cdef bool use_float
105 cdef bint use_float
106106 cdef bint autoreset
107 cdef bint datetime
107108
108109 def __cinit__(self):
109110 cdef int buf_size = 1024*1024
113114 self.pk.buf_size = buf_size
114115 self.pk.length = 0
115116
116 def __init__(self, default=None, encoding=None, unicode_errors=None,
117 bint use_single_float=False, bint autoreset=True, bint use_bin_type=False,
118 bint strict_types=False):
119 if encoding is not None:
120 PyErr_WarnEx(DeprecationWarning, "encoding is deprecated.", 1)
117 def __init__(self, *, default=None,
118 bint use_single_float=False, bint autoreset=True, bint use_bin_type=True,
119 bint strict_types=False, bint datetime=False, unicode_errors=None):
121120 self.use_float = use_single_float
122121 self.strict_types = strict_types
123122 self.autoreset = autoreset
123 self.datetime = datetime
124124 self.pk.use_bin_type = use_bin_type
125125 if default is not None:
126126 if not PyCallable_Check(default):
127127 raise TypeError("default must be a callable.")
128128 self._default = default
129129
130 self._bencoding = encoding
131 if encoding is None:
132 if PY_MAJOR_VERSION < 3:
133 self.encoding = 'utf-8'
134 else:
135 self.encoding = NULL
136 else:
137 self.encoding = self._bencoding
138
139130 self._berrors = unicode_errors
140131 if unicode_errors is None:
141132 self.unicode_errors = NULL
149140 cdef int _pack(self, object o, int nest_limit=DEFAULT_RECURSE_LIMIT) except -1:
150141 cdef long long llval
151142 cdef unsigned long long ullval
143 cdef unsigned long ulval
152144 cdef long longval
153145 cdef float fval
154146 cdef double dval
166158 while True:
167159 if o is None:
168160 ret = msgpack_pack_nil(&self.pk)
169 elif PyBool_Check(o) if strict_types else isinstance(o, bool):
170 if o:
171 ret = msgpack_pack_true(&self.pk)
172 else:
173 ret = msgpack_pack_false(&self.pk)
161 elif o is True:
162 ret = msgpack_pack_true(&self.pk)
163 elif o is False:
164 ret = msgpack_pack_false(&self.pk)
174165 elif PyLong_CheckExact(o) if strict_types else PyLong_Check(o):
175166 # PyInt_Check(long) is True for Python 3.
176167 # So we should test long before int.
207198 if ret == 0:
208199 ret = msgpack_pack_raw_body(&self.pk, rawval, L)
209200 elif PyUnicode_CheckExact(o) if strict_types else PyUnicode_Check(o):
210 if self.encoding == NULL and self.unicode_errors == NULL:
201 if self.unicode_errors == NULL:
211202 ret = msgpack_pack_unicode(&self.pk, o, ITEM_LIMIT);
212203 if ret == -2:
213204 raise ValueError("unicode string is too large")
214205 else:
215 o = PyUnicode_AsEncodedString(o, self.encoding, self.unicode_errors)
206 o = PyUnicode_AsEncodedString(o, NULL, self.unicode_errors)
216207 L = Py_SIZE(o)
217208 if L > ITEM_LIMIT:
218209 raise ValueError("unicode string is too large")
252243 raise ValueError("EXT data is too large")
253244 ret = msgpack_pack_ext(&self.pk, longval, L)
254245 ret = msgpack_pack_raw_body(&self.pk, rawval, L)
246 elif type(o) is Timestamp:
247 llval = o.seconds
248 ulval = o.nanoseconds
249 ret = msgpack_pack_timestamp(&self.pk, llval, ulval)
255250 elif PyList_CheckExact(o) if strict_types else (PyTuple_Check(o) or PyList_Check(o)):
256251 L = Py_SIZE(o)
257252 if L > ITEM_LIMIT:
272267 if ret == 0:
273268 ret = msgpack_pack_raw_body(&self.pk, <char*>view.buf, L)
274269 PyBuffer_Release(&view);
270 elif self.datetime and PyDateTime_CheckExact(o) and datetime_tzinfo(o) is not None:
271 delta = o - epoch
272 if not PyDelta_CheckExact(delta):
273 raise ValueError("failed to calculate delta")
274 llval = timedelta_days(delta) * <long long>(24*60*60) + timedelta_seconds(delta)
275 ulval = timedelta_microseconds(delta) * 1000
276 ret = msgpack_pack_timestamp(&self.pk, llval, ulval)
275277 elif not default_used and self._default:
276278 o = self._default(o)
277279 default_used = 1
350352 def reset(self):
351353 """Reset internal buffer.
352354
353 This method is usaful only when autoreset=False.
355 This method is useful only when autoreset=False.
354356 """
355357 self.pk.length = 0
356358
00 # coding: utf-8
11
22 from cpython cimport *
3
43 cdef extern from "Python.h":
54 ctypedef struct PyObject
65 cdef int PyObject_AsReadBuffer(object o, const void** buff, Py_ssize_t* buf_len) except -1
1817 FormatError,
1918 StackError,
2019 )
21 from . import ExtType
20 from .ext import ExtType, Timestamp
21
22 cdef object giga = 1_000_000_000
2223
2324
2425 cdef extern from "unpack.h":
2728 bint raw
2829 bint has_pairs_hook # call object_hook with k-v pairs
2930 bint strict_map_key
31 int timestamp
3032 PyObject* object_hook
3133 PyObject* list_hook
3234 PyObject* ext_hook
33 char *encoding
35 PyObject* timestamp_t
36 PyObject *giga;
37 PyObject *utc;
3438 char *unicode_errors
3539 Py_ssize_t max_str_len
3640 Py_ssize_t max_bin_len
5660 cdef inline init_ctx(unpack_context *ctx,
5761 object object_hook, object object_pairs_hook,
5862 object list_hook, object ext_hook,
59 bint use_list, bint raw, bint strict_map_key,
60 const char* encoding, const char* unicode_errors,
63 bint use_list, bint raw, int timestamp,
64 bint strict_map_key,
65 const char* unicode_errors,
6166 Py_ssize_t max_str_len, Py_ssize_t max_bin_len,
6267 Py_ssize_t max_array_len, Py_ssize_t max_map_len,
6368 Py_ssize_t max_ext_len):
98103 raise TypeError("ext_hook must be a callable.")
99104 ctx.user.ext_hook = <PyObject*>ext_hook
100105
101 ctx.user.encoding = encoding
106 if timestamp < 0 or 3 < timestamp:
107 raise ValueError("timestamp must be 0..3")
108
109 # Add Timestamp type to the user object so it may be used in unpack.h
110 ctx.user.timestamp = timestamp
111 ctx.user.timestamp_t = <PyObject*>Timestamp
112 ctx.user.giga = <PyObject*>giga
113 ctx.user.utc = <PyObject*>utc
102114 ctx.user.unicode_errors = unicode_errors
103115
104116 def default_read_extended_type(typecode, data):
107119 cdef inline int get_data_from_buffer(object obj,
108120 Py_buffer *view,
109121 char **buf,
110 Py_ssize_t *buffer_len,
111 int *new_protocol) except 0:
122 Py_ssize_t *buffer_len) except 0:
112123 cdef object contiguous
113124 cdef Py_buffer tmp
114 if PyObject_CheckBuffer(obj):
115 new_protocol[0] = 1
116 if PyObject_GetBuffer(obj, view, PyBUF_FULL_RO) == -1:
117 raise
118 if view.itemsize != 1:
119 PyBuffer_Release(view)
120 raise BufferError("cannot unpack from multi-byte object")
121 if PyBuffer_IsContiguous(view, b'A') == 0:
122 PyBuffer_Release(view)
123 # create a contiguous copy and get buffer
124 contiguous = PyMemoryView_GetContiguous(obj, PyBUF_READ, b'C')
125 PyObject_GetBuffer(contiguous, view, PyBUF_SIMPLE)
126 # view must hold the only reference to contiguous,
127 # so memory is freed when view is released
128 Py_DECREF(contiguous)
129 buffer_len[0] = view.len
130 buf[0] = <char*> view.buf
131 return 1
132 else:
133 new_protocol[0] = 0
134 if PyObject_AsReadBuffer(obj, <const void**> buf, buffer_len) == -1:
135 raise BufferError("could not get memoryview")
136 PyErr_WarnEx(RuntimeWarning,
137 "using old buffer interface to unpack %s; "
138 "this leads to unpacking errors if slicing is used and "
139 "will be removed in a future version" % type(obj),
140 1)
141 return 1
142
143 def unpackb(object packed, object object_hook=None, object list_hook=None,
144 bint use_list=True, bint raw=True, bint strict_map_key=False,
145 encoding=None, unicode_errors=None,
125 if PyObject_GetBuffer(obj, view, PyBUF_FULL_RO) == -1:
126 raise
127 if view.itemsize != 1:
128 PyBuffer_Release(view)
129 raise BufferError("cannot unpack from multi-byte object")
130 if PyBuffer_IsContiguous(view, b'A') == 0:
131 PyBuffer_Release(view)
132 # create a contiguous copy and get buffer
133 contiguous = PyMemoryView_GetContiguous(obj, PyBUF_READ, b'C')
134 PyObject_GetBuffer(contiguous, view, PyBUF_SIMPLE)
135 # view must hold the only reference to contiguous,
136 # so memory is freed when view is released
137 Py_DECREF(contiguous)
138 buffer_len[0] = view.len
139 buf[0] = <char*> view.buf
140 return 1
141
142
143 def unpackb(object packed, *, object object_hook=None, object list_hook=None,
144 bint use_list=True, bint raw=False, int timestamp=0, bint strict_map_key=True,
145 unicode_errors=None,
146146 object_pairs_hook=None, ext_hook=ExtType,
147147 Py_ssize_t max_str_len=-1,
148148 Py_ssize_t max_bin_len=-1,
169169 cdef Py_buffer view
170170 cdef char* buf = NULL
171171 cdef Py_ssize_t buf_len
172 cdef const char* cenc = NULL
173172 cdef const char* cerr = NULL
174 cdef int new_protocol = 0
175
176 if encoding is not None:
177 PyErr_WarnEx(DeprecationWarning, "encoding is deprecated, Use raw=False instead.", 1)
178 cenc = encoding
179173
180174 if unicode_errors is not None:
181175 cerr = unicode_errors
182176
183 get_data_from_buffer(packed, &view, &buf, &buf_len, &new_protocol)
177 get_data_from_buffer(packed, &view, &buf, &buf_len)
184178
185179 if max_str_len == -1:
186180 max_str_len = buf_len
195189
196190 try:
197191 init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, ext_hook,
198 use_list, raw, strict_map_key, cenc, cerr,
192 use_list, raw, timestamp, strict_map_key, cerr,
199193 max_str_len, max_bin_len, max_array_len, max_map_len, max_ext_len)
200194 ret = unpack_construct(&ctx, buf, buf_len, &off)
201195 finally:
202 if new_protocol:
203 PyBuffer_Release(&view);
196 PyBuffer_Release(&view);
204197
205198 if ret == 1:
206199 obj = unpack_data(&ctx)
217210 raise ValueError("Unpack failed: error = %d" % (ret,))
218211
219212
220 def unpack(object stream, **kwargs):
221 PyErr_WarnEx(
222 DeprecationWarning,
223 "Direct calling implementation's unpack() is deprecated, Use msgpack.unpack() or unpackb() instead.", 1)
224 data = stream.read()
225 return unpackb(data, **kwargs)
226
227
228213 cdef class Unpacker(object):
229214 """Streaming unpacker.
230215
242227 Otherwise, unpack to Python tuple. (default: True)
243228
244229 :param bool raw:
245 If true, unpack msgpack raw to Python bytes (default).
246 Otherwise, unpack to Python str (or unicode on Python 2) by decoding
247 with UTF-8 encoding (recommended).
248 Currently, the default is true, but it will be changed to false in
249 near future. So you must specify it explicitly for keeping backward
250 compatibility.
251
252 *encoding* option which is deprecated overrides this option.
230 If true, unpack msgpack raw to Python bytes.
231 Otherwise, unpack to Python str by decoding with UTF-8 encoding (default).
253232
254233 :param bool strict_map_key:
255 If true, only str or bytes are accepted for map (dict) keys.
256 It's False by default for backward-compatibility.
257 But it will be True from msgpack 1.0.
234 If true (default), only str or bytes are accepted for map (dict) keys.
258235
259236 :param callable object_hook:
260237 When specified, it should be callable.
267244 (See also simplejson)
268245
269246 :param int max_buffer_size:
270 Limits size of data waiting unpacked. 0 means system's INT_MAX (default).
247 Limits size of data waiting unpacked. 0 means system's INT_MAX.
248 The default value is 100*1024*1024 (100MiB).
271249 Raises `BufferFull` exception when it is insufficient.
272250 You should set this parameter when unpacking data from untrusted source.
273251
274252 :param int max_str_len:
275253 Deprecated, use *max_buffer_size* instead.
276 Limits max length of str. (default: max_buffer_size or 1024*1024)
254 Limits max length of str. (default: max_buffer_size)
277255
278256 :param int max_bin_len:
279257 Deprecated, use *max_buffer_size* instead.
280 Limits max length of bin. (default: max_buffer_size or 1024*1024)
258 Limits max length of bin. (default: max_buffer_size)
281259
282260 :param int max_array_len:
283 Limits max length of array. (default: max_buffer_size or 128*1024)
261 Limits max length of array. (default: max_buffer_size)
284262
285263 :param int max_map_len:
286 Limits max length of map. (default: max_buffer_size//2 or 32*1024)
264 Limits max length of map. (default: max_buffer_size//2)
287265
288266 :param int max_ext_len:
289267 Deprecated, use *max_buffer_size* instead.
290 Limits max size of ext type. (default: max_buffer_size or 1024*1024)
291
292 :param str encoding:
293 Deprecated, use ``raw=False`` instead.
294 Encoding used for decoding msgpack raw.
295 If it is None (default), msgpack raw is deserialized to Python bytes.
268 Limits max size of ext type. (default: max_buffer_size)
296269
297270 :param str unicode_errors:
298271 Error handler used for decoding str type. (default: `'strict'`)
300273
301274 Example of streaming deserialize from file-like object::
302275
303 unpacker = Unpacker(file_like, raw=False, max_buffer_size=10*1024*1024)
276 unpacker = Unpacker(file_like)
304277 for o in unpacker:
305278 process(o)
306279
307280 Example of streaming deserialize from socket::
308281
309 unpacker = Unpacker(raw=False, max_buffer_size=10*1024*1024)
282 unpacker = Unpacker()
310283 while True:
311284 buf = sock.recv(1024**2)
312285 if not buf:
329302 cdef Py_ssize_t read_size
330303 # To maintain refcnt.
331304 cdef object object_hook, object_pairs_hook, list_hook, ext_hook
332 cdef object encoding, unicode_errors
305 cdef object unicode_errors
333306 cdef Py_ssize_t max_buffer_size
334307 cdef uint64_t stream_offset
335308
340313 PyMem_Free(self.buf)
341314 self.buf = NULL
342315
343 def __init__(self, file_like=None, Py_ssize_t read_size=0,
344 bint use_list=True, bint raw=True, bint strict_map_key=False,
316 def __init__(self, file_like=None, *, Py_ssize_t read_size=0,
317 bint use_list=True, bint raw=False, int timestamp=0, bint strict_map_key=True,
345318 object object_hook=None, object object_pairs_hook=None, object list_hook=None,
346 encoding=None, unicode_errors=None, Py_ssize_t max_buffer_size=0,
319 unicode_errors=None, Py_ssize_t max_buffer_size=100*1024*1024,
347320 object ext_hook=ExtType,
348321 Py_ssize_t max_str_len=-1,
349322 Py_ssize_t max_bin_len=-1,
350323 Py_ssize_t max_array_len=-1,
351324 Py_ssize_t max_map_len=-1,
352325 Py_ssize_t max_ext_len=-1):
353 cdef const char *cenc=NULL,
354326 cdef const char *cerr=NULL
355327
356328 self.object_hook = object_hook
364336 if not PyCallable_Check(self.file_like_read):
365337 raise TypeError("`file_like.read` must be a callable.")
366338
367 if max_str_len == -1:
368 max_str_len = max_buffer_size or 1024*1024
369 if max_bin_len == -1:
370 max_bin_len = max_buffer_size or 1024*1024
371 if max_array_len == -1:
372 max_array_len = max_buffer_size or 128*1024
373 if max_map_len == -1:
374 max_map_len = max_buffer_size//2 or 32*1024
375 if max_ext_len == -1:
376 max_ext_len = max_buffer_size or 1024*1024
377
378339 if not max_buffer_size:
379340 max_buffer_size = INT_MAX
341 if max_str_len == -1:
342 max_str_len = max_buffer_size
343 if max_bin_len == -1:
344 max_bin_len = max_buffer_size
345 if max_array_len == -1:
346 max_array_len = max_buffer_size
347 if max_map_len == -1:
348 max_map_len = max_buffer_size//2
349 if max_ext_len == -1:
350 max_ext_len = max_buffer_size
351
380352 if read_size > max_buffer_size:
381353 raise ValueError("read_size should be less or equal to max_buffer_size")
382354 if not read_size:
383355 read_size = min(max_buffer_size, 1024**2)
356
384357 self.max_buffer_size = max_buffer_size
385358 self.read_size = read_size
386359 self.buf = <char*>PyMem_Malloc(read_size)
391364 self.buf_tail = 0
392365 self.stream_offset = 0
393366
394 if encoding is not None:
395 PyErr_WarnEx(DeprecationWarning, "encoding is deprecated, Use raw=False instead.", 1)
396 self.encoding = encoding
397 cenc = encoding
398
399367 if unicode_errors is not None:
400368 self.unicode_errors = unicode_errors
401369 cerr = unicode_errors
402370
403371 init_ctx(&self.ctx, object_hook, object_pairs_hook, list_hook,
404 ext_hook, use_list, raw, strict_map_key, cenc, cerr,
372 ext_hook, use_list, raw, timestamp, strict_map_key, cerr,
405373 max_str_len, max_bin_len, max_array_len,
406374 max_map_len, max_ext_len)
407375
408376 def feed(self, object next_bytes):
409377 """Append `next_bytes` to internal buffer."""
410378 cdef Py_buffer pybuff
411 cdef int new_protocol = 0
412379 cdef char* buf
413380 cdef Py_ssize_t buf_len
414381
416383 raise AssertionError(
417384 "unpacker.feed() is not be able to use with `file_like`.")
418385
419 get_data_from_buffer(next_bytes, &pybuff, &buf, &buf_len, &new_protocol)
386 get_data_from_buffer(next_bytes, &pybuff, &buf, &buf_len)
420387 try:
421388 self.append_buffer(buf, buf_len)
422389 finally:
423 if new_protocol:
424 PyBuffer_Release(&pybuff)
390 PyBuffer_Release(&pybuff)
425391
426392 cdef append_buffer(self, void* _buf, Py_ssize_t _buf_len):
427393 cdef:
0 version = (0, 6, 2)
0 version = (1, 0, 0)
00 #include "Python.h"
11
22 /* cython does not support this preprocessor check => write it in raw C */
3 #if PY_MAJOR_VERSION == 2
4 static PyObject *
5 buff_to_buff(char *buff, Py_ssize_t size)
6 {
7 return PyBuffer_FromMemory(buff, size);
8 }
9
10 #elif (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION >= 3)
113 static PyObject *
124 buff_to_buff(char *buff, Py_ssize_t size)
135 {
146 return PyMemoryView_FromMemory(buff, size, PyBUF_READ);
157 }
16 #else
17 static PyObject *
18 buff_to_buff(char *buff, Py_ssize_t size)
19 {
20 Py_buffer pybuf;
21 if (PyBuffer_FillInfo(&pybuf, NULL, buff, size, 1, PyBUF_FULL_RO) == -1) {
22 return NULL;
23 }
24
25 return PyMemoryView_FromBuffer(&pybuf);
26 }
27 #endif
0 # coding: utf-8
1 from collections import namedtuple
2 import datetime
3 import sys
4 import struct
5
6
7 PY2 = sys.version_info[0] == 2
8
9 if PY2:
10 int_types = (int, long)
11 _utc = None
12 else:
13 int_types = int
14 try:
15 _utc = datetime.timezone.utc
16 except AttributeError:
17 _utc = datetime.timezone(datetime.timedelta(0))
18
19
20 class ExtType(namedtuple("ExtType", "code data")):
21 """ExtType represents ext type in msgpack."""
22
23 def __new__(cls, code, data):
24 if not isinstance(code, int):
25 raise TypeError("code must be int")
26 if not isinstance(data, bytes):
27 raise TypeError("data must be bytes")
28 if not 0 <= code <= 127:
29 raise ValueError("code must be 0~127")
30 return super(ExtType, cls).__new__(cls, code, data)
31
32
33 class Timestamp(object):
34 """Timestamp represents the Timestamp extension type in msgpack.
35
36 When built with Cython, msgpack uses C methods to pack and unpack `Timestamp`. When using pure-Python
37 msgpack, :func:`to_bytes` and :func:`from_bytes` are used to pack and unpack `Timestamp`.
38
39 This class is immutable: Do not override seconds and nanoseconds.
40 """
41
42 __slots__ = ["seconds", "nanoseconds"]
43
44 def __init__(self, seconds, nanoseconds=0):
45 """Initialize a Timestamp object.
46
47 :param int seconds:
48 Number of seconds since the UNIX epoch (00:00:00 UTC Jan 1 1970, minus leap seconds).
49 May be negative.
50
51 :param int nanoseconds:
52 Number of nanoseconds to add to `seconds` to get fractional time.
53 Maximum is 999_999_999. Default is 0.
54
55 Note: Negative times (before the UNIX epoch) are represented as negative seconds + positive ns.
56 """
57 if not isinstance(seconds, int_types):
58 raise TypeError("seconds must be an interger")
59 if not isinstance(nanoseconds, int_types):
60 raise TypeError("nanoseconds must be an integer")
61 if not (0 <= nanoseconds < 10 ** 9):
62 raise ValueError(
63 "nanoseconds must be a non-negative integer less than 999999999."
64 )
65 self.seconds = seconds
66 self.nanoseconds = nanoseconds
67
68 def __repr__(self):
69 """String representation of Timestamp."""
70 return "Timestamp(seconds={0}, nanoseconds={1})".format(
71 self.seconds, self.nanoseconds
72 )
73
74 def __eq__(self, other):
75 """Check for equality with another Timestamp object"""
76 if type(other) is self.__class__:
77 return (
78 self.seconds == other.seconds and self.nanoseconds == other.nanoseconds
79 )
80 return False
81
82 def __ne__(self, other):
83 """not-equals method (see :func:`__eq__()`)"""
84 return not self.__eq__(other)
85
86 def __hash__(self):
87 return hash((self.seconds, self.nanoseconds))
88
89 @staticmethod
90 def from_bytes(b):
91 """Unpack bytes into a `Timestamp` object.
92
93 Used for pure-Python msgpack unpacking.
94
95 :param b: Payload from msgpack ext message with code -1
96 :type b: bytes
97
98 :returns: Timestamp object unpacked from msgpack ext payload
99 :rtype: Timestamp
100 """
101 if len(b) == 4:
102 seconds = struct.unpack("!L", b)[0]
103 nanoseconds = 0
104 elif len(b) == 8:
105 data64 = struct.unpack("!Q", b)[0]
106 seconds = data64 & 0x00000003FFFFFFFF
107 nanoseconds = data64 >> 34
108 elif len(b) == 12:
109 nanoseconds, seconds = struct.unpack("!Iq", b)
110 else:
111 raise ValueError(
112 "Timestamp type can only be created from 32, 64, or 96-bit byte objects"
113 )
114 return Timestamp(seconds, nanoseconds)
115
116 def to_bytes(self):
117 """Pack this Timestamp object into bytes.
118
119 Used for pure-Python msgpack packing.
120
121 :returns data: Payload for EXT message with code -1 (timestamp type)
122 :rtype: bytes
123 """
124 if (self.seconds >> 34) == 0: # seconds is non-negative and fits in 34 bits
125 data64 = self.nanoseconds << 34 | self.seconds
126 if data64 & 0xFFFFFFFF00000000 == 0:
127 # nanoseconds is zero and seconds < 2**32, so timestamp 32
128 data = struct.pack("!L", data64)
129 else:
130 # timestamp 64
131 data = struct.pack("!Q", data64)
132 else:
133 # timestamp 96
134 data = struct.pack("!Iq", self.nanoseconds, self.seconds)
135 return data
136
137 @staticmethod
138 def from_unix(unix_sec):
139 """Create a Timestamp from posix timestamp in seconds.
140
141 :param unix_float: Posix timestamp in seconds.
142 :type unix_float: int or float.
143 """
144 seconds = int(unix_sec // 1)
145 nanoseconds = int((unix_sec % 1) * 10 ** 9)
146 return Timestamp(seconds, nanoseconds)
147
148 def to_unix(self):
149 """Get the timestamp as a floating-point value.
150
151 :returns: posix timestamp
152 :rtype: float
153 """
154 return self.seconds + self.nanoseconds / 1e9
155
156 @staticmethod
157 def from_unix_nano(unix_ns):
158 """Create a Timestamp from posix timestamp in nanoseconds.
159
160 :param int unix_ns: Posix timestamp in nanoseconds.
161 :rtype: Timestamp
162 """
163 return Timestamp(*divmod(unix_ns, 10 ** 9))
164
165 def to_unix_nano(self):
166 """Get the timestamp as a unixtime in nanoseconds.
167
168 :returns: posix timestamp in nanoseconds
169 :rtype: int
170 """
171 return self.seconds * 10 ** 9 + self.nanoseconds
172
173 def to_datetime(self):
174 """Get the timestamp as a UTC datetime.
175
176 Python 2 is not supported.
177
178 :rtype: datetime.
179 """
180 return datetime.datetime.fromtimestamp(self.to_unix(), _utc)
181
182 @staticmethod
183 def from_datetime(dt):
184 """Create a Timestamp from datetime with tzinfo.
185
186 Python 2 is not supported.
187
188 :rtype: Timestamp
189 """
190 return Timestamp.from_unix(dt.timestamp())
00 """Fallback pure Python implementation of msgpack"""
11
2 from datetime import datetime as _DateTime
23 import sys
34 import struct
4 import warnings
5
6
7 if sys.version_info[0] == 2:
8 PY2 = True
5
6
7 PY2 = sys.version_info[0] == 2
8 if PY2:
99 int_types = (int, long)
10
1011 def dict_iteritems(d):
1112 return d.iteritems()
13
14
1215 else:
13 PY2 = False
1416 int_types = int
1517 unicode = str
1618 xrange = range
19
1720 def dict_iteritems(d):
1821 return d.items()
22
1923
2024 if sys.version_info < (3, 5):
2125 # Ugly hack...
2226 RecursionError = RuntimeError
2327
2428 def _is_recursionerror(e):
25 return len(e.args) == 1 and isinstance(e.args[0], str) and \
26 e.args[0].startswith('maximum recursion depth exceeded')
29 return (
30 len(e.args) == 1
31 and isinstance(e.args[0], str)
32 and e.args[0].startswith("maximum recursion depth exceeded")
33 )
34
35
2736 else:
37
2838 def _is_recursionerror(e):
2939 return True
3040
31 if hasattr(sys, 'pypy_version_info'):
32 # cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own
41
42 if hasattr(sys, "pypy_version_info"):
43 # StringIO is slow on PyPy, StringIO is faster. However: PyPy's own
3344 # StringBuilder is fastest.
3445 from __pypy__ import newlist_hint
46
3547 try:
3648 from __pypy__.builders import BytesBuilder as StringBuilder
3749 except ImportError:
3850 from __pypy__.builders import StringBuilder
3951 USING_STRINGBUILDER = True
52
4053 class StringIO(object):
41 def __init__(self, s=b''):
54 def __init__(self, s=b""):
4255 if s:
4356 self.builder = StringBuilder(len(s))
4457 self.builder.append(s)
4558 else:
4659 self.builder = StringBuilder()
60
4761 def write(self, s):
4862 if isinstance(s, memoryview):
4963 s = s.tobytes()
5064 elif isinstance(s, bytearray):
5165 s = bytes(s)
5266 self.builder.append(s)
67
5368 def getvalue(self):
5469 return self.builder.build()
70
71
5572 else:
5673 USING_STRINGBUILDER = False
5774 from io import BytesIO as StringIO
75
5876 newlist_hint = lambda size: []
5977
6078
61 from .exceptions import (
62 BufferFull,
63 OutOfData,
64 ExtraData,
65 FormatError,
66 StackError,
67 )
68
69 from . import ExtType
70
71
72 EX_SKIP = 0
73 EX_CONSTRUCT = 1
74 EX_READ_ARRAY_HEADER = 2
75 EX_READ_MAP_HEADER = 3
76
77 TYPE_IMMEDIATE = 0
78 TYPE_ARRAY = 1
79 TYPE_MAP = 2
80 TYPE_RAW = 3
81 TYPE_BIN = 4
82 TYPE_EXT = 5
79 from .exceptions import BufferFull, OutOfData, ExtraData, FormatError, StackError
80
81 from .ext import ExtType, Timestamp
82
83
84 EX_SKIP = 0
85 EX_CONSTRUCT = 1
86 EX_READ_ARRAY_HEADER = 2
87 EX_READ_MAP_HEADER = 3
88
89 TYPE_IMMEDIATE = 0
90 TYPE_ARRAY = 1
91 TYPE_MAP = 2
92 TYPE_RAW = 3
93 TYPE_BIN = 4
94 TYPE_EXT = 5
8395
8496 DEFAULT_RECURSE_LIMIT = 511
8597
92104
93105
94106 def _get_data_from_buffer(obj):
95 try:
96 view = memoryview(obj)
97 except TypeError:
98 # try to use legacy buffer protocol if 2.7, otherwise re-raise
99 if PY2:
100 view = memoryview(buffer(obj))
101 warnings.warn("using old buffer interface to unpack %s; "
102 "this leads to unpacking errors if slicing is used and "
103 "will be removed in a future version" % type(obj),
104 RuntimeWarning, stacklevel=3)
105 else:
106 raise
107 view = memoryview(obj)
107108 if view.itemsize != 1:
108109 raise ValueError("cannot unpack from multi-byte object")
109110 return view
110
111
112 def unpack(stream, **kwargs):
113 warnings.warn(
114 "Direct calling implementation's unpack() is deprecated, Use msgpack.unpack() or unpackb() instead.",
115 DeprecationWarning, stacklevel=2)
116 data = stream.read()
117 return unpackb(data, **kwargs)
118111
119112
120113 def unpackb(packed, **kwargs):
145138
146139
147140 if sys.version_info < (2, 7, 6):
141
148142 def _unpack_from(f, b, o=0):
149 """Explicit typcast for legacy struct.unpack_from"""
143 """Explicit type cast for legacy struct.unpack_from"""
150144 return struct.unpack_from(f, bytes(b), o)
145
146
151147 else:
152148 _unpack_from = struct.unpack_from
153149
155151 class Unpacker(object):
156152 """Streaming unpacker.
157153
158 arguments:
154 Arguments:
159155
160156 :param file_like:
161157 File-like object having `.read(n)` method.
169165 Otherwise, unpack to Python tuple. (default: True)
170166
171167 :param bool raw:
172 If true, unpack msgpack raw to Python bytes (default).
173 Otherwise, unpack to Python str (or unicode on Python 2) by decoding
174 with UTF-8 encoding (recommended).
175 Currently, the default is true, but it will be changed to false in
176 near future. So you must specify it explicitly for keeping backward
177 compatibility.
178
179 *encoding* option which is deprecated overrides this option.
168 If true, unpack msgpack raw to Python bytes.
169 Otherwise, unpack to Python str by decoding with UTF-8 encoding (default).
170
171 :param int timestamp:
172 Control how timestamp type is unpacked:
173
174 0 - Timestamp
175 1 - float (Seconds from the EPOCH)
176 2 - int (Nanoseconds from the EPOCH)
177 3 - datetime.datetime (UTC). Python 2 is not supported.
180178
181179 :param bool strict_map_key:
182 If true, only str or bytes are accepted for map (dict) keys.
183 It's False by default for backward-compatibility.
184 But it will be True from msgpack 1.0.
180 If true (default), only str or bytes are accepted for map (dict) keys.
185181
186182 :param callable object_hook:
187183 When specified, it should be callable.
193189 Unpacker calls it with a list of key-value pairs after unpacking msgpack map.
194190 (See also simplejson)
195191
196 :param str encoding:
197 Encoding used for decoding msgpack raw.
198 If it is None (default), msgpack raw is deserialized to Python bytes.
199
200192 :param str unicode_errors:
201 (deprecated) Used for decoding msgpack raw with *encoding*.
202 (default: `'strict'`)
193 The error handler for decoding unicode. (default: 'strict')
194 This option should be used only when you have msgpack data which
195 contains invalid UTF-8 string.
203196
204197 :param int max_buffer_size:
205 Limits size of data waiting unpacked. 0 means system's INT_MAX (default).
198 Limits size of data waiting unpacked. 0 means 2**32-1.
199 The default value is 100*1024*1024 (100MiB).
206200 Raises `BufferFull` exception when it is insufficient.
207201 You should set this parameter when unpacking data from untrusted source.
208202
209203 :param int max_str_len:
210204 Deprecated, use *max_buffer_size* instead.
211 Limits max length of str. (default: max_buffer_size or 1024*1024)
205 Limits max length of str. (default: max_buffer_size)
212206
213207 :param int max_bin_len:
214208 Deprecated, use *max_buffer_size* instead.
215 Limits max length of bin. (default: max_buffer_size or 1024*1024)
209 Limits max length of bin. (default: max_buffer_size)
216210
217211 :param int max_array_len:
218212 Limits max length of array.
219 (default: max_buffer_size or 128*1024)
213 (default: max_buffer_size)
220214
221215 :param int max_map_len:
222216 Limits max length of map.
223 (default: max_buffer_size//2 or 32*1024)
217 (default: max_buffer_size//2)
224218
225219 :param int max_ext_len:
226220 Deprecated, use *max_buffer_size* instead.
227 Limits max size of ext type. (default: max_buffer_size or 1024*1024)
221 Limits max size of ext type. (default: max_buffer_size)
228222
229223 Example of streaming deserialize from file-like object::
230224
231 unpacker = Unpacker(file_like, raw=False, max_buffer_size=10*1024*1024)
225 unpacker = Unpacker(file_like)
232226 for o in unpacker:
233227 process(o)
234228
235229 Example of streaming deserialize from socket::
236230
237 unpacker = Unpacker(raw=False, max_buffer_size=10*1024*1024)
231 unpacker = Unpacker(max_buffer_size)
238232 while True:
239233 buf = sock.recv(1024**2)
240234 if not buf:
250244 Other exceptions can be raised during unpacking.
251245 """
252246
253 def __init__(self, file_like=None, read_size=0, use_list=True, raw=True, strict_map_key=False,
254 object_hook=None, object_pairs_hook=None, list_hook=None,
255 encoding=None, unicode_errors=None, max_buffer_size=0,
256 ext_hook=ExtType,
257 max_str_len=-1,
258 max_bin_len=-1,
259 max_array_len=-1,
260 max_map_len=-1,
261 max_ext_len=-1):
262 if encoding is not None:
263 warnings.warn(
264 "encoding is deprecated, Use raw=False instead.",
265 DeprecationWarning, stacklevel=2)
266
247 def __init__(
248 self,
249 file_like=None,
250 read_size=0,
251 use_list=True,
252 raw=False,
253 timestamp=0,
254 strict_map_key=True,
255 object_hook=None,
256 object_pairs_hook=None,
257 list_hook=None,
258 unicode_errors=None,
259 max_buffer_size=100 * 1024 * 1024,
260 ext_hook=ExtType,
261 max_str_len=-1,
262 max_bin_len=-1,
263 max_array_len=-1,
264 max_map_len=-1,
265 max_ext_len=-1,
266 ):
267267 if unicode_errors is None:
268 unicode_errors = 'strict'
268 unicode_errors = "strict"
269269
270270 if file_like is None:
271271 self._feeding = True
289289 # state, which _buf_checkpoint records.
290290 self._buf_checkpoint = 0
291291
292 if not max_buffer_size:
293 max_buffer_size = 2 ** 31 - 1
292294 if max_str_len == -1:
293 max_str_len = max_buffer_size or 1024*1024
295 max_str_len = max_buffer_size
294296 if max_bin_len == -1:
295 max_bin_len = max_buffer_size or 1024*1024
297 max_bin_len = max_buffer_size
296298 if max_array_len == -1:
297 max_array_len = max_buffer_size or 128*1024
299 max_array_len = max_buffer_size
298300 if max_map_len == -1:
299 max_map_len = max_buffer_size//2 or 32*1024
301 max_map_len = max_buffer_size // 2
300302 if max_ext_len == -1:
301 max_ext_len = max_buffer_size or 1024*1024
302
303 self._max_buffer_size = max_buffer_size or 2**31-1
303 max_ext_len = max_buffer_size
304
305 self._max_buffer_size = max_buffer_size
304306 if read_size > self._max_buffer_size:
305307 raise ValueError("read_size must be smaller than max_buffer_size")
306 self._read_size = read_size or min(self._max_buffer_size, 16*1024)
308 self._read_size = read_size or min(self._max_buffer_size, 16 * 1024)
307309 self._raw = bool(raw)
308310 self._strict_map_key = bool(strict_map_key)
309 self._encoding = encoding
310311 self._unicode_errors = unicode_errors
311312 self._use_list = use_list
313 if not (0 <= timestamp <= 3):
314 raise ValueError("timestamp must be 0..3")
315 self._timestamp = timestamp
312316 self._list_hook = list_hook
313317 self._object_hook = object_hook
314318 self._object_pairs_hook = object_pairs_hook
321325 self._stream_offset = 0
322326
323327 if list_hook is not None and not callable(list_hook):
324 raise TypeError('`list_hook` is not callable')
328 raise TypeError("`list_hook` is not callable")
325329 if object_hook is not None and not callable(object_hook):
326 raise TypeError('`object_hook` is not callable')
330 raise TypeError("`object_hook` is not callable")
327331 if object_pairs_hook is not None and not callable(object_pairs_hook):
328 raise TypeError('`object_pairs_hook` is not callable')
332 raise TypeError("`object_pairs_hook` is not callable")
329333 if object_hook is not None and object_pairs_hook is not None:
330 raise TypeError("object_pairs_hook and object_hook are mutually "
331 "exclusive")
334 raise TypeError(
335 "object_pairs_hook and object_hook are mutually " "exclusive"
336 )
332337 if not callable(ext_hook):
333338 raise TypeError("`ext_hook` is not callable")
334339
335340 def feed(self, next_bytes):
336341 assert self._feeding
337342 view = _get_data_from_buffer(next_bytes)
338 if (len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size):
343 if len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size:
339344 raise BufferFull
340345
341346 # Strip buffer before checkpoint before reading file.
342347 if self._buf_checkpoint > 0:
343 del self._buffer[:self._buf_checkpoint]
348 del self._buffer[: self._buf_checkpoint]
344349 self._buff_i -= self._buf_checkpoint
345350 self._buf_checkpoint = 0
346351
356361 return self._buff_i < len(self._buffer)
357362
358363 def _get_extradata(self):
359 return self._buffer[self._buff_i:]
364 return self._buffer[self._buff_i :]
360365
361366 def read_bytes(self, n):
362 return self._read(n)
367 ret = self._read(n)
368 self._consume()
369 return ret
363370
364371 def _read(self, n):
365372 # (int) -> bytearray
366373 self._reserve(n)
367374 i = self._buff_i
368 self._buff_i = i+n
369 return self._buffer[i:i+n]
375 self._buff_i = i + n
376 return self._buffer[i : i + n]
370377
371378 def _reserve(self, n):
372379 remain_bytes = len(self._buffer) - self._buff_i - n
381388
382389 # Strip buffer before checkpoint before reading file.
383390 if self._buf_checkpoint > 0:
384 del self._buffer[:self._buf_checkpoint]
391 del self._buffer[: self._buf_checkpoint]
385392 self._buff_i -= self._buf_checkpoint
386393 self._buf_checkpoint = 0
387394
410417 if b & 0b10000000 == 0:
411418 obj = b
412419 elif b & 0b11100000 == 0b11100000:
413 obj = -1 - (b ^ 0xff)
420 obj = -1 - (b ^ 0xFF)
414421 elif b & 0b11100000 == 0b10100000:
415422 n = b & 0b00011111
416423 typ = TYPE_RAW
427434 typ = TYPE_MAP
428435 if n > self._max_map_len:
429436 raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
430 elif b == 0xc0:
437 elif b == 0xC0:
431438 obj = None
432 elif b == 0xc2:
439 elif b == 0xC2:
433440 obj = False
434 elif b == 0xc3:
441 elif b == 0xC3:
435442 obj = True
436 elif b == 0xc4:
443 elif b == 0xC4:
437444 typ = TYPE_BIN
438445 self._reserve(1)
439446 n = self._buffer[self._buff_i]
441448 if n > self._max_bin_len:
442449 raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
443450 obj = self._read(n)
444 elif b == 0xc5:
451 elif b == 0xC5:
445452 typ = TYPE_BIN
446453 self._reserve(2)
447454 n = _unpack_from(">H", self._buffer, self._buff_i)[0]
449456 if n > self._max_bin_len:
450457 raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
451458 obj = self._read(n)
452 elif b == 0xc6:
459 elif b == 0xC6:
453460 typ = TYPE_BIN
454461 self._reserve(4)
455462 n = _unpack_from(">I", self._buffer, self._buff_i)[0]
457464 if n > self._max_bin_len:
458465 raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
459466 obj = self._read(n)
460 elif b == 0xc7: # ext 8
467 elif b == 0xC7: # ext 8
461468 typ = TYPE_EXT
462469 self._reserve(2)
463 L, n = _unpack_from('Bb', self._buffer, self._buff_i)
470 L, n = _unpack_from("Bb", self._buffer, self._buff_i)
464471 self._buff_i += 2
465472 if L > self._max_ext_len:
466473 raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
467474 obj = self._read(L)
468 elif b == 0xc8: # ext 16
475 elif b == 0xC8: # ext 16
469476 typ = TYPE_EXT
470477 self._reserve(3)
471 L, n = _unpack_from('>Hb', self._buffer, self._buff_i)
478 L, n = _unpack_from(">Hb", self._buffer, self._buff_i)
472479 self._buff_i += 3
473480 if L > self._max_ext_len:
474481 raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
475482 obj = self._read(L)
476 elif b == 0xc9: # ext 32
483 elif b == 0xC9: # ext 32
477484 typ = TYPE_EXT
478485 self._reserve(5)
479 L, n = _unpack_from('>Ib', self._buffer, self._buff_i)
486 L, n = _unpack_from(">Ib", self._buffer, self._buff_i)
480487 self._buff_i += 5
481488 if L > self._max_ext_len:
482489 raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
483490 obj = self._read(L)
484 elif b == 0xca:
491 elif b == 0xCA:
485492 self._reserve(4)
486493 obj = _unpack_from(">f", self._buffer, self._buff_i)[0]
487494 self._buff_i += 4
488 elif b == 0xcb:
495 elif b == 0xCB:
489496 self._reserve(8)
490497 obj = _unpack_from(">d", self._buffer, self._buff_i)[0]
491498 self._buff_i += 8
492 elif b == 0xcc:
499 elif b == 0xCC:
493500 self._reserve(1)
494501 obj = self._buffer[self._buff_i]
495502 self._buff_i += 1
496 elif b == 0xcd:
503 elif b == 0xCD:
497504 self._reserve(2)
498505 obj = _unpack_from(">H", self._buffer, self._buff_i)[0]
499506 self._buff_i += 2
500 elif b == 0xce:
507 elif b == 0xCE:
501508 self._reserve(4)
502509 obj = _unpack_from(">I", self._buffer, self._buff_i)[0]
503510 self._buff_i += 4
504 elif b == 0xcf:
511 elif b == 0xCF:
505512 self._reserve(8)
506513 obj = _unpack_from(">Q", self._buffer, self._buff_i)[0]
507514 self._buff_i += 8
508 elif b == 0xd0:
515 elif b == 0xD0:
509516 self._reserve(1)
510517 obj = _unpack_from("b", self._buffer, self._buff_i)[0]
511518 self._buff_i += 1
512 elif b == 0xd1:
519 elif b == 0xD1:
513520 self._reserve(2)
514521 obj = _unpack_from(">h", self._buffer, self._buff_i)[0]
515522 self._buff_i += 2
516 elif b == 0xd2:
523 elif b == 0xD2:
517524 self._reserve(4)
518525 obj = _unpack_from(">i", self._buffer, self._buff_i)[0]
519526 self._buff_i += 4
520 elif b == 0xd3:
527 elif b == 0xD3:
521528 self._reserve(8)
522529 obj = _unpack_from(">q", self._buffer, self._buff_i)[0]
523530 self._buff_i += 8
524 elif b == 0xd4: # fixext 1
531 elif b == 0xD4: # fixext 1
525532 typ = TYPE_EXT
526533 if self._max_ext_len < 1:
527534 raise ValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len))
528535 self._reserve(2)
529536 n, obj = _unpack_from("b1s", self._buffer, self._buff_i)
530537 self._buff_i += 2
531 elif b == 0xd5: # fixext 2
538 elif b == 0xD5: # fixext 2
532539 typ = TYPE_EXT
533540 if self._max_ext_len < 2:
534541 raise ValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len))
535542 self._reserve(3)
536543 n, obj = _unpack_from("b2s", self._buffer, self._buff_i)
537544 self._buff_i += 3
538 elif b == 0xd6: # fixext 4
545 elif b == 0xD6: # fixext 4
539546 typ = TYPE_EXT
540547 if self._max_ext_len < 4:
541548 raise ValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len))
542549 self._reserve(5)
543550 n, obj = _unpack_from("b4s", self._buffer, self._buff_i)
544551 self._buff_i += 5
545 elif b == 0xd7: # fixext 8
552 elif b == 0xD7: # fixext 8
546553 typ = TYPE_EXT
547554 if self._max_ext_len < 8:
548555 raise ValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len))
549556 self._reserve(9)
550557 n, obj = _unpack_from("b8s", self._buffer, self._buff_i)
551558 self._buff_i += 9
552 elif b == 0xd8: # fixext 16
559 elif b == 0xD8: # fixext 16
553560 typ = TYPE_EXT
554561 if self._max_ext_len < 16:
555562 raise ValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len))
556563 self._reserve(17)
557564 n, obj = _unpack_from("b16s", self._buffer, self._buff_i)
558565 self._buff_i += 17
559 elif b == 0xd9:
566 elif b == 0xD9:
560567 typ = TYPE_RAW
561568 self._reserve(1)
562569 n = self._buffer[self._buff_i]
564571 if n > self._max_str_len:
565572 raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
566573 obj = self._read(n)
567 elif b == 0xda:
574 elif b == 0xDA:
568575 typ = TYPE_RAW
569576 self._reserve(2)
570 n, = _unpack_from(">H", self._buffer, self._buff_i)
577 (n,) = _unpack_from(">H", self._buffer, self._buff_i)
571578 self._buff_i += 2
572579 if n > self._max_str_len:
573580 raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
574581 obj = self._read(n)
575 elif b == 0xdb:
582 elif b == 0xDB:
576583 typ = TYPE_RAW
577584 self._reserve(4)
578 n, = _unpack_from(">I", self._buffer, self._buff_i)
585 (n,) = _unpack_from(">I", self._buffer, self._buff_i)
579586 self._buff_i += 4
580587 if n > self._max_str_len:
581588 raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
582589 obj = self._read(n)
583 elif b == 0xdc:
590 elif b == 0xDC:
584591 typ = TYPE_ARRAY
585592 self._reserve(2)
586 n, = _unpack_from(">H", self._buffer, self._buff_i)
593 (n,) = _unpack_from(">H", self._buffer, self._buff_i)
587594 self._buff_i += 2
588595 if n > self._max_array_len:
589596 raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len)
590 elif b == 0xdd:
597 elif b == 0xDD:
591598 typ = TYPE_ARRAY
592599 self._reserve(4)
593 n, = _unpack_from(">I", self._buffer, self._buff_i)
600 (n,) = _unpack_from(">I", self._buffer, self._buff_i)
594601 self._buff_i += 4
595602 if n > self._max_array_len:
596603 raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len)
597 elif b == 0xde:
604 elif b == 0xDE:
598605 self._reserve(2)
599 n, = _unpack_from(">H", self._buffer, self._buff_i)
606 (n,) = _unpack_from(">H", self._buffer, self._buff_i)
600607 self._buff_i += 2
601608 if n > self._max_map_len:
602609 raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
603610 typ = TYPE_MAP
604 elif b == 0xdf:
611 elif b == 0xDF:
605612 self._reserve(4)
606 n, = _unpack_from(">I", self._buffer, self._buff_i)
613 (n,) = _unpack_from(">I", self._buffer, self._buff_i)
607614 self._buff_i += 4
608615 if n > self._max_map_len:
609616 raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
646653 return
647654 if self._object_pairs_hook is not None:
648655 ret = self._object_pairs_hook(
649 (self._unpack(EX_CONSTRUCT),
650 self._unpack(EX_CONSTRUCT))
651 for _ in xrange(n))
656 (self._unpack(EX_CONSTRUCT), self._unpack(EX_CONSTRUCT))
657 for _ in xrange(n)
658 )
652659 else:
653660 ret = {}
654661 for _ in xrange(n):
655662 key = self._unpack(EX_CONSTRUCT)
656663 if self._strict_map_key and type(key) not in (unicode, bytes):
657 raise ValueError("%s is not allowed for map key" % str(type(key)))
664 raise ValueError(
665 "%s is not allowed for map key" % str(type(key))
666 )
667 if not PY2 and type(key) is str:
668 key = sys.intern(key)
658669 ret[key] = self._unpack(EX_CONSTRUCT)
659670 if self._object_hook is not None:
660671 ret = self._object_hook(ret)
662673 if execute == EX_SKIP:
663674 return
664675 if typ == TYPE_RAW:
665 if self._encoding is not None:
666 obj = obj.decode(self._encoding, self._unicode_errors)
667 elif self._raw:
676 if self._raw:
668677 obj = bytes(obj)
669678 else:
670 obj = obj.decode('utf_8')
679 obj = obj.decode("utf_8", self._unicode_errors)
671680 return obj
672 if typ == TYPE_EXT:
673 return self._ext_hook(n, bytes(obj))
674681 if typ == TYPE_BIN:
675682 return bytes(obj)
683 if typ == TYPE_EXT:
684 if n == -1: # timestamp
685 ts = Timestamp.from_bytes(bytes(obj))
686 if self._timestamp == 1:
687 return ts.to_unix()
688 elif self._timestamp == 2:
689 return ts.to_unix_nano()
690 elif self._timestamp == 3:
691 return ts.to_datetime()
692 else:
693 return ts
694 else:
695 return self._ext_hook(n, bytes(obj))
676696 assert typ == TYPE_IMMEDIATE
677697 return obj
678698
722742 """
723743 MessagePack Packer
724744
725 usage:
745 Usage:
726746
727747 packer = Packer()
728748 astream.write(packer.pack(a))
743763
744764 :param bool use_bin_type:
745765 Use bin type introduced in msgpack spec 2.0 for bytes.
746 It also enables str8 type for unicode.
766 It also enables str8 type for unicode. (default: True)
747767
748768 :param bool strict_types:
749769 If set to true, types will be checked to be exact. Derived classes
750 from serializeable types will not be serialized and will be
770 from serializable types will not be serialized and will be
751771 treated as unsupported type and forwarded to default.
752772 Additionally tuples will not be serialized as lists.
753773 This is useful when trying to implement accurate serialization
754774 for python types.
755775
756 :param str encoding:
757 (deprecated) Convert unicode to bytes with this encoding. (default: 'utf-8')
776 :param bool datetime:
777 If set to true, datetime with tzinfo is packed into Timestamp type.
778 Note that the tzinfo is stripped in the timestamp.
779 You can get UTC datetime with `timestamp=3` option of the Unpacker.
780 (Python 2 is not supported).
758781
759782 :param str unicode_errors:
760 Error handler for encoding unicode. (default: 'strict')
783 The error handler for encoding unicode. (default: 'strict')
784 DO NOT USE THIS!! This option is kept for very specific usage.
761785 """
762 def __init__(self, default=None, encoding=None, unicode_errors=None,
763 use_single_float=False, autoreset=True, use_bin_type=False,
764 strict_types=False):
765 if encoding is None:
766 encoding = 'utf_8'
767 else:
768 warnings.warn(
769 "encoding is deprecated, Use raw=False instead.",
770 DeprecationWarning, stacklevel=2)
771
772 if unicode_errors is None:
773 unicode_errors = 'strict'
774
786
787 def __init__(
788 self,
789 default=None,
790 use_single_float=False,
791 autoreset=True,
792 use_bin_type=True,
793 strict_types=False,
794 datetime=False,
795 unicode_errors=None,
796 ):
775797 self._strict_types = strict_types
776798 self._use_float = use_single_float
777799 self._autoreset = autoreset
778800 self._use_bin_type = use_bin_type
779 self._encoding = encoding
780 self._unicode_errors = unicode_errors
781801 self._buffer = StringIO()
802 if PY2 and datetime:
803 raise ValueError("datetime is not supported in Python 2")
804 self._datetime = bool(datetime)
805 self._unicode_errors = unicode_errors or "strict"
782806 if default is not None:
783807 if not callable(default):
784808 raise TypeError("default must be callable")
785809 self._default = default
786810
787 def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT,
788 check=isinstance, check_type_strict=_check_type_strict):
811 def _pack(
812 self,
813 obj,
814 nest_limit=DEFAULT_RECURSE_LIMIT,
815 check=isinstance,
816 check_type_strict=_check_type_strict,
817 ):
789818 default_used = False
790819 if self._strict_types:
791820 check = check_type_strict
806835 return self._buffer.write(struct.pack("B", obj))
807836 if -0x20 <= obj < 0:
808837 return self._buffer.write(struct.pack("b", obj))
809 if 0x80 <= obj <= 0xff:
810 return self._buffer.write(struct.pack("BB", 0xcc, obj))
838 if 0x80 <= obj <= 0xFF:
839 return self._buffer.write(struct.pack("BB", 0xCC, obj))
811840 if -0x80 <= obj < 0:
812 return self._buffer.write(struct.pack(">Bb", 0xd0, obj))
813 if 0xff < obj <= 0xffff:
814 return self._buffer.write(struct.pack(">BH", 0xcd, obj))
841 return self._buffer.write(struct.pack(">Bb", 0xD0, obj))
842 if 0xFF < obj <= 0xFFFF:
843 return self._buffer.write(struct.pack(">BH", 0xCD, obj))
815844 if -0x8000 <= obj < -0x80:
816 return self._buffer.write(struct.pack(">Bh", 0xd1, obj))
817 if 0xffff < obj <= 0xffffffff:
818 return self._buffer.write(struct.pack(">BI", 0xce, obj))
845 return self._buffer.write(struct.pack(">Bh", 0xD1, obj))
846 if 0xFFFF < obj <= 0xFFFFFFFF:
847 return self._buffer.write(struct.pack(">BI", 0xCE, obj))
819848 if -0x80000000 <= obj < -0x8000:
820 return self._buffer.write(struct.pack(">Bi", 0xd2, obj))
821 if 0xffffffff < obj <= 0xffffffffffffffff:
822 return self._buffer.write(struct.pack(">BQ", 0xcf, obj))
849 return self._buffer.write(struct.pack(">Bi", 0xD2, obj))
850 if 0xFFFFFFFF < obj <= 0xFFFFFFFFFFFFFFFF:
851 return self._buffer.write(struct.pack(">BQ", 0xCF, obj))
823852 if -0x8000000000000000 <= obj < -0x80000000:
824 return self._buffer.write(struct.pack(">Bq", 0xd3, obj))
853 return self._buffer.write(struct.pack(">Bq", 0xD3, obj))
825854 if not default_used and self._default is not None:
826855 obj = self._default(obj)
827856 default_used = True
829858 raise OverflowError("Integer value out of range")
830859 if check(obj, (bytes, bytearray)):
831860 n = len(obj)
832 if n >= 2**32:
861 if n >= 2 ** 32:
833862 raise ValueError("%s is too large" % type(obj).__name__)
834863 self._pack_bin_header(n)
835864 return self._buffer.write(obj)
836865 if check(obj, unicode):
837 if self._encoding is None:
838 raise TypeError(
839 "Can't encode unicode string: "
840 "no encoding is specified")
841 obj = obj.encode(self._encoding, self._unicode_errors)
866 obj = obj.encode("utf-8", self._unicode_errors)
842867 n = len(obj)
843 if n >= 2**32:
868 if n >= 2 ** 32:
844869 raise ValueError("String is too large")
845870 self._pack_raw_header(n)
846871 return self._buffer.write(obj)
847872 if check(obj, memoryview):
848873 n = len(obj) * obj.itemsize
849 if n >= 2**32:
874 if n >= 2 ** 32:
850875 raise ValueError("Memoryview is too large")
851876 self._pack_bin_header(n)
852877 return self._buffer.write(obj)
853878 if check(obj, float):
854879 if self._use_float:
855 return self._buffer.write(struct.pack(">Bf", 0xca, obj))
856 return self._buffer.write(struct.pack(">Bd", 0xcb, obj))
857 if check(obj, ExtType):
858 code = obj.code
859 data = obj.data
880 return self._buffer.write(struct.pack(">Bf", 0xCA, obj))
881 return self._buffer.write(struct.pack(">Bd", 0xCB, obj))
882 if check(obj, (ExtType, Timestamp)):
883 if check(obj, Timestamp):
884 code = -1
885 data = obj.to_bytes()
886 else:
887 code = obj.code
888 data = obj.data
860889 assert isinstance(code, int)
861890 assert isinstance(data, bytes)
862891 L = len(data)
863892 if L == 1:
864 self._buffer.write(b'\xd4')
893 self._buffer.write(b"\xd4")
865894 elif L == 2:
866 self._buffer.write(b'\xd5')
895 self._buffer.write(b"\xd5")
867896 elif L == 4:
868 self._buffer.write(b'\xd6')
897 self._buffer.write(b"\xd6")
869898 elif L == 8:
870 self._buffer.write(b'\xd7')
899 self._buffer.write(b"\xd7")
871900 elif L == 16:
872 self._buffer.write(b'\xd8')
873 elif L <= 0xff:
874 self._buffer.write(struct.pack(">BB", 0xc7, L))
875 elif L <= 0xffff:
876 self._buffer.write(struct.pack(">BH", 0xc8, L))
901 self._buffer.write(b"\xd8")
902 elif L <= 0xFF:
903 self._buffer.write(struct.pack(">BB", 0xC7, L))
904 elif L <= 0xFFFF:
905 self._buffer.write(struct.pack(">BH", 0xC8, L))
877906 else:
878 self._buffer.write(struct.pack(">BI", 0xc9, L))
907 self._buffer.write(struct.pack(">BI", 0xC9, L))
879908 self._buffer.write(struct.pack("b", code))
880909 self._buffer.write(data)
881910 return
886915 self._pack(obj[i], nest_limit - 1)
887916 return
888917 if check(obj, dict):
889 return self._pack_map_pairs(len(obj), dict_iteritems(obj),
890 nest_limit - 1)
918 return self._pack_map_pairs(
919 len(obj), dict_iteritems(obj), nest_limit - 1
920 )
921
922 if self._datetime and check(obj, _DateTime):
923 obj = Timestamp.from_datetime(obj)
924 default_used = 1
925 continue
926
891927 if not default_used and self._default is not None:
892928 obj = self._default(obj)
893929 default_used = 1
894930 continue
895 raise TypeError("Cannot serialize %r" % (obj, ))
931 raise TypeError("Cannot serialize %r" % (obj,))
896932
897933 def pack(self, obj):
898934 try:
913949 return ret
914950
915951 def pack_array_header(self, n):
916 if n >= 2**32:
952 if n >= 2 ** 32:
917953 raise ValueError
918954 self._pack_array_header(n)
919955 if self._autoreset:
922958 return ret
923959
924960 def pack_map_header(self, n):
925 if n >= 2**32:
961 if n >= 2 ** 32:
926962 raise ValueError
927963 self._pack_map_header(n)
928964 if self._autoreset:
938974 if not isinstance(data, bytes):
939975 raise TypeError("data must have bytes type")
940976 L = len(data)
941 if L > 0xffffffff:
977 if L > 0xFFFFFFFF:
942978 raise ValueError("Too large data")
943979 if L == 1:
944 self._buffer.write(b'\xd4')
980 self._buffer.write(b"\xd4")
945981 elif L == 2:
946 self._buffer.write(b'\xd5')
982 self._buffer.write(b"\xd5")
947983 elif L == 4:
948 self._buffer.write(b'\xd6')
984 self._buffer.write(b"\xd6")
949985 elif L == 8:
950 self._buffer.write(b'\xd7')
986 self._buffer.write(b"\xd7")
951987 elif L == 16:
952 self._buffer.write(b'\xd8')
953 elif L <= 0xff:
954 self._buffer.write(b'\xc7' + struct.pack('B', L))
955 elif L <= 0xffff:
956 self._buffer.write(b'\xc8' + struct.pack('>H', L))
988 self._buffer.write(b"\xd8")
989 elif L <= 0xFF:
990 self._buffer.write(b"\xc7" + struct.pack("B", L))
991 elif L <= 0xFFFF:
992 self._buffer.write(b"\xc8" + struct.pack(">H", L))
957993 else:
958 self._buffer.write(b'\xc9' + struct.pack('>I', L))
959 self._buffer.write(struct.pack('B', typecode))
994 self._buffer.write(b"\xc9" + struct.pack(">I", L))
995 self._buffer.write(struct.pack("B", typecode))
960996 self._buffer.write(data)
961997
962998 def _pack_array_header(self, n):
963 if n <= 0x0f:
964 return self._buffer.write(struct.pack('B', 0x90 + n))
965 if n <= 0xffff:
966 return self._buffer.write(struct.pack(">BH", 0xdc, n))
967 if n <= 0xffffffff:
968 return self._buffer.write(struct.pack(">BI", 0xdd, n))
999 if n <= 0x0F:
1000 return self._buffer.write(struct.pack("B", 0x90 + n))
1001 if n <= 0xFFFF:
1002 return self._buffer.write(struct.pack(">BH", 0xDC, n))
1003 if n <= 0xFFFFFFFF:
1004 return self._buffer.write(struct.pack(">BI", 0xDD, n))
9691005 raise ValueError("Array is too large")
9701006
9711007 def _pack_map_header(self, n):
972 if n <= 0x0f:
973 return self._buffer.write(struct.pack('B', 0x80 + n))
974 if n <= 0xffff:
975 return self._buffer.write(struct.pack(">BH", 0xde, n))
976 if n <= 0xffffffff:
977 return self._buffer.write(struct.pack(">BI", 0xdf, n))
1008 if n <= 0x0F:
1009 return self._buffer.write(struct.pack("B", 0x80 + n))
1010 if n <= 0xFFFF:
1011 return self._buffer.write(struct.pack(">BH", 0xDE, n))
1012 if n <= 0xFFFFFFFF:
1013 return self._buffer.write(struct.pack(">BI", 0xDF, n))
9781014 raise ValueError("Dict is too large")
9791015
9801016 def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT):
9841020 self._pack(v, nest_limit - 1)
9851021
9861022 def _pack_raw_header(self, n):
987 if n <= 0x1f:
988 self._buffer.write(struct.pack('B', 0xa0 + n))
989 elif self._use_bin_type and n <= 0xff:
990 self._buffer.write(struct.pack('>BB', 0xd9, n))
991 elif n <= 0xffff:
992 self._buffer.write(struct.pack(">BH", 0xda, n))
993 elif n <= 0xffffffff:
994 self._buffer.write(struct.pack(">BI", 0xdb, n))
1023 if n <= 0x1F:
1024 self._buffer.write(struct.pack("B", 0xA0 + n))
1025 elif self._use_bin_type and n <= 0xFF:
1026 self._buffer.write(struct.pack(">BB", 0xD9, n))
1027 elif n <= 0xFFFF:
1028 self._buffer.write(struct.pack(">BH", 0xDA, n))
1029 elif n <= 0xFFFFFFFF:
1030 self._buffer.write(struct.pack(">BI", 0xDB, n))
9951031 else:
996 raise ValueError('Raw is too large')
1032 raise ValueError("Raw is too large")
9971033
9981034 def _pack_bin_header(self, n):
9991035 if not self._use_bin_type:
10001036 return self._pack_raw_header(n)
1001 elif n <= 0xff:
1002 return self._buffer.write(struct.pack('>BB', 0xc4, n))
1003 elif n <= 0xffff:
1004 return self._buffer.write(struct.pack(">BH", 0xc5, n))
1005 elif n <= 0xffffffff:
1006 return self._buffer.write(struct.pack(">BI", 0xc6, n))
1037 elif n <= 0xFF:
1038 return self._buffer.write(struct.pack(">BB", 0xC4, n))
1039 elif n <= 0xFFFF:
1040 return self._buffer.write(struct.pack(">BH", 0xC5, n))
1041 elif n <= 0xFFFFFFFF:
1042 return self._buffer.write(struct.pack(">BI", 0xC6, n))
10071043 else:
1008 raise ValueError('Bin is too large')
1044 raise ValueError("Bin is too large")
10091045
10101046 def bytes(self):
10111047 """Return internal buffer contents as bytes object"""
10141050 def reset(self):
10151051 """Reset internal buffer.
10161052
1017 This method is usaful only when autoreset=False.
1053 This method is useful only when autoreset=False.
10181054 """
10191055 self._buffer = StringIO()
10201056
758758
759759 }
760760
761 /*
762 * Pack Timestamp extension type. Follows msgpack-c pack_template.h.
763 */
764 static inline int msgpack_pack_timestamp(msgpack_packer* x, int64_t seconds, uint32_t nanoseconds)
765 {
766 if ((seconds >> 34) == 0) {
767 /* seconds is unsigned and fits in 34 bits */
768 uint64_t data64 = ((uint64_t)nanoseconds << 34) | (uint64_t)seconds;
769 if ((data64 & 0xffffffff00000000L) == 0) {
770 /* no nanoseconds and seconds is 32bits or smaller. timestamp32. */
771 unsigned char buf[4];
772 uint32_t data32 = (uint32_t)data64;
773 msgpack_pack_ext(x, -1, 4);
774 _msgpack_store32(buf, data32);
775 msgpack_pack_raw_body(x, buf, 4);
776 } else {
777 /* timestamp64 */
778 unsigned char buf[8];
779 msgpack_pack_ext(x, -1, 8);
780 _msgpack_store64(buf, data64);
781 msgpack_pack_raw_body(x, buf, 8);
782
783 }
784 } else {
785 /* seconds is signed or >34bits */
786 unsigned char buf[12];
787 _msgpack_store32(&buf[0], nanoseconds);
788 _msgpack_store64(&buf[4], seconds);
789 msgpack_pack_ext(x, -1, 12);
790 msgpack_pack_raw_body(x, buf, 12);
791 }
792 return 0;
793 }
761794
762795
763796 #undef msgpack_pack_append_buffer
2323 bool raw;
2424 bool has_pairs_hook;
2525 bool strict_map_key;
26 int timestamp;
2627 PyObject *object_hook;
2728 PyObject *list_hook;
2829 PyObject *ext_hook;
29 const char *encoding;
30 PyObject *timestamp_t;
31 PyObject *giga;
32 PyObject *utc;
3033 const char *unicode_errors;
3134 Py_ssize_t max_str_len, max_bin_len, max_array_len, max_map_len, max_ext_len;
3235 } unpack_user;
191194 if (u->strict_map_key && !PyUnicode_CheckExact(k) && !PyBytes_CheckExact(k)) {
192195 PyErr_Format(PyExc_ValueError, "%.100s is not allowed for map key", Py_TYPE(k)->tp_name);
193196 return -1;
197 }
198 if (PyUnicode_CheckExact(k)) {
199 PyUnicode_InternInPlace(&k);
194200 }
195201 if (u->has_pairs_hook) {
196202 msgpack_unpack_object item = PyTuple_Pack(2, k, v);
231237
232238 PyObject *py;
233239
234 if (u->encoding) {
235 py = PyUnicode_Decode(p, l, u->encoding, u->unicode_errors);
236 } else if (u->raw) {
240 if (u->raw) {
237241 py = PyBytes_FromStringAndSize(p, l);
238242 } else {
239243 py = PyUnicode_DecodeUTF8(p, l, u->unicode_errors);
258262 return 0;
259263 }
260264
261 static inline int unpack_callback_ext(unpack_user* u, const char* base, const char* pos,
262 unsigned int length, msgpack_unpack_object* o)
263 {
264 PyObject *py;
265 typedef struct msgpack_timestamp {
266 int64_t tv_sec;
267 uint32_t tv_nsec;
268 } msgpack_timestamp;
269
270 /*
271 * Unpack ext buffer to a timestamp. Pulled from msgpack-c timestamp.h.
272 */
273 static int unpack_timestamp(const char* buf, unsigned int buflen, msgpack_timestamp* ts) {
274 switch (buflen) {
275 case 4:
276 ts->tv_nsec = 0;
277 {
278 uint32_t v = _msgpack_load32(uint32_t, buf);
279 ts->tv_sec = (int64_t)v;
280 }
281 return 0;
282 case 8: {
283 uint64_t value =_msgpack_load64(uint64_t, buf);
284 ts->tv_nsec = (uint32_t)(value >> 34);
285 ts->tv_sec = value & 0x00000003ffffffffLL;
286 return 0;
287 }
288 case 12:
289 ts->tv_nsec = _msgpack_load32(uint32_t, buf);
290 ts->tv_sec = _msgpack_load64(int64_t, buf + 4);
291 return 0;
292 default:
293 return -1;
294 }
295 }
296
297 #include "datetime.h"
298
299 static int unpack_callback_ext(unpack_user* u, const char* base, const char* pos,
300 unsigned int length, msgpack_unpack_object* o)
301 {
265302 int8_t typecode = (int8_t)*pos++;
266303 if (!u->ext_hook) {
267304 PyErr_SetString(PyExc_AssertionError, "u->ext_hook cannot be NULL");
271308 PyErr_Format(PyExc_ValueError, "%u exceeds max_ext_len(%zd)", length, u->max_ext_len);
272309 return -1;
273310 }
311
312 PyObject *py = NULL;
274313 // length also includes the typecode, so the actual data is length-1
275 #if PY_MAJOR_VERSION == 2
276 py = PyObject_CallFunction(u->ext_hook, "(is#)", (int)typecode, pos, (Py_ssize_t)length-1);
277 #else
278 py = PyObject_CallFunction(u->ext_hook, "(iy#)", (int)typecode, pos, (Py_ssize_t)length-1);
279 #endif
314 if (typecode == -1) {
315 msgpack_timestamp ts;
316 if (unpack_timestamp(pos, length-1, &ts) < 0) {
317 return -1;
318 }
319
320 if (u->timestamp == 2) { // int
321 PyObject *a = PyLong_FromLongLong(ts.tv_sec);
322 if (a == NULL) return -1;
323
324 PyObject *c = PyNumber_Multiply(a, u->giga);
325 Py_DECREF(a);
326 if (c == NULL) {
327 return -1;
328 }
329
330 PyObject *b = PyLong_FromUnsignedLong(ts.tv_nsec);
331 if (b == NULL) {
332 Py_DECREF(c);
333 return -1;
334 }
335
336 py = PyNumber_Add(c, b);
337 Py_DECREF(c);
338 Py_DECREF(b);
339 }
340 else if (u->timestamp == 0) { // Timestamp
341 py = PyObject_CallFunction(u->timestamp_t, "(Lk)", ts.tv_sec, ts.tv_nsec);
342 }
343 else { // float or datetime
344 PyObject *a = PyFloat_FromDouble((double)ts.tv_nsec);
345 if (a == NULL) return -1;
346
347 PyObject *b = PyNumber_TrueDivide(a, u->giga);
348 Py_DECREF(a);
349 if (b == NULL) return -1;
350
351 PyObject *c = PyLong_FromLongLong(ts.tv_sec);
352 if (c == NULL) {
353 Py_DECREF(b);
354 return -1;
355 }
356
357 a = PyNumber_Add(b, c);
358 Py_DECREF(b);
359 Py_DECREF(c);
360
361 if (u->timestamp == 3) { // datetime
362 PyObject *t = PyTuple_Pack(2, a, u->utc);
363 Py_DECREF(a);
364 if (t == NULL) {
365 return -1;
366 }
367 py = PyDateTime_FromTimestamp(t);
368 Py_DECREF(t);
369 } else { // float
370 py = a;
371 }
372 }
373 } else {
374 py = PyObject_CallFunction(u->ext_hook, "(iy#)", (int)typecode, pos, (Py_ssize_t)length-1);
375 }
280376 if (!py)
281377 return -1;
282378 *o = py;
88
99 from distutils.command.build_ext import build_ext
1010
11 # for building transitional package.
12 TRANSITIONAL = False
11
12 PYPY = hasattr(sys, "pypy_version_info")
13 PY2 = sys.version_info[0] == 2
14
1315
1416 class NoCython(Exception):
1517 pass
1618
19
1720 try:
1821 import Cython.Compiler.Main as cython_compiler
22
1923 have_cython = True
2024 except ImportError:
2125 have_cython = False
2529 sys.stderr.write("cythonize: %r\n" % (src,))
2630 cython_compiler.compile([src], cplus=True)
2731
32
2833 def ensure_source(src):
29 pyx = os.path.splitext(src)[0] + '.pyx'
34 pyx = os.path.splitext(src)[0] + ".pyx"
3035
3136 if not os.path.exists(src):
3237 if not have_cython:
3338 raise NoCython
3439 cythonize(pyx)
35 elif (os.path.exists(pyx) and
36 os.stat(src).st_mtime < os.stat(pyx).st_mtime and
37 have_cython):
40 elif (
41 os.path.exists(pyx)
42 and os.stat(src).st_mtime < os.stat(pyx).st_mtime
43 and have_cython
44 ):
3845 cythonize(pyx)
3946 return src
4047
5764 print(e)
5865
5966
60 exec(open('msgpack/_version.py').read())
67 exec(open("msgpack/_version.py").read())
6168
62 version_str = '.'.join(str(x) for x in version[:3])
63 if len(version) > 3 and version[3] != 'final':
69 version_str = ".".join(str(x) for x in version[:3])
70 if len(version) > 3 and version[3] != "final":
6471 version_str += version[3]
6572
66 # take care of extension modules.
67 if have_cython:
68 class Sdist(sdist):
69 def __init__(self, *args, **kwargs):
70 cythonize('msgpack/_cmsgpack.pyx')
71 sdist.__init__(self, *args, **kwargs)
72 else:
73 Sdist = sdist
73 # Cython is required for sdist
74 class Sdist(sdist):
75 def __init__(self, *args, **kwargs):
76 cythonize("msgpack/_cmsgpack.pyx")
77 sdist.__init__(self, *args, **kwargs)
78
7479
7580 libraries = []
76 if sys.platform == 'win32':
77 libraries.append('ws2_32')
81 if sys.platform == "win32":
82 libraries.append("ws2_32")
7883
79 if sys.byteorder == 'big':
80 macros = [('__BIG_ENDIAN__', '1')]
84 if sys.byteorder == "big":
85 macros = [("__BIG_ENDIAN__", "1")]
8186 else:
82 macros = [('__LITTLE_ENDIAN__', '1')]
87 macros = [("__LITTLE_ENDIAN__", "1")]
8388
8489 ext_modules = []
85 if not hasattr(sys, 'pypy_version_info'):
86 ext_modules.append(Extension('msgpack._cmsgpack',
87 sources=['msgpack/_cmsgpack.cpp'],
88 libraries=libraries,
89 include_dirs=['.'],
90 define_macros=macros,
91 ))
90 if not PYPY and not PY2:
91 ext_modules.append(
92 Extension(
93 "msgpack._cmsgpack",
94 sources=["msgpack/_cmsgpack.cpp"],
95 libraries=libraries,
96 include_dirs=["."],
97 define_macros=macros,
98 )
99 )
92100 del libraries, macros
93101
94102
95 desc = 'MessagePack (de)serializer.'
96 with io.open('README.rst', encoding='utf-8') as f:
103 desc = "MessagePack (de)serializer."
104 with io.open("README.md", encoding="utf-8") as f:
97105 long_desc = f.read()
98106 del f
99107
100 name = 'msgpack'
101
102 if TRANSITIONAL:
103 name = 'msgpack-python'
104 long_desc = "This package is deprecated. Install msgpack instead."
105
106 setup(name=name,
107 author='INADA Naoki',
108 author_email='songofacandy@gmail.com',
109 version=version_str,
110 cmdclass={'build_ext': BuildExt, 'sdist': Sdist},
111 ext_modules=ext_modules,
112 packages=['msgpack'],
113 description=desc,
114 long_description=long_desc,
115 long_description_content_type="text/x-rst",
116 url='https://msgpack.org/',
117 project_urls = {
118 'Documentation': 'https://msgpack-python.readthedocs.io/',
119 'Source': 'https://github.com/msgpack/msgpack-python',
120 'Tracker': 'https://github.com/msgpack/msgpack-python/issues',
121 },
122 license='Apache 2.0',
123 classifiers=[
124 'Programming Language :: Python :: 2',
125 'Programming Language :: Python :: 2.7',
126 'Programming Language :: Python :: 3',
127 'Programming Language :: Python :: 3.5',
128 'Programming Language :: Python :: 3.6',
129 'Programming Language :: Python :: 3.7',
130 'Programming Language :: Python :: Implementation :: CPython',
131 'Programming Language :: Python :: Implementation :: PyPy',
132 'Intended Audience :: Developers',
133 'License :: OSI Approved :: Apache Software License',
134 ],
108 setup(
109 name="msgpack",
110 author="Inada Naoki",
111 author_email="songofacandy@gmail.com",
112 version=version_str,
113 cmdclass={"build_ext": BuildExt, "sdist": Sdist},
114 ext_modules=ext_modules,
115 packages=["msgpack"],
116 description=desc,
117 long_description=long_desc,
118 long_description_content_type="text/markdown",
119 url="https://msgpack.org/",
120 project_urls={
121 "Documentation": "https://msgpack-python.readthedocs.io/",
122 "Source": "https://github.com/msgpack/msgpack-python",
123 "Tracker": "https://github.com/msgpack/msgpack-python/issues",
124 },
125 license="Apache 2.0",
126 classifiers=[
127 "Programming Language :: Python :: 2",
128 "Programming Language :: Python :: 2.7",
129 "Programming Language :: Python :: 3",
130 "Programming Language :: Python :: 3.5",
131 "Programming Language :: Python :: 3.6",
132 "Programming Language :: Python :: 3.7",
133 "Programming Language :: Python :: 3.8",
134 "Programming Language :: Python :: Implementation :: CPython",
135 "Programming Language :: Python :: Implementation :: PyPy",
136 "Intended Audience :: Developers",
137 "License :: OSI Approved :: Apache Software License",
138 ],
135139 )
00 #!/usr/bin/env python
11 # coding: utf-8
22
3 import sys
4 import pytest
35 from msgpack import packb, unpackb
46
57
8 @pytest.mark.skipif(sys.version_info[0] == 2, reason="Python 2 is not supported")
69 def test_unpack_buffer():
710 from array import array
8 buf = array('b')
9 try:
10 buf.frombytes(packb((b'foo', b'bar')))
11 except AttributeError: # PY2
12 buf.fromstring(packb((b'foo', b'bar')))
11
12 buf = array("b")
13 buf.frombytes(packb((b"foo", b"bar")))
1314 obj = unpackb(buf, use_list=1)
14 assert [b'foo', b'bar'] == obj
15 assert [b"foo", b"bar"] == obj
1516
1617
1718 def test_unpack_bytearray():
18 buf = bytearray(packb(('foo', 'bar')))
19 buf = bytearray(packb((b"foo", b"bar")))
1920 obj = unpackb(buf, use_list=1)
20 assert [b'foo', b'bar'] == obj
21 assert [b"foo", b"bar"] == obj
2122 expected_type = bytes
2223 assert all(type(s) == expected_type for s in obj)
2324
2425
2526 def test_unpack_memoryview():
26 buf = bytearray(packb(('foo', 'bar')))
27 buf = bytearray(packb((b"foo", b"bar")))
2728 view = memoryview(buf)
2829 obj = unpackb(view, use_list=1)
29 assert [b'foo', b'bar'] == obj
30 assert [b"foo", b"bar"] == obj
3031 expected_type = bytes
3132 assert all(type(s) == expected_type for s in obj)
00 #!/usr/bin/env python
11 # coding: utf-8
2
32 from msgpack import packb, unpackb
43
54
6 def check(length, obj):
7 v = packb(obj)
8 assert len(v) == length, \
9 "%r length should be %r but get %r" % (obj, length, len(v))
10 assert unpackb(v, use_list=0) == obj
5 def check(length, obj, use_bin_type=True):
6 v = packb(obj, use_bin_type=use_bin_type)
7 assert len(v) == length, "%r length should be %r but get %r" % (obj, length, len(v))
8 assert unpackb(v, use_list=0, raw=not use_bin_type) == obj
9
1110
1211 def test_1():
13 for o in [None, True, False, 0, 1, (1 << 6), (1 << 7) - 1, -1,
14 -((1<<5)-1), -(1<<5)]:
12 for o in [
13 None,
14 True,
15 False,
16 0,
17 1,
18 (1 << 6),
19 (1 << 7) - 1,
20 -1,
21 -((1 << 5) - 1),
22 -(1 << 5),
23 ]:
1524 check(1, o)
1625
26
1727 def test_2():
18 for o in [1 << 7, (1 << 8) - 1,
19 -((1<<5)+1), -(1<<7)
20 ]:
28 for o in [1 << 7, (1 << 8) - 1, -((1 << 5) + 1), -(1 << 7)]:
2129 check(2, o)
2230
31
2332 def test_3():
24 for o in [1 << 8, (1 << 16) - 1,
25 -((1<<7)+1), -(1<<15)]:
33 for o in [1 << 8, (1 << 16) - 1, -((1 << 7) + 1), -(1 << 15)]:
2634 check(3, o)
2735
36
2837 def test_5():
29 for o in [1 << 16, (1 << 32) - 1,
30 -((1<<15)+1), -(1<<31)]:
38 for o in [1 << 16, (1 << 32) - 1, -((1 << 15) + 1), -(1 << 31)]:
3139 check(5, o)
3240
41
3342 def test_9():
34 for o in [1 << 32, (1 << 64) - 1,
35 -((1<<31)+1), -(1<<63),
36 1.0, 0.1, -0.1, -1.0]:
43 for o in [
44 1 << 32,
45 (1 << 64) - 1,
46 -((1 << 31) + 1),
47 -(1 << 63),
48 1.0,
49 0.1,
50 -0.1,
51 -1.0,
52 ]:
3753 check(9, o)
3854
3955
4056 def check_raw(overhead, num):
41 check(num + overhead, b" " * num)
57 check(num + overhead, b" " * num, use_bin_type=False)
58
4259
4360 def test_fixraw():
4461 check_raw(1, 0)
45 check_raw(1, (1<<5) - 1)
62 check_raw(1, (1 << 5) - 1)
63
4664
4765 def test_raw16():
48 check_raw(3, 1<<5)
49 check_raw(3, (1<<16) - 1)
66 check_raw(3, 1 << 5)
67 check_raw(3, (1 << 16) - 1)
68
5069
5170 def test_raw32():
52 check_raw(5, 1<<16)
71 check_raw(5, 1 << 16)
5372
5473
5574 def check_array(overhead, num):
5675 check(num + overhead, (None,) * num)
5776
77
5878 def test_fixarray():
5979 check_array(1, 0)
6080 check_array(1, (1 << 4) - 1)
6181
82
6283 def test_array16():
6384 check_array(3, 1 << 4)
64 check_array(3, (1<<16)-1)
85 check_array(3, (1 << 16) - 1)
86
6587
6688 def test_array32():
67 check_array(5, (1<<16))
89 check_array(5, (1 << 16))
6890
6991
7092 def match(obj, buf):
7193 assert packb(obj) == buf
72 assert unpackb(buf, use_list=0) == obj
94 assert unpackb(buf, use_list=0, strict_map_key=False) == obj
95
7396
7497 def test_match():
7598 cases = [
76 (None, b'\xc0'),
77 (False, b'\xc2'),
78 (True, b'\xc3'),
79 (0, b'\x00'),
80 (127, b'\x7f'),
81 (128, b'\xcc\x80'),
82 (256, b'\xcd\x01\x00'),
83 (-1, b'\xff'),
84 (-33, b'\xd0\xdf'),
85 (-129, b'\xd1\xff\x7f'),
86 ({1:1}, b'\x81\x01\x01'),
99 (None, b"\xc0"),
100 (False, b"\xc2"),
101 (True, b"\xc3"),
102 (0, b"\x00"),
103 (127, b"\x7f"),
104 (128, b"\xcc\x80"),
105 (256, b"\xcd\x01\x00"),
106 (-1, b"\xff"),
107 (-33, b"\xd0\xdf"),
108 (-129, b"\xd1\xff\x7f"),
109 ({1: 1}, b"\x81\x01\x01"),
87110 (1.0, b"\xcb\x3f\xf0\x00\x00\x00\x00\x00\x00"),
88 ((), b'\x90'),
89 (tuple(range(15)),b"\x9f\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"),
90 (tuple(range(16)),b"\xdc\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"),
91 ({}, b'\x80'),
92 (dict([(x,x) for x in range(15)]), b'\x8f\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t\n\n\x0b\x0b\x0c\x0c\r\r\x0e\x0e'),
93 (dict([(x,x) for x in range(16)]), b'\xde\x00\x10\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t\n\n\x0b\x0b\x0c\x0c\r\r\x0e\x0e\x0f\x0f'),
94 ]
111 ((), b"\x90"),
112 (
113 tuple(range(15)),
114 b"\x9f\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e",
115 ),
116 (
117 tuple(range(16)),
118 b"\xdc\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
119 ),
120 ({}, b"\x80"),
121 (
122 dict([(x, x) for x in range(15)]),
123 b"\x8f\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t\n\n\x0b\x0b\x0c\x0c\r\r\x0e\x0e",
124 ),
125 (
126 dict([(x, x) for x in range(16)]),
127 b"\xde\x00\x10\x00\x00\x01\x01\x02\x02\x03\x03\x04\x04\x05\x05\x06\x06\x07\x07\x08\x08\t\t\n\n\x0b\x0b\x0c\x0c\r\r\x0e\x0e\x0f\x0f",
128 ),
129 ]
95130
96131 for v, p in cases:
97132 match(v, p)
98133
134
99135 def test_unicode():
100 assert unpackb(packb('foobar'), use_list=1) == b'foobar'
101
136 assert unpackb(packb(u"foobar"), use_list=1) == u"foobar"
88 packer = msgpack.Packer()
99 packer.pack_ext_type(0x42, s)
1010 return packer.bytes()
11 assert p(b'A') == b'\xd4\x42A' # fixext 1
12 assert p(b'AB') == b'\xd5\x42AB' # fixext 2
13 assert p(b'ABCD') == b'\xd6\x42ABCD' # fixext 4
14 assert p(b'ABCDEFGH') == b'\xd7\x42ABCDEFGH' # fixext 8
15 assert p(b'A'*16) == b'\xd8\x42' + b'A'*16 # fixext 16
16 assert p(b'ABC') == b'\xc7\x03\x42ABC' # ext 8
17 assert p(b'A'*0x0123) == b'\xc8\x01\x23\x42' + b'A'*0x0123 # ext 16
18 assert p(b'A'*0x00012345) == b'\xc9\x00\x01\x23\x45\x42' + b'A'*0x00012345 # ext 32
11
12 assert p(b"A") == b"\xd4\x42A" # fixext 1
13 assert p(b"AB") == b"\xd5\x42AB" # fixext 2
14 assert p(b"ABCD") == b"\xd6\x42ABCD" # fixext 4
15 assert p(b"ABCDEFGH") == b"\xd7\x42ABCDEFGH" # fixext 8
16 assert p(b"A" * 16) == b"\xd8\x42" + b"A" * 16 # fixext 16
17 assert p(b"ABC") == b"\xc7\x03\x42ABC" # ext 8
18 assert p(b"A" * 0x0123) == b"\xc8\x01\x23\x42" + b"A" * 0x0123 # ext 16
19 assert (
20 p(b"A" * 0x00012345) == b"\xc9\x00\x01\x23\x45\x42" + b"A" * 0x00012345
21 ) # ext 32
1922
2023
2124 def test_unpack_ext_type():
2225 def check(b, expected):
2326 assert msgpack.unpackb(b) == expected
2427
25 check(b'\xd4\x42A', ExtType(0x42, b'A')) # fixext 1
26 check(b'\xd5\x42AB', ExtType(0x42, b'AB')) # fixext 2
27 check(b'\xd6\x42ABCD', ExtType(0x42, b'ABCD')) # fixext 4
28 check(b'\xd7\x42ABCDEFGH', ExtType(0x42, b'ABCDEFGH')) # fixext 8
29 check(b'\xd8\x42' + b'A'*16, ExtType(0x42, b'A'*16)) # fixext 16
30 check(b'\xc7\x03\x42ABC', ExtType(0x42, b'ABC')) # ext 8
31 check(b'\xc8\x01\x23\x42' + b'A'*0x0123,
32 ExtType(0x42, b'A'*0x0123)) # ext 16
33 check(b'\xc9\x00\x01\x23\x45\x42' + b'A'*0x00012345,
34 ExtType(0x42, b'A'*0x00012345)) # ext 32
28 check(b"\xd4\x42A", ExtType(0x42, b"A")) # fixext 1
29 check(b"\xd5\x42AB", ExtType(0x42, b"AB")) # fixext 2
30 check(b"\xd6\x42ABCD", ExtType(0x42, b"ABCD")) # fixext 4
31 check(b"\xd7\x42ABCDEFGH", ExtType(0x42, b"ABCDEFGH")) # fixext 8
32 check(b"\xd8\x42" + b"A" * 16, ExtType(0x42, b"A" * 16)) # fixext 16
33 check(b"\xc7\x03\x42ABC", ExtType(0x42, b"ABC")) # ext 8
34 check(b"\xc8\x01\x23\x42" + b"A" * 0x0123, ExtType(0x42, b"A" * 0x0123)) # ext 16
35 check(
36 b"\xc9\x00\x01\x23\x45\x42" + b"A" * 0x00012345,
37 ExtType(0x42, b"A" * 0x00012345),
38 ) # ext 32
3539
3640
3741 def test_extension_type():
3842 def default(obj):
39 print('default called', obj)
43 print("default called", obj)
4044 if isinstance(obj, array.array):
41 typecode = 123 # application specific typecode
45 typecode = 123 # application specific typecode
4246 try:
4347 data = obj.tobytes()
4448 except AttributeError:
4751 raise TypeError("Unknown type object %r" % (obj,))
4852
4953 def ext_hook(code, data):
50 print('ext_hook called', code, data)
54 print("ext_hook called", code, data)
5155 assert code == 123
52 obj = array.array('d')
56 obj = array.array("d")
5357 try:
5458 obj.frombytes(data)
5559 except AttributeError: # PY2
5660 obj.fromstring(data)
5761 return obj
5862
59 obj = [42, b'hello', array.array('d', [1.1, 2.2, 3.3])]
63 obj = [42, b"hello", array.array("d", [1.1, 2.2, 3.3])]
6064 s = msgpack.packb(obj, default=default)
6165 obj2 = msgpack.unpackb(s, ext_hook=ext_hook)
6266 assert obj == obj2
6367
68
6469 import sys
65 if sys.version > '3':
70
71 if sys.version > "3":
6672 long = int
73
6774
6875 def test_overriding_hooks():
6976 def default(obj):
22
33 from msgpack import unpackb
44
5 def check(src, should, use_list=0):
6 assert unpackb(src, use_list=use_list) == should
5
6 def check(src, should, use_list=0, raw=True):
7 assert unpackb(src, use_list=use_list, raw=raw, strict_map_key=False) == should
8
79
810 def testSimpleValue():
9 check(b"\x93\xc0\xc2\xc3",
10 (None, False, True,))
11 check(b"\x93\xc0\xc2\xc3", (None, False, True))
12
1113
1214 def testFixnum():
13 check(b"\x92\x93\x00\x40\x7f\x93\xe0\xf0\xff",
14 ((0,64,127,), (-32,-16,-1,),)
15 )
15 check(b"\x92\x93\x00\x40\x7f\x93\xe0\xf0\xff", ((0, 64, 127), (-32, -16, -1)))
16
1617
1718 def testFixArray():
18 check(b"\x92\x90\x91\x91\xc0",
19 ((),((None,),),),
20 )
19 check(b"\x92\x90\x91\x91\xc0", ((), ((None,),)))
20
2121
2222 def testFixRaw():
23 check(b"\x94\xa0\xa1a\xa2bc\xa3def",
24 (b"", b"a", b"bc", b"def",),
25 )
23 check(b"\x94\xa0\xa1a\xa2bc\xa3def", (b"", b"a", b"bc", b"def"))
24
2625
2726 def testFixMap():
2827 check(
29 b"\x82\xc2\x81\xc0\xc0\xc3\x81\xc0\x80",
30 {False: {None: None}, True:{None:{}}},
31 )
28 b"\x82\xc2\x81\xc0\xc0\xc3\x81\xc0\x80", {False: {None: None}, True: {None: {}}}
29 )
30
3231
3332 def testUnsignedInt():
3433 check(
35 b"\x99\xcc\x00\xcc\x80\xcc\xff\xcd\x00\x00\xcd\x80\x00"
36 b"\xcd\xff\xff\xce\x00\x00\x00\x00\xce\x80\x00\x00\x00"
37 b"\xce\xff\xff\xff\xff",
38 (0, 128, 255, 0, 32768, 65535, 0, 2147483648, 4294967295,),
39 )
34 b"\x99\xcc\x00\xcc\x80\xcc\xff\xcd\x00\x00\xcd\x80\x00"
35 b"\xcd\xff\xff\xce\x00\x00\x00\x00\xce\x80\x00\x00\x00"
36 b"\xce\xff\xff\xff\xff",
37 (0, 128, 255, 0, 32768, 65535, 0, 2147483648, 4294967295),
38 )
39
4040
4141 def testSignedInt():
42 check(b"\x99\xd0\x00\xd0\x80\xd0\xff\xd1\x00\x00\xd1\x80\x00"
43 b"\xd1\xff\xff\xd2\x00\x00\x00\x00\xd2\x80\x00\x00\x00"
44 b"\xd2\xff\xff\xff\xff",
45 (0, -128, -1, 0, -32768, -1, 0, -2147483648, -1,))
42 check(
43 b"\x99\xd0\x00\xd0\x80\xd0\xff\xd1\x00\x00\xd1\x80\x00"
44 b"\xd1\xff\xff\xd2\x00\x00\x00\x00\xd2\x80\x00\x00\x00"
45 b"\xd2\xff\xff\xff\xff",
46 (0, -128, -1, 0, -32768, -1, 0, -2147483648, -1),
47 )
48
4649
4750 def testRaw():
48 check(b"\x96\xda\x00\x00\xda\x00\x01a\xda\x00\x02ab\xdb\x00\x00"
51 check(
52 b"\x96\xda\x00\x00\xda\x00\x01a\xda\x00\x02ab\xdb\x00\x00"
4953 b"\x00\x00\xdb\x00\x00\x00\x01a\xdb\x00\x00\x00\x02ab",
50 (b"", b"a", b"ab", b"", b"a", b"ab"))
54 (b"", b"a", b"ab", b"", b"a", b"ab"),
55 )
56 check(
57 b"\x96\xda\x00\x00\xda\x00\x01a\xda\x00\x02ab\xdb\x00\x00"
58 b"\x00\x00\xdb\x00\x00\x00\x01a\xdb\x00\x00\x00\x02ab",
59 ("", "a", "ab", "", "a", "ab"),
60 raw=False,
61 )
62
5163
5264 def testArray():
53 check(b"\x96\xdc\x00\x00\xdc\x00\x01\xc0\xdc\x00\x02\xc2\xc3\xdd\x00"
65 check(
66 b"\x96\xdc\x00\x00\xdc\x00\x01\xc0\xdc\x00\x02\xc2\xc3\xdd\x00"
5467 b"\x00\x00\x00\xdd\x00\x00\x00\x01\xc0\xdd\x00\x00\x00\x02"
5568 b"\xc2\xc3",
56 ((), (None,), (False,True), (), (None,), (False,True))
57 )
69 ((), (None,), (False, True), (), (None,), (False, True)),
70 )
71
5872
5973 def testMap():
6074 check(
6175 b"\x96"
62 b"\xde\x00\x00"
63 b"\xde\x00\x01\xc0\xc2"
64 b"\xde\x00\x02\xc0\xc2\xc3\xc2"
65 b"\xdf\x00\x00\x00\x00"
66 b"\xdf\x00\x00\x00\x01\xc0\xc2"
67 b"\xdf\x00\x00\x00\x02\xc0\xc2\xc3\xc2",
68 ({}, {None: False}, {True: False, None: False}, {},
69 {None: False}, {True: False, None: False}))
76 b"\xde\x00\x00"
77 b"\xde\x00\x01\xc0\xc2"
78 b"\xde\x00\x02\xc0\xc2\xc3\xc2"
79 b"\xdf\x00\x00\x00\x00"
80 b"\xdf\x00\x00\x00\x01\xc0\xc2"
81 b"\xdf\x00\x00\x00\x02\xc0\xc2\xc3\xc2",
82 (
83 {},
84 {None: False},
85 {True: False, None: False},
86 {},
87 {None: False},
88 {True: False, None: False},
89 ),
90 )
33 import pytest
44
55 from msgpack import (
6 packb, unpackb, Packer, Unpacker, ExtType,
7 PackOverflowError, PackValueError, UnpackValueError,
6 packb,
7 unpackb,
8 Packer,
9 Unpacker,
10 ExtType,
11 PackOverflowError,
12 PackValueError,
13 UnpackValueError,
814 )
915
1016
1218 x = -(2 ** 63)
1319 assert unpackb(packb(x)) == x
1420 with pytest.raises(PackOverflowError):
15 packb(x-1)
21 packb(x - 1)
1622
1723 x = 2 ** 64 - 1
1824 assert unpackb(packb(x)) == x
1925 with pytest.raises(PackOverflowError):
20 packb(x+1)
26 packb(x + 1)
2127
2228
2329 def test_array_header():
2430 packer = Packer()
25 packer.pack_array_header(2**32-1)
31 packer.pack_array_header(2 ** 32 - 1)
2632 with pytest.raises(PackValueError):
27 packer.pack_array_header(2**32)
33 packer.pack_array_header(2 ** 32)
2834
2935
3036 def test_map_header():
3137 packer = Packer()
32 packer.pack_map_header(2**32-1)
38 packer.pack_map_header(2 ** 32 - 1)
3339 with pytest.raises(PackValueError):
34 packer.pack_array_header(2**32)
40 packer.pack_array_header(2 ** 32)
3541
3642
3743 def test_max_str_len():
38 d = 'x' * 3
44 d = "x" * 3
3945 packed = packb(d)
4046
4147 unpacker = Unpacker(max_str_len=3, raw=False)
4955
5056
5157 def test_max_bin_len():
52 d = b'x' * 3
58 d = b"x" * 3
5359 packed = packb(d, use_bin_type=True)
5460
5561 unpacker = Unpacker(max_bin_len=3)
6369
6470
6571 def test_max_array_len():
66 d = [1,2,3]
72 d = [1, 2, 3]
6773 packed = packb(d)
6874
6975 unpacker = Unpacker(max_array_len=3)
8086 d = {1: 2, 3: 4, 5: 6}
8187 packed = packb(d)
8288
83 unpacker = Unpacker(max_map_len=3)
89 unpacker = Unpacker(max_map_len=3, strict_map_key=False)
8490 unpacker.feed(packed)
8591 assert unpacker.unpack() == d
8692
87 unpacker = Unpacker(max_map_len=2)
93 unpacker = Unpacker(max_map_len=2, strict_map_key=False)
8894 with pytest.raises(UnpackValueError):
8995 unpacker.feed(packed)
9096 unpacker.unpack()
106112
107113 # PyPy fails following tests because of constant folding?
108114 # https://bugs.pypy.org/issue1721
109 #@pytest.mark.skipif(True, reason="Requires very large memory.")
110 #def test_binary():
115 # @pytest.mark.skipif(True, reason="Requires very large memory.")
116 # def test_binary():
111117 # x = b'x' * (2**32 - 1)
112118 # assert unpackb(packb(x)) == x
113119 # del x
116122 # packb(x)
117123 #
118124 #
119 #@pytest.mark.skipif(True, reason="Requires very large memory.")
120 #def test_string():
125 # @pytest.mark.skipif(True, reason="Requires very large memory.")
126 # def test_string():
121127 # x = 'x' * (2**32 - 1)
122128 # assert unpackb(packb(x)) == x
123129 # x += 'y'
125131 # packb(x)
126132 #
127133 #
128 #@pytest.mark.skipif(True, reason="Requires very large memory.")
129 #def test_array():
134 # @pytest.mark.skipif(True, reason="Requires very large memory.")
135 # def test_array():
130136 # x = [0] * (2**32 - 1)
131137 # assert unpackb(packb(x)) == x
132138 # x.append(0)
136142
137143 # auto max len
138144
145
139146 def test_auto_max_array_len():
140 packed = b'\xde\x00\x06zz'
147 packed = b"\xde\x00\x06zz"
141148 with pytest.raises(UnpackValueError):
142149 unpackb(packed, raw=False)
143150
146153 with pytest.raises(UnpackValueError):
147154 unpacker.unpack()
148155
156
149157 def test_auto_max_map_len():
150158 # len(packed) == 6 -> max_map_len == 3
151 packed = b'\xde\x00\x04zzz'
159 packed = b"\xde\x00\x04zzz"
152160 with pytest.raises(UnpackValueError):
153161 unpackb(packed, raw=False)
154162
00 #!/usr/bin/env python
11 # coding: utf-8
22
3 import pytest
34 from array import array
45 from msgpack import packb, unpackb
56 import sys
67
78
8 # For Python < 3:
9 # - array type only supports old buffer interface
10 # - array.frombytes is not available, must use deprecated array.fromstring
11 if sys.version_info[0] < 3:
12 def make_memoryview(obj):
13 return memoryview(buffer(obj))
9 pytestmark = pytest.mark.skipif(
10 sys.version_info[0] < 3, reason="Only Python 3 supports buffer protocol"
11 )
1412
15 def make_array(f, data):
16 a = array(f)
17 a.fromstring(data)
18 return a
1913
20 def get_data(a):
21 return a.tostring()
22 else:
23 make_memoryview = memoryview
24
25 def make_array(f, data):
26 a = array(f)
27 a.frombytes(data)
28 return a
29
30 def get_data(a):
31 return a.tobytes()
14 def make_array(f, data):
15 a = array(f)
16 a.frombytes(data)
17 return a
3218
3319
3420 def _runtest(format, nbytes, expected_header, expected_prefix, use_bin_type):
3521 # create a new array
3622 original_array = array(format)
3723 original_array.fromlist([255] * (nbytes // original_array.itemsize))
38 original_data = get_data(original_array)
39 view = make_memoryview(original_array)
24 original_data = original_array.tobytes()
25 view = memoryview(original_array)
4026
4127 # pack, unpack, and reconstruct array
4228 packed = packb(view, use_bin_type=use_bin_type)
43 unpacked = unpackb(packed)
29 unpacked = unpackb(packed, raw=(not use_bin_type))
4430 reconstructed_array = make_array(format, unpacked)
4531
4632 # check that we got the right amount of data
4834 # check packed header
4935 assert packed[:1] == expected_header
5036 # check packed length prefix, if any
51 assert packed[1:1+len(expected_prefix)] == expected_prefix
37 assert packed[1 : 1 + len(expected_prefix)] == expected_prefix
5238 # check packed data
53 assert packed[1+len(expected_prefix):] == original_data
39 assert packed[1 + len(expected_prefix) :] == original_data
5440 # check array unpacked correctly
5541 assert original_array == reconstructed_array
5642
5743
5844 def test_fixstr_from_byte():
59 _runtest('B', 1, b'\xa1', b'', False)
60 _runtest('B', 31, b'\xbf', b'', False)
45 _runtest("B", 1, b"\xa1", b"", False)
46 _runtest("B", 31, b"\xbf", b"", False)
6147
6248
6349 def test_fixstr_from_float():
64 _runtest('f', 4, b'\xa4', b'', False)
65 _runtest('f', 28, b'\xbc', b'', False)
50 _runtest("f", 4, b"\xa4", b"", False)
51 _runtest("f", 28, b"\xbc", b"", False)
6652
6753
6854 def test_str16_from_byte():
69 _runtest('B', 2**8, b'\xda', b'\x01\x00', False)
70 _runtest('B', 2**16-1, b'\xda', b'\xff\xff', False)
55 _runtest("B", 2 ** 8, b"\xda", b"\x01\x00", False)
56 _runtest("B", 2 ** 16 - 1, b"\xda", b"\xff\xff", False)
7157
7258
7359 def test_str16_from_float():
74 _runtest('f', 2**8, b'\xda', b'\x01\x00', False)
75 _runtest('f', 2**16-4, b'\xda', b'\xff\xfc', False)
60 _runtest("f", 2 ** 8, b"\xda", b"\x01\x00", False)
61 _runtest("f", 2 ** 16 - 4, b"\xda", b"\xff\xfc", False)
7662
7763
7864 def test_str32_from_byte():
79 _runtest('B', 2**16, b'\xdb', b'\x00\x01\x00\x00', False)
65 _runtest("B", 2 ** 16, b"\xdb", b"\x00\x01\x00\x00", False)
8066
8167
8268 def test_str32_from_float():
83 _runtest('f', 2**16, b'\xdb', b'\x00\x01\x00\x00', False)
69 _runtest("f", 2 ** 16, b"\xdb", b"\x00\x01\x00\x00", False)
8470
8571
8672 def test_bin8_from_byte():
87 _runtest('B', 1, b'\xc4', b'\x01', True)
88 _runtest('B', 2**8-1, b'\xc4', b'\xff', True)
73 _runtest("B", 1, b"\xc4", b"\x01", True)
74 _runtest("B", 2 ** 8 - 1, b"\xc4", b"\xff", True)
8975
9076
9177 def test_bin8_from_float():
92 _runtest('f', 4, b'\xc4', b'\x04', True)
93 _runtest('f', 2**8-4, b'\xc4', b'\xfc', True)
78 _runtest("f", 4, b"\xc4", b"\x04", True)
79 _runtest("f", 2 ** 8 - 4, b"\xc4", b"\xfc", True)
9480
9581
9682 def test_bin16_from_byte():
97 _runtest('B', 2**8, b'\xc5', b'\x01\x00', True)
98 _runtest('B', 2**16-1, b'\xc5', b'\xff\xff', True)
83 _runtest("B", 2 ** 8, b"\xc5", b"\x01\x00", True)
84 _runtest("B", 2 ** 16 - 1, b"\xc5", b"\xff\xff", True)
9985
10086
10187 def test_bin16_from_float():
102 _runtest('f', 2**8, b'\xc5', b'\x01\x00', True)
103 _runtest('f', 2**16-4, b'\xc5', b'\xff\xfc', True)
88 _runtest("f", 2 ** 8, b"\xc5", b"\x01\x00", True)
89 _runtest("f", 2 ** 16 - 4, b"\xc5", b"\xff\xfc", True)
10490
10591
10692 def test_bin32_from_byte():
107 _runtest('B', 2**16, b'\xc6', b'\x00\x01\x00\x00', True)
93 _runtest("B", 2 ** 16, b"\xc6", b"\x00\x01\x00\x00", True)
10894
10995
11096 def test_bin32_from_float():
111 _runtest('f', 2**16, b'\xc6', b'\x00\x01\x00\x00', True)
97 _runtest("f", 2 ** 16, b"\xc6", b"\x00\x01\x00\x00", True)
33
44
55 def test_str8():
6 header = b'\xd9'
7 data = b'x' * 32
6 header = b"\xd9"
7 data = b"x" * 32
88 b = packb(data.decode(), use_bin_type=True)
99 assert len(b) == len(data) + 2
10 assert b[0:2] == header + b'\x20'
10 assert b[0:2] == header + b"\x20"
11 assert b[2:] == data
12 assert unpackb(b, raw=True) == data
13 assert unpackb(b, raw=False) == data.decode()
14
15 data = b"x" * 255
16 b = packb(data.decode(), use_bin_type=True)
17 assert len(b) == len(data) + 2
18 assert b[0:2] == header + b"\xff"
19 assert b[2:] == data
20 assert unpackb(b, raw=True) == data
21 assert unpackb(b, raw=False) == data.decode()
22
23
24 def test_bin8():
25 header = b"\xc4"
26 data = b""
27 b = packb(data, use_bin_type=True)
28 assert len(b) == len(data) + 2
29 assert b[0:2] == header + b"\x00"
1130 assert b[2:] == data
1231 assert unpackb(b) == data
1332
14 data = b'x' * 255
15 b = packb(data.decode(), use_bin_type=True)
16 assert len(b) == len(data) + 2
17 assert b[0:2] == header + b'\xff'
18 assert b[2:] == data
19 assert unpackb(b) == data
20
21
22 def test_bin8():
23 header = b'\xc4'
24 data = b''
33 data = b"x" * 255
2534 b = packb(data, use_bin_type=True)
2635 assert len(b) == len(data) + 2
27 assert b[0:2] == header + b'\x00'
28 assert b[2:] == data
29 assert unpackb(b) == data
30
31 data = b'x' * 255
32 b = packb(data, use_bin_type=True)
33 assert len(b) == len(data) + 2
34 assert b[0:2] == header + b'\xff'
36 assert b[0:2] == header + b"\xff"
3537 assert b[2:] == data
3638 assert unpackb(b) == data
3739
3840
3941 def test_bin16():
40 header = b'\xc5'
41 data = b'x' * 256
42 header = b"\xc5"
43 data = b"x" * 256
4244 b = packb(data, use_bin_type=True)
4345 assert len(b) == len(data) + 3
4446 assert b[0:1] == header
45 assert b[1:3] == b'\x01\x00'
47 assert b[1:3] == b"\x01\x00"
4648 assert b[3:] == data
4749 assert unpackb(b) == data
4850
49 data = b'x' * 65535
51 data = b"x" * 65535
5052 b = packb(data, use_bin_type=True)
5153 assert len(b) == len(data) + 3
5254 assert b[0:1] == header
53 assert b[1:3] == b'\xff\xff'
55 assert b[1:3] == b"\xff\xff"
5456 assert b[3:] == data
5557 assert unpackb(b) == data
5658
5759
5860 def test_bin32():
59 header = b'\xc6'
60 data = b'x' * 65536
61 header = b"\xc6"
62 data = b"x" * 65536
6163 b = packb(data, use_bin_type=True)
6264 assert len(b) == len(data) + 5
6365 assert b[0:1] == header
64 assert b[1:5] == b'\x00\x01\x00\x00'
66 assert b[1:5] == b"\x00\x01\x00\x00"
6567 assert b[5:] == data
6668 assert unpackb(b) == data
69
6770
6871 def test_ext():
6972 def check(ext, packed):
7073 assert packb(ext) == packed
7174 assert unpackb(packed) == ext
72 check(ExtType(0x42, b'Z'), b'\xd4\x42Z') # fixext 1
73 check(ExtType(0x42, b'ZZ'), b'\xd5\x42ZZ') # fixext 2
74 check(ExtType(0x42, b'Z'*4), b'\xd6\x42' + b'Z'*4) # fixext 4
75 check(ExtType(0x42, b'Z'*8), b'\xd7\x42' + b'Z'*8) # fixext 8
76 check(ExtType(0x42, b'Z'*16), b'\xd8\x42' + b'Z'*16) # fixext 16
75
76 check(ExtType(0x42, b"Z"), b"\xd4\x42Z") # fixext 1
77 check(ExtType(0x42, b"ZZ"), b"\xd5\x42ZZ") # fixext 2
78 check(ExtType(0x42, b"Z" * 4), b"\xd6\x42" + b"Z" * 4) # fixext 4
79 check(ExtType(0x42, b"Z" * 8), b"\xd7\x42" + b"Z" * 8) # fixext 8
80 check(ExtType(0x42, b"Z" * 16), b"\xd8\x42" + b"Z" * 16) # fixext 16
7781 # ext 8
78 check(ExtType(0x42, b''), b'\xc7\x00\x42')
79 check(ExtType(0x42, b'Z'*255), b'\xc7\xff\x42' + b'Z'*255)
82 check(ExtType(0x42, b""), b"\xc7\x00\x42")
83 check(ExtType(0x42, b"Z" * 255), b"\xc7\xff\x42" + b"Z" * 255)
8084 # ext 16
81 check(ExtType(0x42, b'Z'*256), b'\xc8\x01\x00\x42' + b'Z'*256)
82 check(ExtType(0x42, b'Z'*0xffff), b'\xc8\xff\xff\x42' + b'Z'*0xffff)
85 check(ExtType(0x42, b"Z" * 256), b"\xc8\x01\x00\x42" + b"Z" * 256)
86 check(ExtType(0x42, b"Z" * 0xFFFF), b"\xc8\xff\xff\x42" + b"Z" * 0xFFFF)
8387 # ext 32
84 check(ExtType(0x42, b'Z'*0x10000), b'\xc9\x00\x01\x00\x00\x42' + b'Z'*0x10000)
88 check(ExtType(0x42, b"Z" * 0x10000), b"\xc9\x00\x01\x00\x00\x42" + b"Z" * 0x10000)
8589 # needs large memory
86 #check(ExtType(0x42, b'Z'*0xffffffff),
90 # check(ExtType(0x42, b'Z'*0xffffffff),
8791 # b'\xc9\xff\xff\xff\xff\x42' + b'Z'*0xffffffff)
33 from pytest import raises
44 from msgpack import packb, unpackb
55
6
67 def _decode_complex(obj):
7 if b'__complex__' in obj:
8 return complex(obj[b'real'], obj[b'imag'])
8 if b"__complex__" in obj:
9 return complex(obj[b"real"], obj[b"imag"])
910 return obj
11
1012
1113 def _encode_complex(obj):
1214 if isinstance(obj, complex):
13 return {b'__complex__': True, b'real': 1, b'imag': 2}
15 return {b"__complex__": True, b"real": 1, b"imag": 2}
1416 return obj
1517
18
1619 def test_encode_hook():
17 packed = packb([3, 1+2j], default=_encode_complex)
20 packed = packb([3, 1 + 2j], default=_encode_complex)
1821 unpacked = unpackb(packed, use_list=1)
19 assert unpacked[1] == {b'__complex__': True, b'real': 1, b'imag': 2}
22 assert unpacked[1] == {b"__complex__": True, b"real": 1, b"imag": 2}
23
2024
2125 def test_decode_hook():
22 packed = packb([3, {b'__complex__': True, b'real': 1, b'imag': 2}])
26 packed = packb([3, {b"__complex__": True, b"real": 1, b"imag": 2}])
2327 unpacked = unpackb(packed, object_hook=_decode_complex, use_list=1)
24 assert unpacked[1] == 1+2j
28 assert unpacked[1] == 1 + 2j
29
2530
2631 def test_decode_pairs_hook():
2732 packed = packb([3, {1: 2, 3: 4}])
2833 prod_sum = 1 * 2 + 3 * 4
29 unpacked = unpackb(packed, object_pairs_hook=lambda l: sum(k * v for k, v in l), use_list=1)
34 unpacked = unpackb(
35 packed,
36 object_pairs_hook=lambda l: sum(k * v for k, v in l),
37 use_list=1,
38 strict_map_key=False,
39 )
3040 assert unpacked[1] == prod_sum
41
3142
3243 def test_only_one_obj_hook():
3344 with raises(TypeError):
34 unpackb(b'', object_hook=lambda x: x, object_pairs_hook=lambda x: x)
45 unpackb(b"", object_hook=lambda x: x, object_pairs_hook=lambda x: x)
46
3547
3648 def test_bad_hook():
3749 with raises(TypeError):
38 packed = packb([3, 1+2j], default=lambda o: o)
50 packed = packb([3, 1 + 2j], default=lambda o: o)
3951 unpacked = unpackb(packed, use_list=1)
4052
53
4154 def _arr_to_str(arr):
42 return ''.join(str(c) for c in arr)
55 return "".join(str(c) for c in arr)
56
4357
4458 def test_array_hook():
45 packed = packb([1,2,3])
59 packed = packb([1, 2, 3])
4660 unpacked = unpackb(packed, list_hook=_arr_to_str, use_list=1)
47 assert unpacked == '123'
61 assert unpacked == "123"
4862
4963
5064 class DecodeError(Exception):
5165 pass
66
5267
5368 def bad_complex_decoder(o):
5469 raise DecodeError("Ooops!")
5671
5772 def test_an_exception_in_objecthook1():
5873 with raises(DecodeError):
59 packed = packb({1: {'__complex__': True, 'real': 1, 'imag': 2}})
60 unpackb(packed, object_hook=bad_complex_decoder)
74 packed = packb({1: {"__complex__": True, "real": 1, "imag": 2}})
75 unpackb(packed, object_hook=bad_complex_decoder, strict_map_key=False)
6176
6277
6378 def test_an_exception_in_objecthook2():
6479 with raises(DecodeError):
65 packed = packb({1: [{'__complex__': True, 'real': 1, 'imag': 2}]})
66 unpackb(packed, list_hook=bad_complex_decoder, use_list=1)
80 packed = packb({1: [{"__complex__": True, "real": 1, "imag": 2}]})
81 unpackb(packed, list_hook=bad_complex_decoder, use_list=1, strict_map_key=False)
44 from collections import OrderedDict
55 from io import BytesIO
66 import struct
7 import sys
78
89 import pytest
910 from pytest import raises, xfail
1213
1314
1415 def check(data, use_list=False):
15 re = unpackb(packb(data), use_list=use_list)
16 re = unpackb(packb(data), use_list=use_list, strict_map_key=False)
1617 assert re == data
18
1719
1820 def testPack():
1921 test_data = [
20 0, 1, 127, 128, 255, 256, 65535, 65536, 4294967295, 4294967296,
21 -1, -32, -33, -128, -129, -32768, -32769, -4294967296, -4294967297,
22 1.0,
23 b"", b"a", b"a"*31, b"a"*32,
24 None, True, False,
25 (), ((),), ((), None,),
22 0,
23 1,
24 127,
25 128,
26 255,
27 256,
28 65535,
29 65536,
30 4294967295,
31 4294967296,
32 -1,
33 -32,
34 -33,
35 -128,
36 -129,
37 -32768,
38 -32769,
39 -4294967296,
40 -4294967297,
41 1.0,
42 b"",
43 b"a",
44 b"a" * 31,
45 b"a" * 32,
46 None,
47 True,
48 False,
49 (),
50 ((),),
51 ((), None),
2652 {None: 0},
27 (1<<23),
28 ]
53 (1 << 23),
54 ]
2955 for td in test_data:
3056 check(td)
57
3158
3259 def testPackUnicode():
3360 test_data = ["", "abcd", ["defgh"], "Русский текст"]
3966 re = Unpacker(BytesIO(data), raw=False, use_list=1).unpack()
4067 assert re == td
4168
42 def testPackUTF32(): # deprecated
43 try:
44 test_data = [
45 "",
46 "abcd",
47 ["defgh"],
48 "Русский текст",
49 ]
50 for td in test_data:
51 with pytest.deprecated_call():
52 re = unpackb(packb(td, encoding='utf-32'), use_list=1, encoding='utf-32')
53 assert re == td
54 except LookupError as e:
55 xfail(e)
5669
5770 def testPackBytes():
58 test_data = [
59 b"", b"abcd", (b"defgh",),
60 ]
71 test_data = [b"", b"abcd", (b"defgh",)]
6172 for td in test_data:
6273 check(td)
6374
75
6476 def testPackByteArrays():
65 test_data = [
66 bytearray(b""), bytearray(b"abcd"), (bytearray(b"defgh"),),
67 ]
77 test_data = [bytearray(b""), bytearray(b"abcd"), (bytearray(b"defgh"),)]
6878 for td in test_data:
6979 check(td)
7080
71 def testIgnoreUnicodeErrors(): # deprecated
72 with pytest.deprecated_call():
73 re = unpackb(packb(b'abc\xeddef'), encoding='utf-8', unicode_errors='ignore', use_list=1)
81
82 @pytest.mark.skipif(
83 sys.version_info < (3, 0), reason="Python 2 passes invalid surrogates"
84 )
85 def testIgnoreUnicodeErrors():
86 re = unpackb(
87 packb(b"abc\xeddef", use_bin_type=False), raw=False, unicode_errors="ignore"
88 )
7489 assert re == "abcdef"
7590
91
7692 def testStrictUnicodeUnpack():
77 packed = packb(b'abc\xeddef')
93 packed = packb(b"abc\xeddef", use_bin_type=False)
7894 with pytest.raises(UnicodeDecodeError):
7995 unpackb(packed, raw=False, use_list=1)
8096
81 def testStrictUnicodePack(): # deprecated
82 with raises(UnicodeEncodeError):
83 with pytest.deprecated_call():
84 packb("abc\xeddef", encoding='ascii', unicode_errors='strict')
8597
86 def testIgnoreErrorsPack(): # deprecated
87 with pytest.deprecated_call():
88 re = unpackb(packb("abcФФФdef", encoding='ascii', unicode_errors='ignore'), raw=False, use_list=1)
98 @pytest.mark.skipif(
99 sys.version_info < (3, 0), reason="Python 2 passes invalid surrogates"
100 )
101 def testIgnoreErrorsPack():
102 re = unpackb(
103 packb("abc\uDC80\uDCFFdef", use_bin_type=True, unicode_errors="ignore"),
104 raw=False,
105 use_list=1,
106 )
89107 assert re == "abcdef"
90108
109
91110 def testDecodeBinary():
92 re = unpackb(packb(b"abc"), encoding=None, use_list=1)
111 re = unpackb(packb(b"abc"), use_list=1)
93112 assert re == b"abc"
94113
114
95115 def testPackFloat():
96 assert packb(1.0, use_single_float=True) == b'\xca' + struct.pack(str('>f'), 1.0)
97 assert packb(1.0, use_single_float=False) == b'\xcb' + struct.pack(str('>d'), 1.0)
116 assert packb(1.0, use_single_float=True) == b"\xca" + struct.pack(str(">f"), 1.0)
117 assert packb(1.0, use_single_float=False) == b"\xcb" + struct.pack(str(">d"), 1.0)
118
98119
99120 def testArraySize(sizes=[0, 5, 50, 1000]):
100121 bio = BytesIO()
109130 for size in sizes:
110131 assert unpacker.unpack() == list(range(size))
111132
133
112134 def test_manualreset(sizes=[0, 5, 50, 1000]):
113135 packer = Packer(autoreset=False)
114136 for size in sizes:
122144 assert unpacker.unpack() == list(range(size))
123145
124146 packer.reset()
125 assert packer.bytes() == b''
147 assert packer.bytes() == b""
148
126149
127150 def testMapSize(sizes=[0, 5, 50, 1000]):
128151 bio = BytesIO()
130153 for size in sizes:
131154 bio.write(packer.pack_map_header(size))
132155 for i in range(size):
133 bio.write(packer.pack(i)) # key
134 bio.write(packer.pack(i * 2)) # value
156 bio.write(packer.pack(i)) # key
157 bio.write(packer.pack(i * 2)) # value
135158
136159 bio.seek(0)
137 unpacker = Unpacker(bio)
160 unpacker = Unpacker(bio, strict_map_key=False)
138161 for size in sizes:
139162 assert unpacker.unpack() == dict((i, i * 2) for i in range(size))
140163
141164
142165 def test_odict():
143 seq = [(b'one', 1), (b'two', 2), (b'three', 3), (b'four', 4)]
166 seq = [(b"one", 1), (b"two", 2), (b"three", 3), (b"four", 4)]
144167 od = OrderedDict(seq)
145168 assert unpackb(packb(od), use_list=1) == dict(seq)
169
146170 def pair_hook(seq):
147171 return list(seq)
172
148173 assert unpackb(packb(od), object_pairs_hook=pair_hook, use_list=1) == seq
149174
150175
151176 def test_pairlist():
152 pairlist = [(b'a', 1), (2, b'b'), (b'foo', b'bar')]
177 pairlist = [(b"a", 1), (2, b"b"), (b"foo", b"bar")]
153178 packer = Packer()
154179 packed = packer.pack_map_pairs(pairlist)
155 unpacked = unpackb(packed, object_pairs_hook=list)
180 unpacked = unpackb(packed, object_pairs_hook=list, strict_map_key=False)
156181 assert pairlist == unpacked
182
157183
158184 def test_get_buffer():
159185 packer = Packer(autoreset=0, use_bin_type=True)
00 """Test Unpacker's read_array_header and read_map_header methods"""
11 from msgpack import packb, Unpacker, OutOfData
2
23 UnexpectedTypeException = ValueError
4
35
46 def test_read_array_header():
57 unpacker = Unpacker()
6 unpacker.feed(packb(['a', 'b', 'c']))
8 unpacker.feed(packb(["a", "b", "c"]))
79 assert unpacker.read_array_header() == 3
8 assert unpacker.unpack() == b'a'
9 assert unpacker.unpack() == b'b'
10 assert unpacker.unpack() == b'c'
10 assert unpacker.unpack() == "a"
11 assert unpacker.unpack() == "b"
12 assert unpacker.unpack() == "c"
1113 try:
1214 unpacker.unpack()
13 assert 0, 'should raise exception'
15 assert 0, "should raise exception"
1416 except OutOfData:
15 assert 1, 'okay'
17 assert 1, "okay"
1618
1719
1820 def test_read_map_header():
1921 unpacker = Unpacker()
20 unpacker.feed(packb({'a': 'A'}))
22 unpacker.feed(packb({"a": "A"}))
2123 assert unpacker.read_map_header() == 1
22 assert unpacker.unpack() == B'a'
23 assert unpacker.unpack() == B'A'
24 assert unpacker.unpack() == "a"
25 assert unpacker.unpack() == "A"
2426 try:
2527 unpacker.unpack()
26 assert 0, 'should raise exception'
28 assert 0, "should raise exception"
2729 except OutOfData:
28 assert 1, 'okay'
30 assert 1, "okay"
31
2932
3033 def test_incorrect_type_array():
3134 unpacker = Unpacker()
3235 unpacker.feed(packb(1))
3336 try:
3437 unpacker.read_array_header()
35 assert 0, 'should raise exception'
38 assert 0, "should raise exception"
3639 except UnexpectedTypeException:
37 assert 1, 'okay'
40 assert 1, "okay"
41
3842
3943 def test_incorrect_type_map():
4044 unpacker = Unpacker()
4145 unpacker.feed(packb(1))
4246 try:
4347 unpacker.read_map_header()
44 assert 0, 'should raise exception'
48 assert 0, "should raise exception"
4549 except UnexpectedTypeException:
46 assert 1, 'okay'
50 assert 1, "okay"
51
4752
4853 def test_correct_type_nested_array():
4954 unpacker = Unpacker()
50 unpacker.feed(packb({'a': ['b', 'c', 'd']}))
55 unpacker.feed(packb({"a": ["b", "c", "d"]}))
5156 try:
5257 unpacker.read_array_header()
53 assert 0, 'should raise exception'
58 assert 0, "should raise exception"
5459 except UnexpectedTypeException:
55 assert 1, 'okay'
60 assert 1, "okay"
61
5662
5763 def test_incorrect_type_nested_map():
5864 unpacker = Unpacker()
59 unpacker.feed(packb([{'a': 'b'}]))
65 unpacker.feed(packb([{"a": "b"}]))
6066 try:
6167 unpacker.read_map_header()
62 assert 0, 'should raise exception'
68 assert 0, "should raise exception"
6369 except UnexpectedTypeException:
64 assert 1, 'okay'
65
70 assert 1, "okay"
66
77 binarydata = bytes(bytearray(range(256)))
88
9
910 def gen_binary_data(idx):
10 return binarydata[:idx % 300]
11 return binarydata[: idx % 300]
1112
1213
1314 def test_exceeding_unpacker_read_size():
1718
1819 NUMBER_OF_STRINGS = 6
1920 read_size = 16
20 # 5 ok for read_size=16, while 6 glibc detected *** python: double free or corruption (fasttop):
21 # 20 ok for read_size=256, while 25 segfaults / glibc detected *** python: double free or corruption (!prev)
22 # 40 ok for read_size=1024, while 50 introduces errors
23 # 7000 ok for read_size=1024*1024, while 8000 leads to glibc detected *** python: double free or corruption (!prev):
21 # 5 ok for read_size=16, while 6 glibc detected *** python: double free or corruption (fasttop):
22 # 20 ok for read_size=256, while 25 segfaults / glibc detected *** python: double free or corruption (!prev)
23 # 40 ok for read_size=1024, while 50 introduces errors
24 # 7000 ok for read_size=1024*1024, while 8000 leads to glibc detected *** python: double free or corruption (!prev):
2425
2526 for idx in range(NUMBER_OF_STRINGS):
2627 data = gen_binary_data(idx)
00 #!/usr/bin/env python
11 # coding: utf-8
2
32 import io
43 from msgpack import Unpacker, BufferFull
54 from msgpack import pack
98
109 def test_partialdata():
1110 unpacker = Unpacker()
12 unpacker.feed(b'\xa5')
13 with raises(StopIteration): next(iter(unpacker))
14 unpacker.feed(b'h')
15 with raises(StopIteration): next(iter(unpacker))
16 unpacker.feed(b'a')
17 with raises(StopIteration): next(iter(unpacker))
18 unpacker.feed(b'l')
19 with raises(StopIteration): next(iter(unpacker))
20 unpacker.feed(b'l')
21 with raises(StopIteration): next(iter(unpacker))
22 unpacker.feed(b'o')
23 assert next(iter(unpacker)) == b'hallo'
11 unpacker.feed(b"\xa5")
12 with raises(StopIteration):
13 next(iter(unpacker))
14 unpacker.feed(b"h")
15 with raises(StopIteration):
16 next(iter(unpacker))
17 unpacker.feed(b"a")
18 with raises(StopIteration):
19 next(iter(unpacker))
20 unpacker.feed(b"l")
21 with raises(StopIteration):
22 next(iter(unpacker))
23 unpacker.feed(b"l")
24 with raises(StopIteration):
25 next(iter(unpacker))
26 unpacker.feed(b"o")
27 assert next(iter(unpacker)) == "hallo"
28
2429
2530 def test_foobar():
2631 unpacker = Unpacker(read_size=3, use_list=1)
27 unpacker.feed(b'foobar')
28 assert unpacker.unpack() == ord(b'f')
29 assert unpacker.unpack() == ord(b'o')
30 assert unpacker.unpack() == ord(b'o')
31 assert unpacker.unpack() == ord(b'b')
32 assert unpacker.unpack() == ord(b'a')
33 assert unpacker.unpack() == ord(b'r')
32 unpacker.feed(b"foobar")
33 assert unpacker.unpack() == ord(b"f")
34 assert unpacker.unpack() == ord(b"o")
35 assert unpacker.unpack() == ord(b"o")
36 assert unpacker.unpack() == ord(b"b")
37 assert unpacker.unpack() == ord(b"a")
38 assert unpacker.unpack() == ord(b"r")
3439 with raises(OutOfData):
3540 unpacker.unpack()
3641
37 unpacker.feed(b'foo')
38 unpacker.feed(b'bar')
42 unpacker.feed(b"foo")
43 unpacker.feed(b"bar")
3944
4045 k = 0
41 for o, e in zip(unpacker, 'foobarbaz'):
46 for o, e in zip(unpacker, "foobarbaz"):
4247 assert o == ord(e)
4348 k += 1
44 assert k == len(b'foobar')
49 assert k == len(b"foobar")
50
4551
4652 def test_foobar_skip():
4753 unpacker = Unpacker(read_size=3, use_list=1)
48 unpacker.feed(b'foobar')
49 assert unpacker.unpack() == ord(b'f')
54 unpacker.feed(b"foobar")
55 assert unpacker.unpack() == ord(b"f")
5056 unpacker.skip()
51 assert unpacker.unpack() == ord(b'o')
57 assert unpacker.unpack() == ord(b"o")
5258 unpacker.skip()
53 assert unpacker.unpack() == ord(b'a')
59 assert unpacker.unpack() == ord(b"a")
5460 unpacker.skip()
5561 with raises(OutOfData):
5662 unpacker.unpack()
63
5764
5865 def test_maxbuffersize():
5966 with raises(ValueError):
6067 Unpacker(read_size=5, max_buffer_size=3)
6168 unpacker = Unpacker(read_size=3, max_buffer_size=3, use_list=1)
62 unpacker.feed(b'fo')
69 unpacker.feed(b"fo")
6370 with raises(BufferFull):
64 unpacker.feed(b'ob')
65 unpacker.feed(b'o')
66 assert ord('f') == next(unpacker)
67 unpacker.feed(b'b')
68 assert ord('o') == next(unpacker)
69 assert ord('o') == next(unpacker)
70 assert ord('b') == next(unpacker)
71 unpacker.feed(b"ob")
72 unpacker.feed(b"o")
73 assert ord("f") == next(unpacker)
74 unpacker.feed(b"b")
75 assert ord("o") == next(unpacker)
76 assert ord("o") == next(unpacker)
77 assert ord("b") == next(unpacker)
7178
7279
7380 def test_readbytes():
7481 unpacker = Unpacker(read_size=3)
75 unpacker.feed(b'foobar')
76 assert unpacker.unpack() == ord(b'f')
77 assert unpacker.read_bytes(3) == b'oob'
78 assert unpacker.unpack() == ord(b'a')
79 assert unpacker.unpack() == ord(b'r')
82 unpacker.feed(b"foobar")
83 assert unpacker.unpack() == ord(b"f")
84 assert unpacker.read_bytes(3) == b"oob"
85 assert unpacker.unpack() == ord(b"a")
86 assert unpacker.unpack() == ord(b"r")
8087
8188 # Test buffer refill
82 unpacker = Unpacker(io.BytesIO(b'foobar'), read_size=3)
83 assert unpacker.unpack() == ord(b'f')
84 assert unpacker.read_bytes(3) == b'oob'
85 assert unpacker.unpack() == ord(b'a')
86 assert unpacker.unpack() == ord(b'r')
89 unpacker = Unpacker(io.BytesIO(b"foobar"), read_size=3)
90 assert unpacker.unpack() == ord(b"f")
91 assert unpacker.read_bytes(3) == b"oob"
92 assert unpacker.unpack() == ord(b"a")
93 assert unpacker.unpack() == ord(b"r")
94
95 # Issue 352
96 u = Unpacker()
97 u.feed(b"x")
98 assert bytes(u.read_bytes(1)) == b"x"
99 with raises(StopIteration):
100 next(u)
101 u.feed(b"\1")
102 assert next(u) == 1
103
87104
88105 def test_issue124():
89106 unpacker = Unpacker()
90 unpacker.feed(b'\xa1?\xa1!')
91 assert tuple(unpacker) == (b'?', b'!')
107 unpacker.feed(b"\xa1?\xa1!")
108 assert tuple(unpacker) == ("?", "!")
92109 assert tuple(unpacker) == ()
93110 unpacker.feed(b"\xa1?\xa1")
94 assert tuple(unpacker) == (b'?',)
111 assert tuple(unpacker) == ("?",)
95112 assert tuple(unpacker) == ()
96113 unpacker.feed(b"!")
97 assert tuple(unpacker) == (b'!',)
114 assert tuple(unpacker) == ("!",)
98115 assert tuple(unpacker) == ()
99116
100117
101118 def test_unpack_tell():
102119 stream = io.BytesIO()
103 messages = [2**i-1 for i in range(65)]
104 messages += [-(2**i) for i in range(1, 64)]
105 messages += [b'hello', b'hello'*1000, list(range(20)),
106 {i: bytes(i)*i for i in range(10)},
107 {i: bytes(i)*i for i in range(32)}]
120 messages = [2 ** i - 1 for i in range(65)]
121 messages += [-(2 ** i) for i in range(1, 64)]
122 messages += [
123 b"hello",
124 b"hello" * 1000,
125 list(range(20)),
126 {i: bytes(i) * i for i in range(10)},
127 {i: bytes(i) * i for i in range(32)},
128 ]
108129 offsets = []
109130 for m in messages:
110131 pack(m, stream)
111132 offsets.append(stream.tell())
112133 stream.seek(0)
113 unpacker = Unpacker(stream)
134 unpacker = Unpacker(stream, strict_map_key=False)
114135 for m, o in zip(messages, offsets):
115136 m2 = next(unpacker)
116137 assert m == m2
44
55
66 def test_namedtuple():
7 T = namedtuple('T', "foo bar")
7 T = namedtuple("T", "foo bar")
8
89 def default(o):
910 if isinstance(o, T):
1011 return dict(o._asdict())
11 raise TypeError('Unsupported type %s' % (type(o),))
12 raise TypeError("Unsupported type %s" % (type(o),))
13
1214 packed = packb(T(1, 42), strict_types=True, use_bin_type=True, default=default)
1315 unpacked = unpackb(packed, raw=False)
14 assert unpacked == {'foo': 1, 'bar': 42}
16 assert unpacked == {"foo": 1, "bar": 42}
1517
1618
1719 def test_tuple():
18 t = ('one', 2, b'three', (4, ))
20 t = ("one", 2, b"three", (4,))
1921
2022 def default(o):
2123 if isinstance(o, tuple):
22 return {
23 '__type__': 'tuple',
24 'value': list(o),
25 }
26 raise TypeError('Unsupported type %s' % (type(o),))
24 return {"__type__": "tuple", "value": list(o)}
25 raise TypeError("Unsupported type %s" % (type(o),))
2726
2827 def convert(o):
29 if o.get('__type__') == 'tuple':
30 return tuple(o['value'])
28 if o.get("__type__") == "tuple":
29 return tuple(o["value"])
3130 return o
3231
3332 data = packb(t, strict_types=True, use_bin_type=True, default=default)
3736
3837
3938 def test_tuple_ext():
40 t = ('one', 2, b'three', (4, ))
39 t = ("one", 2, b"three", (4,))
4140
4241 MSGPACK_EXT_TYPE_TUPLE = 0
4342
4544 if isinstance(o, tuple):
4645 # Convert to list and pack
4746 payload = packb(
48 list(o), strict_types=True, use_bin_type=True, default=default)
47 list(o), strict_types=True, use_bin_type=True, default=default
48 )
4949 return ExtType(MSGPACK_EXT_TYPE_TUPLE, payload)
5050 raise TypeError(repr(o))
5151
5353 if code == MSGPACK_EXT_TYPE_TUPLE:
5454 # Unpack and convert to tuple
5555 return tuple(unpackb(payload, raw=False, ext_hook=convert))
56 raise ValueError('Unknown Ext code {}'.format(code))
56 raise ValueError("Unknown Ext code {}".format(code))
5757
5858 data = packb(t, strict_types=True, use_bin_type=True, default=default)
5959 expected = unpackb(data, raw=False, ext_hook=convert)
33 from msgpack import packb, unpackb
44 from collections import namedtuple
55
6
67 class MyList(list):
78 pass
9
810
911 class MyDict(dict):
1012 pass
1113
14
1215 class MyTuple(tuple):
1316 pass
1417
15 MyNamedTuple = namedtuple('MyNamedTuple', 'x y')
18
19 MyNamedTuple = namedtuple("MyNamedTuple", "x y")
20
1621
1722 def test_types():
1823 assert packb(MyDict()) == packb(dict())
0 import pytest
1 import sys
2 import datetime
3 import msgpack
4 from msgpack.ext import Timestamp
5
6 if sys.version_info[0] > 2:
7 from msgpack.ext import _utc
8
9
10 def test_timestamp():
11 # timestamp32
12 ts = Timestamp(2 ** 32 - 1)
13 assert ts.to_bytes() == b"\xff\xff\xff\xff"
14 packed = msgpack.packb(ts)
15 assert packed == b"\xd6\xff" + ts.to_bytes()
16 unpacked = msgpack.unpackb(packed)
17 assert ts == unpacked
18 assert ts.seconds == 2 ** 32 - 1 and ts.nanoseconds == 0
19
20 # timestamp64
21 ts = Timestamp(2 ** 34 - 1, 999999999)
22 assert ts.to_bytes() == b"\xee\x6b\x27\xff\xff\xff\xff\xff"
23 packed = msgpack.packb(ts)
24 assert packed == b"\xd7\xff" + ts.to_bytes()
25 unpacked = msgpack.unpackb(packed)
26 assert ts == unpacked
27 assert ts.seconds == 2 ** 34 - 1 and ts.nanoseconds == 999999999
28
29 # timestamp96
30 ts = Timestamp(2 ** 63 - 1, 999999999)
31 assert ts.to_bytes() == b"\x3b\x9a\xc9\xff\x7f\xff\xff\xff\xff\xff\xff\xff"
32 packed = msgpack.packb(ts)
33 assert packed == b"\xc7\x0c\xff" + ts.to_bytes()
34 unpacked = msgpack.unpackb(packed)
35 assert ts == unpacked
36 assert ts.seconds == 2 ** 63 - 1 and ts.nanoseconds == 999999999
37
38 # negative fractional
39 ts = Timestamp.from_unix(-2.3) # s: -3, ns: 700000000
40 assert ts.seconds == -3 and ts.nanoseconds == 700000000
41 assert ts.to_bytes() == b"\x29\xb9\x27\x00\xff\xff\xff\xff\xff\xff\xff\xfd"
42 packed = msgpack.packb(ts)
43 assert packed == b"\xc7\x0c\xff" + ts.to_bytes()
44 unpacked = msgpack.unpackb(packed)
45 assert ts == unpacked
46
47
48 def test_unpack_timestamp():
49 # timestamp 32
50 assert msgpack.unpackb(b"\xd6\xff\x00\x00\x00\x00") == Timestamp(0)
51
52 # timestamp 64
53 assert msgpack.unpackb(b"\xd7\xff" + b"\x00" * 8) == Timestamp(0)
54 with pytest.raises(ValueError):
55 msgpack.unpackb(b"\xd7\xff" + b"\xff" * 8)
56
57 # timestamp 96
58 assert msgpack.unpackb(b"\xc7\x0c\xff" + b"\x00" * 12) == Timestamp(0)
59 with pytest.raises(ValueError):
60 msgpack.unpackb(b"\xc7\x0c\xff" + b"\xff" * 12) == Timestamp(0)
61
62 # Undefined
63 with pytest.raises(ValueError):
64 msgpack.unpackb(b"\xd4\xff\x00") # fixext 1
65 with pytest.raises(ValueError):
66 msgpack.unpackb(b"\xd5\xff\x00\x00") # fixext 2
67 with pytest.raises(ValueError):
68 msgpack.unpackb(b"\xc7\x00\xff") # ext8 (len=0)
69 with pytest.raises(ValueError):
70 msgpack.unpackb(b"\xc7\x03\xff\0\0\0") # ext8 (len=3)
71 with pytest.raises(ValueError):
72 msgpack.unpackb(b"\xc7\x05\xff\0\0\0\0\0") # ext8 (len=5)
73
74
75 def test_timestamp_from():
76 t = Timestamp(42, 14000)
77 assert Timestamp.from_unix(42.000014) == t
78 assert Timestamp.from_unix_nano(42000014000) == t
79
80
81 def test_timestamp_to():
82 t = Timestamp(42, 14000)
83 assert t.to_unix() == 42.000014
84 assert t.to_unix_nano() == 42000014000
85
86
87 @pytest.mark.skipif(sys.version_info[0] == 2, reason="datetime support is PY3+ only")
88 def test_timestamp_datetime():
89 t = Timestamp(42, 14)
90 assert t.to_datetime() == datetime.datetime(1970, 1, 1, 0, 0, 42, 0, tzinfo=_utc)
91
92
93 @pytest.mark.skipif(sys.version_info[0] == 2, reason="datetime support is PY3+ only")
94 def test_unpack_datetime():
95 t = Timestamp(42, 14)
96 packed = msgpack.packb(t)
97 unpacked = msgpack.unpackb(packed, timestamp=3)
98 assert unpacked == datetime.datetime(1970, 1, 1, 0, 0, 42, 0, tzinfo=_utc)
99
100
101 @pytest.mark.skipif(sys.version_info[0] == 2, reason="datetime support is PY3+ only")
102 def test_pack_datetime():
103 t = Timestamp(42, 14000)
104 dt = t.to_datetime()
105 assert dt == datetime.datetime(1970, 1, 1, 0, 0, 42, 14, tzinfo=_utc)
106
107 packed = msgpack.packb(dt, datetime=True)
108 packed2 = msgpack.packb(t)
109 assert packed == packed2
110
111 unpacked = msgpack.unpackb(packed)
112 print(packed, unpacked)
113 assert unpacked == t
114
115 unpacked = msgpack.unpackb(packed, timestamp=3)
116 assert unpacked == dt
117
118 x = []
119 packed = msgpack.packb(dt, datetime=False, default=x.append)
120 assert x
121 assert x[0] == dt
122 assert msgpack.unpackb(packed) is None
44
55
66 def test_unpack_array_header_from_file():
7 f = BytesIO(packb([1,2,3,4]))
7 f = BytesIO(packb([1, 2, 3, 4]))
88 unpacker = Unpacker(f)
99 assert unpacker.read_array_header() == 4
1010 assert unpacker.unpack() == 1
1515 unpacker.unpack()
1616
1717
18 @mark.skipif("not hasattr(sys, 'getrefcount') == True",
19 reason='sys.getrefcount() is needed to pass this test')
18 @mark.skipif(
19 "not hasattr(sys, 'getrefcount') == True",
20 reason="sys.getrefcount() is needed to pass this test",
21 )
2022 def test_unpacker_hook_refcnt():
2123 result = []
2224
4244
4345
4446 def test_unpacker_ext_hook():
45
4647 class MyUnpacker(Unpacker):
47
4848 def __init__(self):
49 super(MyUnpacker, self).__init__(
50 ext_hook=self._hook, raw=False)
49 super(MyUnpacker, self).__init__(ext_hook=self._hook, raw=False)
5150
5251 def _hook(self, code, data):
5352 if code == 1:
5655 return ExtType(code, data)
5756
5857 unpacker = MyUnpacker()
59 unpacker.feed(packb({'a': 1}))
60 assert unpacker.unpack() == {'a': 1}
61 unpacker.feed(packb({'a': ExtType(1, b'123')}))
62 assert unpacker.unpack() == {'a': 123}
63 unpacker.feed(packb({'a': ExtType(2, b'321')}))
64 assert unpacker.unpack() == {'a': ExtType(2, b'321')}
58 unpacker.feed(packb({"a": 1}))
59 assert unpacker.unpack() == {"a": 1}
60 unpacker.feed(packb({"a": ExtType(1, b"123")}))
61 assert unpacker.unpack() == {"a": 123}
62 unpacker.feed(packb({"a": ExtType(2, b"321")}))
63 assert unpacker.unpack() == {"a": ExtType(2, b"321")}
6564
6665
67 if __name__ == '__main__':
66 if __name__ == "__main__":
6867 test_unpack_array_header_from_file()
6968 test_unpacker_hook_refcnt()
7069 test_unpacker_ext_hook()
00 [tox]
1 envlist = {py27,py35,py36,py37}-{c,pure},{pypy,pypy3}-pure,py27-x86,py34-x86
1 envlist =
2 py27-pure,
3 {py35,py36,py37,py38}-{c,pure},
4 {pypy,pypy3}-pure,
5 py27-x86,
6 py34-x86,
27
38 [variants:pure]
49 setenv=