tmsgpack 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/COPYING +1 -1
  2. {tmsgpack-0.1.0/tmsgpack.egg-info → tmsgpack-0.1.2}/PKG-INFO +59 -182
  3. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/README.md +58 -181
  4. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/contexts_for_tests.py +1 -1
  5. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_buffer.py +6 -6
  6. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_case.py +5 -23
  7. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_except.py +18 -7
  8. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_format.py +6 -11
  9. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_limits.py +9 -9
  10. tmsgpack-0.1.2/test/test_memoryview.py +72 -0
  11. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_newspec.py +9 -11
  12. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_pack.py +8 -28
  13. tmsgpack-0.1.2/test/test_roundtrip.py +51 -0
  14. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_seq.py +1 -1
  15. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_sequnpack.py +3 -3
  16. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_trace_from_x.py +7 -24
  17. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_typed_objects.py +2 -2
  18. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_unpack.py +3 -3
  19. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/__init__.py +31 -57
  20. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/_ctmsgpack.cpp +1620 -1864
  21. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/_packer.pyx +33 -47
  22. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/_unpacker.pyx +20 -42
  23. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/buff_converter.h +1 -1
  24. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/fallback.py +59 -76
  25. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/pack.h +0 -22
  26. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/pack_template.h +4 -7
  27. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/unpack.h +21 -39
  28. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/unpack_define.h +4 -4
  29. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/unpack_template.h +13 -13
  30. {tmsgpack-0.1.0 → tmsgpack-0.1.2/tmsgpack.egg-info}/PKG-INFO +59 -182
  31. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack.egg-info/SOURCES.txt +1 -1
  32. tmsgpack-0.1.0/test/test_memoryview.py +0 -100
  33. tmsgpack-0.1.0/tmsgpack/ext.py +0 -0
  34. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/MANIFEST.in +0 -0
  35. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/pyproject.toml +0 -0
  36. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/setup.cfg +0 -0
  37. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/setup.py +0 -0
  38. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/test/test_subtype.py +0 -0
  39. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/_ctmsgpack.pyx +0 -0
  40. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/exceptions.py +0 -0
  41. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack/sysdep.h +0 -0
  42. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack.egg-info/dependency_links.txt +0 -0
  43. {tmsgpack-0.1.0 → tmsgpack-0.1.2}/tmsgpack.egg-info/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- Copyright (C) 2008-2011 INADA Naoki <songofacandy@gmail.com>
1
+ Copyright (C) 2025 Yaakov Belch <yaakov.belch@gmail.com>
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tmsgpack
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Typed MessagePack serializer (similar but incompatible with msgpack)
5
5
  Home-page: https://github.com/Yaakov-Belch/tmsgpack
6
6
  Author: Inada Naoki, Yaakov Belch
@@ -24,8 +24,10 @@ Dynamic: license-file
24
24
 
25
25
  # tmsgpack: Typed MessagePack-inspired pack/unpack component
26
26
 
27
- The tmsgpack format expresses **typed objects**: maps and arrays (or: dicts and lists)
28
- with an `object_type` property.
27
+ See also: [FORMAT.md](FORMAT.md) and [DEVELOP.md](DEVELOP.md)
28
+
29
+ The tmsgpack format expresses **typed objects**: maps and arrays (or: dicts and
30
+ tuples/lists) with an `object_type` property.
29
31
 
30
32
  Unlike msgpack and pickle, this is not a batteries-included end-to-end serialization
31
33
  solution. It is a composable component that helps you to build end-to-end communication
@@ -47,7 +49,10 @@ This python package makes a minimal (backwards-incompatible) modification to the
47
49
  msgpack format to make all this elegantly possible. This package is based on
48
50
  `msgpack v1.0.5`.
49
51
 
50
- ## TODO: Installation
52
+ ## Installation
53
+ ```bash
54
+ pip install tmsgpack
55
+ ```
51
56
 
52
57
  ## Usage
53
58
  Packing and unpacking data is controlled by `pack_ctrl` and `unpack_ctrl` objects (see
@@ -93,7 +98,7 @@ class MinimalPackCtrl:
93
98
  class MinimalUnpackCtrl:
94
99
  def from_dict(self, ctype, dct):
95
100
  raise ValueError(f'Unpack type not supported: {ctype} data: {dct}')
96
- def from_list(self, ctype, lst):
101
+ def from_tuple(self, ctype, lst):
97
102
  raise ValueError(f'Unpack type not supported: {ctype} data: {lst}')
98
103
  options: UnpackConfig
99
104
 
@@ -106,15 +111,15 @@ minimal_unpack_ctrl = uctrl()
106
111
 
107
112
  ## The API and configuration
108
113
  As you see, the `pack_ctrl` object provides a method `from_obj`. The `unpack_ctrl`
109
- object provides the methods `from_dict` and `from_array`:
114
+ object provides the methods `from_dict` and `from_tuple`:
110
115
  ```python
111
116
  as_dict, data_type, data = pack_ctrl.from(obj)
112
117
 
113
118
  # When `as_dict` is true, then `data` should be a dictionary.
114
- # When `as_dict` is false, then `data` should be a list.
119
+ # When `as_dict` is false, then `data` should be a tuple or a list.
115
120
 
116
121
  unpacked = unpack_ctrl.from_dict(data_type, data) # used when as_dict is true.
117
- unpacked = unpack_ctrl.from_list(data_type, data) # used when as_dict is false.
122
+ unpacked = unpack_ctrl.from_tuple(data_type, data) # used when as_dict is false.
118
123
  ```
119
124
 
120
125
  ## PackConfig configuration objects for pack_ctrl
@@ -123,35 +128,24 @@ unpacked = unpack_ctrl.from_list(data_type, data) # used when as_dict is false.
123
128
  from tmsgpack import PackConfig
124
129
 
125
130
  config = PackConfig(
126
- use_single_float=False, use_bin_type=True,
127
- tuple_as_list=True, strict_types=False,
128
- unicode_errors='strict', sort_keys=False,
131
+ p_shortcuts=True, sort_keys=False, p_str_keys=False, use_single_float=False,
129
132
  )
130
133
  """
131
134
  Config object for pack_ctrl.options
132
135
 
133
- :param bool use_single_float:
134
- Use single precision float type for float. (default: False)
135
-
136
- :param bool use_bin_type:
137
- Use bin type introduced in tmsgpack spec 2.0 for bytes.
138
- It also enables str8 type for unicode. (default: True)
139
-
140
- :param bool tuple_as_list:
141
- If true, tuples are serialized as lists. (default: True)
142
- Otherwise, tuples are passed to pack_ctrl.from_obj(?).
136
+ :param bool p_shortcuts:
137
+ If true, pack dicts, tuples, lists without calling from_obj(...).
138
+ Object types: {...} => None; (...) => None; [...] => False
139
+ (default: True)
143
140
 
144
- :param bool strict_types:
145
- If set to true, types will be checked to be exact. (default: False)
146
- Derived classes are distinct and passed to pack_ctrl.from_obj(?).
147
- Dicts, lists and tuples are not affected by strict_types.
141
+ :param bool sort_keys:
142
+ Sort output dictionaries by key. (default: False)
148
143
 
149
- :param str unicode_errors:
150
- The error handler for encoding unicode. (default: 'strict')
151
- DO NOT USE THIS!! This option is kept for very specific usage.
144
+ :param bool p_str_keys:
145
+ If true, accept only strings as dict keys. (default: False)
152
146
 
153
- :param bool sort_keys:
154
- Sort output dictionaries by key. (default: False)
147
+ :param bool use_single_float:
148
+ Use single precision float type for float. (default: False)
155
149
  """
156
150
  ```
157
151
  ## UnpackConfig configuration objects for unpack_ctrl
@@ -160,55 +154,43 @@ Config object for pack_ctrl.options
160
154
  from tmsgpack import UnpackConfig
161
155
 
162
156
  config = UnpackConfig(
163
- read_size=16*1024, use_tuple=False, raw=False,
164
- strict_dict_key=False, object_as_pairs=False,
165
- unicode_errors='strict', max_buffer_size=0,
157
+ u_shortcuts=True, u_str_keys=False,
158
+ read_size=16*1024, max_buffer_size=0,
166
159
  max_str_len=-1, max_bin_len=-1, max_list_len=-1, max_dict_len=-1,
167
160
  )
168
161
  """
169
162
  Config object for unpack_ctrl.options
170
163
 
171
- :param int read_size:
172
- Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`)
164
+ :param bool u_shortcuts:
165
+ If true, unpack dicts, tuples, lists without calling from_dict/from_tuple.
166
+ Object types: None => {...}/(...), False => [...]
167
+ (default: True)
173
168
 
174
- :param bool use_tuple:
175
- If true, unpack a tmsgpack list as a Python tuple. (default: False)
169
+ :param bool u_str_keys:
170
+ If true, accept only strings as dict keys. (default: False)
176
171
 
177
- :param bool raw:
178
- If true, unpack tmsgpack strings (raw) to Python bytes.
179
- Otherwise, unpack to Python str by decoding with UTF-8 encoding (default: False).
172
+ :param int read_size:
173
+ Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`)
180
174
 
181
- :param bool strict_dict_key:
182
- If true only str or bytes are accepted for dict (dict) keys. (default: False).
175
+ :param int max_buffer_size:
176
+ (default: 100*1024*1024 (100MiB))
177
+ Limits size of data waiting unpacked. 0 means 2**32-1.
178
+ Raises `BufferFull` exception when it is insufficient.
179
+ You should set this parameter when unpacking data from untrusted source.
183
180
 
184
- :param callable object_as_pairs:
185
- If true, handles dicts as tuples of pairs.
186
- Otherwise, as dicts (default: False).
181
+ :param int max_str_len:
182
+ Limits max length of str. (default: max_buffer_size)
187
183
 
188
- :param str unicode_errors:
189
- The error handler for decoding unicode. (default: 'strict')
190
- This option should be used only when you have tmsgpack data which
191
- contains invalid UTF-8 string.
184
+ :param int max_bin_len:
185
+ Limits max length of bin. (default: max_buffer_size)
192
186
 
193
- :param int max_buffer_size:
194
- Limits size of data waiting unpacked. 0 means 2**32-1.
195
- The default value is 100*1024*1024 (100MiB).
196
- Raises `BufferFull` exception when it is insufficient.
197
- You should set this parameter when unpacking data from untrusted source.
187
+ :param int max_list_len:
188
+ Limits max length of list.
189
+ (default: max_buffer_size)
198
190
 
199
- :param int max_str_len:
200
- Limits max length of str. (default: max_buffer_size)
201
-
202
- :param int max_bin_len:
203
- Limits max length of bin. (default: max_buffer_size)
204
-
205
- :param int max_list_len:
206
- Limits max length of list.
207
- (default: max_buffer_size)
208
-
209
- :param int max_dict_len:
210
- Limits max length of dict.
211
- (default: max_buffer_size//2)
191
+ :param int max_dict_len:
192
+ Limits max length of dict.
193
+ (default: max_buffer_size//2)
212
194
  """
213
195
  ```
214
196
  ## Packing and Unpacking dataclass objects
@@ -248,7 +230,7 @@ class TypedPackCtrl:
248
230
  class TypedUnpackCtrl:
249
231
  constructors: Dict[str, callable]
250
232
  def from_dict(self, ctype, data): return self.constructors[ctype](**data)
251
- def from_list(self, ctype, data): return self.constructors[ctype]( *data)
233
+ def from_tuple(self, ctype, data): return self.constructors[ctype]( *data)
252
234
  options: UnpackConfig
253
235
 
254
236
  def unpack(self, packed):
@@ -287,33 +269,20 @@ class Bar:
287
269
  x: int = 1
288
270
  y: str = 'Y'
289
271
  as_list = True
290
-
291
- @dataclass
292
- class Add:
293
- x: int = 10
294
- y: int = 20
295
-
296
- class Expr:
297
- @staticmethod
298
- def Add(x:int, y:int): return x+y
299
- @staticmethod
300
- def tuple(*args): return args
301
272
  ```
302
273
  Notes:
303
274
  * Class Bar has a class property `as_list=True`. It will be packed compactly as
304
275
  a parameter value list.
305
- * The function (static method) `Expr.Add` has the same name as the class constructor
306
- `Add`. We will soon exploit this...
307
276
 
308
277
  Here is a simple test runner to be used for several tests:
309
278
  ```python
310
279
  def run(input, expected=None):
311
280
  if expected is None: expected = input
312
281
 
313
- constructors = [Foo, Bar, Expr.tuple, Expr.Add]
282
+ constructors = [Foo, Bar]
314
283
 
315
- pack_ctrl = pc(tuple_as_list=False) # We want to distinguish between tuples and lists.
316
- unpack_ctrl = uc(constructors)
284
+ pack_ctrl = pc()
285
+ unpack_ctrl = uc(constructors)
317
286
 
318
287
  packed = pack_ctrl.pack(input)
319
288
  output = unpack_ctrl.unpack(packed)
@@ -321,105 +290,13 @@ def run(input, expected=None):
321
290
  assert output == expected
322
291
  ```
323
292
 
324
- And here are the first tests. The `Foo()` and `Bar()` objects are packed and unpacked
325
- correctly:
293
+ The `Foo()` and `Bar()` objects are packed and unpacked correctly:
326
294
  ```python
327
295
  def test_typed_foobar():
328
- run(Foo()) # Encoded as a typed dict
329
- run(Bar()) # Encoded as a typed list
330
- run((1,2,3)) # Tuples are encoded as a typed list with object_type='tuple'
296
+ run(Foo()) # Encoded as a typed dict
297
+ run(Bar()) # Encoded as a typed list
298
+ run((1,2,3)) # Tuples are encoded as a typed list with object_type=None.
299
+ run([1,2,3]) # Tuples are encoded as a typed list with object_type=False.
300
+ run({'hello':'world'}) # Dicts are encoded as a typed dict with object_type=None.
331
301
  ```
332
302
 
333
- The second test shows that we can encode an object tree into an
334
- binary expression buffer. When unpacking this expression buffer, the expression
335
- is evaluated.
336
- ```python
337
- def test_simple_expression():
338
- run(Add(Add(1,2), Add(2,3)), 8) # Unpacking is expression evaluation.
339
- ```
340
- Variables (parameters) can be implemented using a dictionary inside the `unpack_ctrl`
341
- object.
342
-
343
- ## Development: Environment and testing
344
-
345
- ```
346
- # Clone the repository
347
- cd ~/git/
348
- # git clone https://github.com/Yaakov-Belch/tmsgpack.git # You need permissions for that.
349
- git clone https://github.com/Yaakov-Belch/tmsgpack.git
350
-
351
- # Create a virtual environment in your project directory
352
- cd ~/git/tmsgpack
353
- python -m venv venv
354
-
355
- # Activate the virtual environment
356
- source venv/bin/activate
357
-
358
- # Upgrade pip (recommended)
359
- pip install --upgrade pip
360
-
361
- # Install the required dependencies
362
- pip install -r requirements.txt
363
-
364
- # Now you can run the tests
365
- make test
366
-
367
- # Run one test
368
- pytest -v test/test_typed_objects.py
369
- ```
370
-
371
- ## Build and publish to PyPI
372
- Follow the steps above in "Development": Clone this repository, create and activate
373
- a virtual environment, upgrade pip, install required dependencies; make test.
374
- ```bash
375
- cd ~/git/tmsgpack
376
- source venv/bin/activate
377
-
378
- pip install build twine
379
- python -m build # puts results in dist/
380
-
381
- # Test the new package -- in a fresh test environment:
382
-
383
- # Create a fresh test environment
384
- deactivate
385
- python -m venv venv-test
386
- source venv-test/bin/activate
387
- pip install --upgrade pip
388
- pip install dist/tmsgpack-0.1.0-cp310-cp310-linux_x86_64.whl
389
- ```
390
-
391
- Obsolete:
392
- cd ~/git/tmsgpack
393
- python -m venv venv
394
- source venv/bin/activate
395
- python --version
396
-
397
-
398
- cd ~/git/tmsgpack
399
- python -m venv venv-test
400
- source venv-test/bin/activate
401
- python --version
402
-
403
-
404
- ## The tmsgpack format (version 0.1.0)
405
- The msgpack format defines two types of containers: maps and arrays (dicts and lists).
406
- They are encoded by a `container_header` that identifies the container type and the
407
- number of key-value pairs or array-elements that follow after the `container_header`:
408
- ```
409
- dict_container_header(3) key1 value1 key2 value2 key3 value3
410
- array_container_header(3) element1 element2 element3
411
- ```
412
- The tmsgpack format uses the same rules -- but adds an `object_type` entry right
413
- after every `container_header`:
414
- ```
415
- dict_container_header(3) object_type key1 value1 key2 value2 key3 value3
416
- array_container_header(3) object_type element1 element2 element3
417
- ```
418
-
419
- ## Future extensibility
420
- In msgpack, possible `ExtType` values for the first `data_header` byte declare
421
- this data element as an msgpack extension. The tmsgpack format does not use this
422
- extension mechanism -- and these eight values are available for future extensions.
423
-
424
- The value `0xC1` is never used by the original msgpack specification. It is also
425
- available for future extensions of the tmsgpack format.