ormsgpack 1.6.0__tar.gz → 1.7.0__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.

Potentially problematic release.


This version of ormsgpack might be problematic. Click here for more details.

Files changed (43) hide show
  1. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/CHANGELOG.md +15 -0
  2. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/Cargo.lock +25 -56
  3. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/Cargo.toml +5 -6
  4. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/PKG-INFO +19 -31
  5. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/README.md +16 -27
  6. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/pyproject.toml +4 -3
  7. ormsgpack-1.7.0/src/deserialize/cache.rs +72 -0
  8. ormsgpack-1.7.0/src/deserialize/deserializer.rs +576 -0
  9. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/lib.rs +1 -0
  10. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/dataclass.rs +42 -76
  11. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/datetimelike.rs +1 -1
  12. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/ext.rs +1 -4
  13. ormsgpack-1.7.0/src/serialize/serializer.rs +803 -0
  14. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/typeref.rs +4 -4
  15. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/unicode.rs +11 -55
  16. ormsgpack-1.6.0/src/deserialize/cache.rs +0 -48
  17. ormsgpack-1.6.0/src/deserialize/deserializer.rs +0 -523
  18. ormsgpack-1.6.0/src/serialize/serializer.rs +0 -318
  19. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/LICENSE-APACHE +0 -0
  20. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/LICENSE-MIT +0 -0
  21. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/build.rs +0 -0
  22. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/python/ormsgpack/__init__.py +0 -0
  23. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/python/ormsgpack/__init__.pyi +0 -0
  24. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/python/ormsgpack/py.typed +0 -0
  25. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/deserialize/error.rs +0 -0
  26. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/deserialize/mod.rs +0 -0
  27. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/exc.rs +0 -0
  28. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/ext.rs +0 -0
  29. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/ffi.rs +0 -0
  30. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/opt.rs +0 -0
  31. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/bytes.rs +0 -0
  32. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/datetime.rs +0 -0
  33. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/default.rs +0 -0
  34. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/dict.rs +0 -0
  35. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/int.rs +0 -0
  36. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/list.rs +0 -0
  37. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/mod.rs +0 -0
  38. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/numpy.rs +0 -0
  39. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/str.rs +0 -0
  40. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/tuple.rs +0 -0
  41. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/uuid.rs +0 -0
  42. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/serialize/writer.rs +0 -0
  43. {ormsgpack-1.6.0 → ormsgpack-1.7.0}/src/util.rs +0 -0
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.7.0 29/11/2024
4
+
5
+ ### Fixed
6
+
7
+ - Detect Pydantic 2.10 models [#311](/../../issues/311)
8
+ - Fix serialization of dataclasses without `__slots__` and with a field defined
9
+ with a descriptor object as default value, a field defined with `init=False`
10
+ and a default value, or a cached property
11
+
12
+ ### Changed
13
+
14
+ - Drop support for Python 3.8
15
+ - Support `OPT_SORT_KEYS` also for Pydantic models [#312](/../../issues/312)
16
+ - Improve deserialization performance
17
+
3
18
  ## 1.6.0 18/10/2024
4
19
 
5
20
  ### Fixed
@@ -14,21 +14,6 @@ dependencies = [
14
14
  "zerocopy",
15
15
  ]
16
16
 
17
- [[package]]
18
- name = "any_all_workaround"
19
- version = "0.1.0"
20
- source = "registry+https://github.com/rust-lang/crates.io-index"
21
- checksum = "88fea40735f2cc320a5133ce772d39c571bd6c9b0d4c1a326926eecdd5af2e86"
22
- dependencies = [
23
- "cfg-if",
24
- ]
25
-
26
- [[package]]
27
- name = "associative-cache"
28
- version = "2.0.0"
29
- source = "registry+https://github.com/rust-lang/crates.io-index"
30
- checksum = "b993cd767a2bc7307dd87622311ca22c44329cc7a21366206bfa0896827b2bad"
31
-
32
17
  [[package]]
33
18
  name = "autocfg"
34
19
  version = "1.3.0"
@@ -68,16 +53,6 @@ version = "0.2.2"
68
53
  source = "registry+https://github.com/rust-lang/crates.io-index"
69
54
  checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
70
55
 
71
- [[package]]
72
- name = "encoding_rs"
73
- version = "0.8.34"
74
- source = "registry+https://github.com/rust-lang/crates.io-index"
75
- checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
76
- dependencies = [
77
- "any_all_workaround",
78
- "cfg-if",
79
- ]
80
-
81
56
  [[package]]
82
57
  name = "half"
83
58
  version = "2.4.1"
@@ -90,9 +65,9 @@ dependencies = [
90
65
 
91
66
  [[package]]
92
67
  name = "itoa"
93
- version = "1.0.11"
68
+ version = "1.0.13"
94
69
  source = "registry+https://github.com/rust-lang/crates.io-index"
95
- checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
70
+ checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2"
96
71
 
97
72
  [[package]]
98
73
  name = "libc"
@@ -126,22 +101,21 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
126
101
 
127
102
  [[package]]
128
103
  name = "ormsgpack"
129
- version = "1.6.0"
104
+ version = "1.7.0"
130
105
  dependencies = [
131
106
  "ahash",
132
- "associative-cache",
133
107
  "bytecount",
108
+ "byteorder",
134
109
  "chrono",
135
- "encoding_rs",
136
110
  "half",
137
111
  "itoa",
138
112
  "once_cell",
139
113
  "pyo3",
140
114
  "pyo3-build-config",
141
115
  "rmp",
142
- "rmp-serde",
143
116
  "serde",
144
117
  "serde_bytes",
118
+ "simdutf8",
145
119
  "smallvec",
146
120
  ]
147
121
 
@@ -159,18 +133,18 @@ checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
159
133
 
160
134
  [[package]]
161
135
  name = "proc-macro2"
162
- version = "1.0.82"
136
+ version = "1.0.89"
163
137
  source = "registry+https://github.com/rust-lang/crates.io-index"
164
- checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
138
+ checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
165
139
  dependencies = [
166
140
  "unicode-ident",
167
141
  ]
168
142
 
169
143
  [[package]]
170
144
  name = "pyo3"
171
- version = "0.22.5"
145
+ version = "0.22.6"
172
146
  source = "registry+https://github.com/rust-lang/crates.io-index"
173
- checksum = "3d922163ba1f79c04bc49073ba7b32fd5a8d3b76a87c955921234b8e77333c51"
147
+ checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
174
148
  dependencies = [
175
149
  "cfg-if",
176
150
  "libc",
@@ -183,9 +157,9 @@ dependencies = [
183
157
 
184
158
  [[package]]
185
159
  name = "pyo3-build-config"
186
- version = "0.22.5"
160
+ version = "0.22.6"
187
161
  source = "registry+https://github.com/rust-lang/crates.io-index"
188
- checksum = "bc38c5feeb496c8321091edf3d63e9a6829eab4b863b4a6a65f26f3e9cc6b179"
162
+ checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
189
163
  dependencies = [
190
164
  "once_cell",
191
165
  "target-lexicon",
@@ -193,9 +167,9 @@ dependencies = [
193
167
 
194
168
  [[package]]
195
169
  name = "pyo3-ffi"
196
- version = "0.22.5"
170
+ version = "0.22.6"
197
171
  source = "registry+https://github.com/rust-lang/crates.io-index"
198
- checksum = "94845622d88ae274d2729fcefc850e63d7a3ddff5e3ce11bd88486db9f1d357d"
172
+ checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
199
173
  dependencies = [
200
174
  "libc",
201
175
  "pyo3-build-config",
@@ -221,22 +195,11 @@ dependencies = [
221
195
  "paste",
222
196
  ]
223
197
 
224
- [[package]]
225
- name = "rmp-serde"
226
- version = "1.3.0"
227
- source = "registry+https://github.com/rust-lang/crates.io-index"
228
- checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
229
- dependencies = [
230
- "byteorder",
231
- "rmp",
232
- "serde",
233
- ]
234
-
235
198
  [[package]]
236
199
  name = "serde"
237
- version = "1.0.210"
200
+ version = "1.0.215"
238
201
  source = "registry+https://github.com/rust-lang/crates.io-index"
239
- checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
202
+ checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
240
203
  dependencies = [
241
204
  "serde_derive",
242
205
  ]
@@ -252,15 +215,21 @@ dependencies = [
252
215
 
253
216
  [[package]]
254
217
  name = "serde_derive"
255
- version = "1.0.210"
218
+ version = "1.0.215"
256
219
  source = "registry+https://github.com/rust-lang/crates.io-index"
257
- checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
220
+ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
258
221
  dependencies = [
259
222
  "proc-macro2",
260
223
  "quote",
261
224
  "syn",
262
225
  ]
263
226
 
227
+ [[package]]
228
+ name = "simdutf8"
229
+ version = "0.1.5"
230
+ source = "registry+https://github.com/rust-lang/crates.io-index"
231
+ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
232
+
264
233
  [[package]]
265
234
  name = "smallvec"
266
235
  version = "1.13.2"
@@ -269,9 +238,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
269
238
 
270
239
  [[package]]
271
240
  name = "syn"
272
- version = "2.0.62"
241
+ version = "2.0.82"
273
242
  source = "registry+https://github.com/rust-lang/crates.io-index"
274
- checksum = "9f660c3bfcefb88c538776b6685a0c472e3128b51e74d48793dc2a488196e8eb"
243
+ checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021"
275
244
  dependencies = [
276
245
  "proc-macro2",
277
246
  "quote",
@@ -1,12 +1,13 @@
1
1
  [package]
2
2
  name = "ormsgpack"
3
- version = "1.6.0"
3
+ version = "1.7.0"
4
4
  authors = [
5
5
  "Aviram Hassan <aviramyhassan@gmail.com>",
6
6
  "Emanuele Giaquinta <emanuele.giaquinta@gmail.com>",
7
7
  ]
8
8
  description = "Fast, correct Python msgpack library supporting dataclasses, datetimes, and numpy"
9
9
  edition = "2021"
10
+ rust-version = "1.70"
10
11
  license = "Apache-2.0 OR MIT"
11
12
  repository = "https://github.com/aviramha/ormsgpack"
12
13
  homepage = "https://github.com/aviramha/ormsgpack"
@@ -33,23 +34,21 @@ default = ["unstable-simd"]
33
34
  # Use SIMD intrinsics. This requires Rust on the nightly channel.
34
35
  unstable-simd = [
35
36
  "bytecount/generic-simd",
36
- "encoding_rs/simd-accel",
37
37
  ]
38
38
 
39
39
  [dependencies]
40
40
  ahash = { version = "0.8", default-features = false }
41
- associative-cache = { version = "2", default-features = false }
42
41
  bytecount = { version = "^0.6.7", default-features = false, features = ["runtime-dispatch-simd"] }
42
+ byteorder = { version = "1.5.0", default-features = false, features = ["std"] }
43
43
  chrono = { version = "0.4.38", default-features = false }
44
- encoding_rs = { version = "0.8", default-features = false }
45
44
  half = { version = "2.4.1", default-features = false }
46
45
  itoa = { version = "1", default-features = false }
47
46
  once_cell = { version = "1", default-features = false, features = ["race"] }
48
- pyo3 = { version = "^0.22.5", default-features = false, features = ["extension-module"] }
47
+ pyo3 = { version = "^0.22.6", default-features = false, features = ["extension-module"] }
49
48
  rmp = { version = "^0.8.14", default-features = false, features = ["std"] }
50
- rmp-serde = { version = "1", default-features = false }
51
49
  serde = { version = "1", default-features = false }
52
50
  serde_bytes = { version = "0.11.15", default-features = false, features = ["std"] }
51
+ simdutf8 = { version = "0.1.5", default-features = false, features = ["std"] }
53
52
  smallvec = { version = "^1.13", default-features = false, features = ["union", "write"] }
54
53
 
55
54
  [build-dependencies]
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: ormsgpack
3
- Version: 1.6.0
3
+ Version: 1.7.0
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: Apache Software License
@@ -9,7 +9,6 @@ Classifier: Operating System :: MacOS
9
9
  Classifier: Operating System :: Microsoft :: Windows
10
10
  Classifier: Operating System :: POSIX :: Linux
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.8
13
12
  Classifier: Programming Language :: Python :: 3.9
14
13
  Classifier: Programming Language :: Python :: 3.10
15
14
  Classifier: Programming Language :: Python :: 3.11
@@ -27,7 +26,7 @@ Home-Page: https://github.com/aviramha/ormsgpack
27
26
  Author: Aviram Hassan <aviramyhassan@gmail.com>, Emanuele Giaquinta <emanuele.giaquinta@gmail.com>
28
27
  Author-email: Aviram Hassan <aviramyhassan@gmail.com>, Emanuele Giaquinta <emanuele.giaquinta@gmail.com>
29
28
  License: Apache-2.0 OR MIT
30
- Requires-Python: >=3.8
29
+ Requires-Python: >=3.9
31
30
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
32
31
  Project-URL: Source Code, https://github.com/aviramha/ormsgpack
33
32
 
@@ -35,28 +34,13 @@ Project-URL: Source Code, https://github.com/aviramha/ormsgpack
35
34
  ![PyPI](https://img.shields.io/pypi/v/ormsgpack)
36
35
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/ormsgpack)
37
36
 
38
- ormsgpack is a fast msgpack library for Python. It is a fork/reboot of [orjson](https://github.com/ijl/orjson)
39
- It serializes faster than [msgpack-python](https://github.com/msgpack/msgpack-python) and deserializes a bit slower (right now).
40
- It supports serialization of:
41
- [dataclass](#dataclass),
42
- [datetime](#datetime),
43
- [numpy](#numpy),
44
- [pydantic](#pydantic) and
45
- [UUID](#uuid) instances natively.
46
-
47
- Its features and drawbacks compared to other Python msgpack libraries:
48
-
49
- * serializes `dataclass` instances natively.
50
- * serializes `datetime`, `date`, and `time` instances to RFC 3339 format,
51
- e.g., "1970-01-01T00:00:00+00:00"
52
- * serializes `numpy.ndarray` instances natively and faster.
53
- * serializes `pydantic.BaseModel` instances natively
54
- * serializes arbitrary types using a `default` hook
55
-
56
- ormsgpack supports CPython 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13.
57
- ormsgpack does not support PyPy. Releases follow semantic
58
- versioning and serializing a new object type without an opt-in flag is
59
- considered a breaking change.
37
+ ormsgpack is a fast msgpack serialization library for Python derived
38
+ from [orjson](https://github.com/ijl/orjson), with native support for
39
+ various Python types.
40
+
41
+ ormsgpack supports CPython 3.9, 3.10, 3.11, 3.12 and 3.13. Releases
42
+ follow semantic versioning and serializing a new object type without
43
+ an opt-in flag is considered a breaking change.
60
44
 
61
45
  ormsgpack is licensed under both the Apache 2.0 and MIT licenses. The
62
46
  repository and issue tracker is
@@ -139,7 +123,7 @@ serializes subclasses of `str`, `int`, `dict`, `list`,
139
123
  of `tuple` to avoid serializing `namedtuple` objects as arrays. To avoid
140
124
  serializing subclasses, specify the option `ormsgpack.OPT_PASSTHROUGH_SUBCLASS`.
141
125
 
142
- The output is a `bytes` object containing UTF-8.
126
+ The output is a `bytes` object.
143
127
 
144
128
  The global interpreter lock (GIL) is held for the duration of the call.
145
129
 
@@ -443,8 +427,8 @@ Serialize `pydantic.BaseModel` instances.
443
427
 
444
428
  ##### OPT_SORT_KEYS
445
429
 
446
- Serialize `dict` keys in sorted order. The default is to serialize in an
447
- unspecified order.
430
+ Serialize `dict` keys and pydantic model fields in sorted order. The default
431
+ is to serialize in an unspecified order.
448
432
 
449
433
  This can be used to ensure the order is deterministic for hashing or tests.
450
434
  It has a substantial performance penalty and is not recommended in general.
@@ -797,7 +781,11 @@ b'\xd9$886313e1-3b8a-5372-9b90-0c9aee199e5d'
797
781
  ```
798
782
 
799
783
  ### Pydantic
800
- ormsgpack serializes `pydantic.BaseModel` instances natively.
784
+ ormsgpack serializes `pydantic.BaseModel` instances natively, with
785
+ [duck-typing](https://docs.pydantic.dev/2.10/concepts/serialization/#serializing-with-duck-typing).
786
+ This is equivalent to serializing
787
+ `model.model_dump(serialize_as_any=True)` with Pydantic V2 or
788
+ `model.dict()`with Pydantic V1.
801
789
 
802
790
  #### Performance
803
791
  ![alt text](doc/pydantic.svg "pydantic")
@@ -906,7 +894,7 @@ level above this.
906
894
 
907
895
  ## Packaging
908
896
 
909
- To package ormsgpack requires [Rust](https://www.rust-lang.org/) 1.65
897
+ To package ormsgpack requires [Rust](https://www.rust-lang.org/) 1.70
910
898
  or newer and the [maturin](https://github.com/PyO3/maturin) build
911
899
  tool. The default feature `unstable-simd` enables the usage of SIMD
912
900
  operations and requires nightly Rust. The recommended build command
@@ -2,28 +2,13 @@
2
2
  ![PyPI](https://img.shields.io/pypi/v/ormsgpack)
3
3
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/ormsgpack)
4
4
 
5
- ormsgpack is a fast msgpack library for Python. It is a fork/reboot of [orjson](https://github.com/ijl/orjson)
6
- It serializes faster than [msgpack-python](https://github.com/msgpack/msgpack-python) and deserializes a bit slower (right now).
7
- It supports serialization of:
8
- [dataclass](#dataclass),
9
- [datetime](#datetime),
10
- [numpy](#numpy),
11
- [pydantic](#pydantic) and
12
- [UUID](#uuid) instances natively.
13
-
14
- Its features and drawbacks compared to other Python msgpack libraries:
15
-
16
- * serializes `dataclass` instances natively.
17
- * serializes `datetime`, `date`, and `time` instances to RFC 3339 format,
18
- e.g., "1970-01-01T00:00:00+00:00"
19
- * serializes `numpy.ndarray` instances natively and faster.
20
- * serializes `pydantic.BaseModel` instances natively
21
- * serializes arbitrary types using a `default` hook
22
-
23
- ormsgpack supports CPython 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13.
24
- ormsgpack does not support PyPy. Releases follow semantic
25
- versioning and serializing a new object type without an opt-in flag is
26
- considered a breaking change.
5
+ ormsgpack is a fast msgpack serialization library for Python derived
6
+ from [orjson](https://github.com/ijl/orjson), with native support for
7
+ various Python types.
8
+
9
+ ormsgpack supports CPython 3.9, 3.10, 3.11, 3.12 and 3.13. Releases
10
+ follow semantic versioning and serializing a new object type without
11
+ an opt-in flag is considered a breaking change.
27
12
 
28
13
  ormsgpack is licensed under both the Apache 2.0 and MIT licenses. The
29
14
  repository and issue tracker is
@@ -106,7 +91,7 @@ serializes subclasses of `str`, `int`, `dict`, `list`,
106
91
  of `tuple` to avoid serializing `namedtuple` objects as arrays. To avoid
107
92
  serializing subclasses, specify the option `ormsgpack.OPT_PASSTHROUGH_SUBCLASS`.
108
93
 
109
- The output is a `bytes` object containing UTF-8.
94
+ The output is a `bytes` object.
110
95
 
111
96
  The global interpreter lock (GIL) is held for the duration of the call.
112
97
 
@@ -410,8 +395,8 @@ Serialize `pydantic.BaseModel` instances.
410
395
 
411
396
  ##### OPT_SORT_KEYS
412
397
 
413
- Serialize `dict` keys in sorted order. The default is to serialize in an
414
- unspecified order.
398
+ Serialize `dict` keys and pydantic model fields in sorted order. The default
399
+ is to serialize in an unspecified order.
415
400
 
416
401
  This can be used to ensure the order is deterministic for hashing or tests.
417
402
  It has a substantial performance penalty and is not recommended in general.
@@ -764,7 +749,11 @@ b'\xd9$886313e1-3b8a-5372-9b90-0c9aee199e5d'
764
749
  ```
765
750
 
766
751
  ### Pydantic
767
- ormsgpack serializes `pydantic.BaseModel` instances natively.
752
+ ormsgpack serializes `pydantic.BaseModel` instances natively, with
753
+ [duck-typing](https://docs.pydantic.dev/2.10/concepts/serialization/#serializing-with-duck-typing).
754
+ This is equivalent to serializing
755
+ `model.model_dump(serialize_as_any=True)` with Pydantic V2 or
756
+ `model.dict()`with Pydantic V1.
768
757
 
769
758
  #### Performance
770
759
  ![alt text](doc/pydantic.svg "pydantic")
@@ -873,7 +862,7 @@ level above this.
873
862
 
874
863
  ## Packaging
875
864
 
876
- To package ormsgpack requires [Rust](https://www.rust-lang.org/) 1.65
865
+ To package ormsgpack requires [Rust](https://www.rust-lang.org/) 1.70
877
866
  or newer and the [maturin](https://github.com/PyO3/maturin) build
878
867
  tool. The default feature `unstable-simd` enables the usage of SIMD
879
868
  operations and requires nightly Rust. The recommended build command
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "ormsgpack"
3
3
  repository = "https://github.com/aviramha/ormsgpack"
4
- requires-python = ">=3.8"
4
+ requires-python = ">=3.9"
5
5
  classifiers = [
6
6
  "Development Status :: 5 - Production/Stable",
7
7
  "Intended Audience :: Developers",
@@ -11,7 +11,6 @@ classifiers = [
11
11
  "Operating System :: Microsoft :: Windows",
12
12
  "Operating System :: POSIX :: Linux",
13
13
  "Programming Language :: Python :: 3",
14
- "Programming Language :: Python :: 3.8",
15
14
  "Programming Language :: Python :: 3.9",
16
15
  "Programming Language :: Python :: 3.10",
17
16
  "Programming Language :: Python :: 3.11",
@@ -41,7 +40,7 @@ ignore_missing_imports = true
41
40
 
42
41
  [tool.ruff]
43
42
  line-length = 88
44
- target-version = "py38"
43
+ target-version = "py39"
45
44
 
46
45
  [tool.ruff.lint]
47
46
  select = [
@@ -52,6 +51,8 @@ select = [
52
51
  ]
53
52
  ignore = [
54
53
  "E501",
54
+ "RUF022",
55
+ "RUF023",
55
56
  ]
56
57
 
57
58
  [tool.ruff.lint.isort]
@@ -0,0 +1,72 @@
1
+ // SPDX-License-Identifier: (Apache-2.0 OR MIT)
2
+
3
+ use crate::typeref::*;
4
+ use crate::unicode::*;
5
+ use once_cell::unsync::OnceCell;
6
+ use simdutf8::basic::{from_utf8, Utf8Error};
7
+ use std::hash::BuildHasher;
8
+ use std::hash::Hasher;
9
+ use std::ptr::NonNull;
10
+
11
+ #[repr(transparent)]
12
+ struct CachedKey {
13
+ ptr: *mut pyo3::ffi::PyObject,
14
+ }
15
+
16
+ unsafe impl Send for CachedKey {}
17
+ unsafe impl Sync for CachedKey {}
18
+
19
+ impl CachedKey {
20
+ fn new(ptr: *mut pyo3::ffi::PyObject) -> CachedKey {
21
+ CachedKey { ptr: ptr }
22
+ }
23
+
24
+ fn get(&mut self) -> *mut pyo3::ffi::PyObject {
25
+ ffi!(Py_INCREF(self.ptr));
26
+ self.ptr
27
+ }
28
+ }
29
+
30
+ impl Drop for CachedKey {
31
+ fn drop(&mut self) {
32
+ ffi!(Py_DECREF(self.ptr));
33
+ }
34
+ }
35
+
36
+ pub struct KeyMap<const C: usize> {
37
+ entries: Vec<Option<CachedKey>>,
38
+ }
39
+
40
+ impl<const C: usize> KeyMap<C> {
41
+ pub fn new() -> Self {
42
+ let mut entries = Vec::with_capacity(C);
43
+ for _ in 0..C {
44
+ entries.push(None);
45
+ }
46
+ KeyMap { entries: entries }
47
+ }
48
+
49
+ pub fn get(&mut self, key: &[u8]) -> Result<NonNull<pyo3::ffi::PyObject>, Utf8Error> {
50
+ let mut hasher = unsafe { HASH_BUILDER.get().unwrap().build_hasher() };
51
+ let hash = {
52
+ hasher.write(key);
53
+ hasher.finish()
54
+ } as usize;
55
+ let index = hash % C;
56
+ let entry = match &mut self.entries[index] {
57
+ Some(v) if unicode_to_str(v.ptr).unwrap().as_bytes() == key => v,
58
+ _ => {
59
+ let pykey = unicode_from_str(from_utf8(key)?);
60
+ hash_str(pykey);
61
+ self.entries[index] = Some(CachedKey::new(pykey));
62
+ match &mut self.entries[index] {
63
+ Some(v) => v,
64
+ _ => unreachable!(),
65
+ }
66
+ }
67
+ };
68
+ Ok(nonnull!(entry.get()))
69
+ }
70
+ }
71
+
72
+ pub static mut KEY_MAP: OnceCell<KeyMap<512>> = OnceCell::new();