uuid-utils 0.9.0__tar.gz → 0.10.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 uuid-utils might be problematic. Click here for more details.

Files changed (28) hide show
  1. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/.github/workflows/ci.yml +50 -49
  2. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/Cargo.lock +13 -13
  3. uuid_utils-0.10.0/Cargo.toml +14 -0
  4. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/PKG-INFO +15 -13
  5. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/README.md +12 -10
  6. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/docs/index.md +12 -10
  7. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/pyproject.toml +2 -2
  8. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/python/uuid_utils/__init__.py +3 -0
  9. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/python/uuid_utils/__init__.pyi +47 -37
  10. uuid_utils-0.10.0/requirements.txt +5 -0
  11. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/src/lib.rs +28 -4
  12. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/tests/test_uuid.py +6 -1
  13. uuid_utils-0.9.0/Cargo.toml +0 -14
  14. uuid_utils-0.9.0/requirements.txt +0 -5
  15. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/.gitignore +0 -0
  16. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/LICENSE.md +0 -0
  17. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/Makefile +0 -0
  18. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/benchmarks/README.md +0 -0
  19. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/benchmarks/bench_generator.py +0 -0
  20. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/benchmarks/bench_parser.py +0 -0
  21. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/docs/api.md +0 -0
  22. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/mkdocs.yml +0 -0
  23. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/python/uuid_utils/compat/__init__.py +0 -0
  24. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/python/uuid_utils/compat/__init__.pyi +0 -0
  25. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/python/uuid_utils/py.typed +0 -0
  26. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/tests/__init__.py +0 -0
  27. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/tests/test_compat/__init__.py +0 -0
  28. {uuid_utils-0.9.0 → uuid_utils-0.10.0}/tests/test_compat/test_compat.py +0 -0
@@ -16,10 +16,10 @@ jobs:
16
16
  name: Check code quality
17
17
  runs-on: ubuntu-latest
18
18
  steps:
19
- - uses: actions/checkout@v3
20
- - uses: actions/setup-python@v4
19
+ - uses: actions/checkout@v4
20
+ - uses: actions/setup-python@v5
21
21
  with:
22
- python-version: "3.10"
22
+ python-version: "3.12"
23
23
  - name: Install dependencies
24
24
  run: pip install -r requirements.txt
25
25
  - name: Check code
@@ -33,17 +33,17 @@ jobs:
33
33
  strategy:
34
34
  matrix:
35
35
  target: [x86_64, i686]
36
- python-version: ["3.10", "3.11", "3.12"]
36
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
37
37
  steps:
38
- - uses: actions/checkout@v3
39
- - uses: actions/setup-python@v4
38
+ - uses: actions/checkout@v4
39
+ - uses: actions/setup-python@v5
40
40
  with:
41
41
  python-version: "${{ matrix.python-version }}"
42
42
  - name: Build wheels
43
43
  uses: PyO3/maturin-action@v1
44
44
  with:
45
45
  target: ${{ matrix.target }}
46
- args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9
46
+ args: --release --out dist -i 3.9 3.10 3.11 3.12 3.13 pypy3.9 pypy3.10
47
47
  sccache: "true"
48
48
  manylinux: auto
49
49
  - name: Install and test
@@ -53,9 +53,9 @@ jobs:
53
53
  pip install pytest
54
54
  pytest -v .
55
55
  - name: Upload wheels
56
- uses: actions/upload-artifact@v3
56
+ uses: actions/upload-artifact@v4
57
57
  with:
58
- name: wheels
58
+ name: wheels-linux-${{ strategy.job-index }}
59
59
  path: dist
60
60
 
61
61
  linux-cross:
@@ -65,23 +65,23 @@ jobs:
65
65
  matrix:
66
66
  target: [aarch64, armv7, ppc64le]
67
67
  steps:
68
- - uses: actions/checkout@v3
69
- - uses: actions/setup-python@v4
68
+ - uses: actions/checkout@v4
69
+ - uses: actions/setup-python@v5
70
70
  with:
71
- python-version: "3.11"
71
+ python-version: "3.12"
72
72
  - name: Build wheels
73
73
  uses: PyO3/maturin-action@v1
74
74
  with:
75
75
  rust-toolchain: stable
76
76
  target: ${{ matrix.target }}
77
77
  manylinux: auto
78
- args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9
79
- - uses: uraimo/run-on-arch-action@v2.7.2
78
+ args: --release --out dist -i 3.9 3.10 3.11 3.12 3.13 pypy3.9 pypy3.10
79
+ - uses: uraimo/run-on-arch-action@v2.8.1
80
80
  if: matrix.target != 'ppc64'
81
81
  name: Install built wheel
82
82
  with:
83
83
  arch: ${{ matrix.target }}
84
- distro: ubuntu20.04
84
+ distro: ubuntu22.04
85
85
  githubToken: ${{ github.token }}
86
86
  install: |
87
87
  apt-get update
@@ -91,9 +91,9 @@ jobs:
91
91
  pip3 install uuid_utils --no-index --find-links dist/ --force-reinstall
92
92
  pytest -v .
93
93
  - name: Upload wheels
94
- uses: actions/upload-artifact@v3
94
+ uses: actions/upload-artifact@v4
95
95
  with:
96
- name: wheels
96
+ name: wheels-linux-cross-${{ strategy.job-index }}
97
97
  path: dist
98
98
 
99
99
  musllinux:
@@ -105,10 +105,10 @@ jobs:
105
105
  - x86_64-unknown-linux-musl
106
106
  - i686-unknown-linux-musl
107
107
  steps:
108
- - uses: actions/checkout@v3
109
- - uses: actions/setup-python@v4
108
+ - uses: actions/checkout@v4
109
+ - uses: actions/setup-python@v5
110
110
  with:
111
- python-version: "3.11"
111
+ python-version: "3.12"
112
112
  architecture: x64
113
113
  - name: Build wheels
114
114
  uses: PyO3/maturin-action@v1
@@ -116,7 +116,7 @@ jobs:
116
116
  rust-toolchain: stable
117
117
  target: ${{ matrix.target }}
118
118
  manylinux: musllinux_1_2
119
- args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12
119
+ args: --release --out dist -i 3.9 3.10 3.11 3.12 3.13
120
120
  - name: Install built wheel
121
121
  if: matrix.target == 'x86_64-unknown-linux-musl'
122
122
  uses: addnab/docker-run-action@v3
@@ -129,9 +129,9 @@ jobs:
129
129
  pip3 install uuid_utils --no-index --find-links /io/dist/ --force-reinstall --break-system-packages
130
130
  python3 -c "import uuid_utils"
131
131
  - name: Upload wheels
132
- uses: actions/upload-artifact@v3
132
+ uses: actions/upload-artifact@v4
133
133
  with:
134
- name: wheels
134
+ name: wheels-musllinux-${{ strategy.job-index }}
135
135
  path: dist
136
136
 
137
137
  musllinux-cross:
@@ -143,21 +143,21 @@ jobs:
143
143
  - target: aarch64-unknown-linux-musl
144
144
  arch: aarch64
145
145
  steps:
146
- - uses: actions/checkout@v3
147
- - uses: actions/setup-python@v4
146
+ - uses: actions/checkout@v4
147
+ - uses: actions/setup-python@v5
148
148
  with:
149
- python-version: "3.11"
149
+ python-version: "3.12"
150
150
  - name: Build wheels
151
151
  uses: PyO3/maturin-action@v1
152
152
  with:
153
153
  rust-toolchain: stable
154
154
  target: ${{ matrix.platform.target }}
155
155
  manylinux: musllinux_1_2
156
- args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12
156
+ args: --release --out dist -i 3.9 3.10 3.11 3.12 3.13
157
157
  - name: Upload wheels
158
- uses: actions/upload-artifact@v3
158
+ uses: actions/upload-artifact@v4
159
159
  with:
160
- name: wheels
160
+ name: wheels-musllinux-cross-${{ strategy.job-index }}
161
161
  path: dist
162
162
 
163
163
  windows:
@@ -167,14 +167,14 @@ jobs:
167
167
  matrix:
168
168
  platform:
169
169
  - target: x64
170
- interpreter: 3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9
170
+ interpreter: 3.9 3.10 3.11 3.12 3.13 pypy3.9 pypy3.10
171
171
  - target: x86
172
- interpreter: 3.8 3.9 3.10 3.11
172
+ interpreter: 3.9 3.10 3.11 3.12
173
173
  steps:
174
- - uses: actions/checkout@v3
175
- - uses: actions/setup-python@v4
174
+ - uses: actions/checkout@v4
175
+ - uses: actions/setup-python@v5
176
176
  with:
177
- python-version: "3.11"
177
+ python-version: "3.12"
178
178
  architecture: ${{ matrix.platform.target }}
179
179
  - uses: dtolnay/rust-toolchain@stable
180
180
  - name: Build wheels
@@ -189,56 +189,56 @@ jobs:
189
189
  pip install pytest
190
190
  pytest -v .
191
191
  - name: Upload wheels
192
- uses: actions/upload-artifact@v3
192
+ uses: actions/upload-artifact@v4
193
193
  with:
194
- name: wheels
194
+ name: wheels-windows-${{ strategy.job-index }}
195
195
  path: dist
196
196
 
197
197
  macos:
198
198
  name: "MacOS"
199
199
  runs-on: macos-latest
200
200
  steps:
201
- - uses: actions/checkout@v3
202
- - uses: actions/setup-python@v4
201
+ - uses: actions/checkout@v4
202
+ - uses: actions/setup-python@v5
203
203
  with:
204
- python-version: "3.11"
204
+ python-version: "3.12"
205
205
  - uses: dtolnay/rust-toolchain@stable
206
206
  - name: Build wheels - x86_64
207
207
  uses: PyO3/maturin-action@v1
208
208
  with:
209
209
  target: x86_64
210
- args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9
210
+ args: --release --out dist -i 3.9 3.10 3.11 3.12 3.13 pypy3.9 pypy3.10
211
211
  sccache: "true"
212
212
  - name: Build wheels - universal2
213
213
  uses: PyO3/maturin-action@v1
214
214
  with:
215
215
  target: universal2-apple-darwin
216
- args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9
216
+ args: --release --out dist -i 3.9 3.10 3.11 3.12 3.13 pypy3.9 pypy3.10
217
217
  - name: Install and test uuid_utils
218
218
  run: |
219
219
  pip install uuid_utils --no-index --find-links dist --force-reinstall
220
220
  pip install pytest
221
221
  pytest -v .
222
222
  - name: Upload wheels
223
- uses: actions/upload-artifact@v3
223
+ uses: actions/upload-artifact@v4
224
224
  with:
225
- name: wheels
225
+ name: wheels-macos
226
226
  path: dist
227
227
 
228
228
  sdist:
229
229
  name: Source Distribution
230
230
  runs-on: ubuntu-latest
231
231
  steps:
232
- - uses: actions/checkout@v3
232
+ - uses: actions/checkout@v4
233
233
  - name: Build sdist
234
234
  uses: PyO3/maturin-action@v1
235
235
  with:
236
236
  command: sdist
237
237
  args: --out dist
238
238
  - name: Upload sdist
239
- uses: actions/upload-artifact@v3
239
+ uses: actions/upload-artifact@v4
240
240
  with:
241
- name: wheels
241
+ name: wheels-sdist
242
242
  path: dist
243
243
 
244
244
  release:
@@ -247,9 +247,10 @@ jobs:
247
247
  if: "startsWith(github.ref, 'refs/tags/')"
248
248
  needs: [lint, linux, linux-cross, musllinux, musllinux-cross, windows, macos, sdist]
249
249
  steps:
250
- - uses: actions/download-artifact@v3
250
+ - uses: actions/download-artifact@v4.1.8
251
251
  with:
252
- name: wheels
252
+ pattern: wheels-*
253
+ merge-multiple: true
253
254
  - name: Publish to PyPI
254
255
  uses: PyO3/maturin-action@v1
255
256
  env:
@@ -264,7 +265,7 @@ jobs:
264
265
  if: "startsWith(github.ref, 'refs/tags/')"
265
266
  needs: [release]
266
267
  steps:
267
- - uses: actions/checkout@v3
268
+ - uses: actions/checkout@v4
268
269
  - name: Build and publish docs
269
270
  run: |
270
271
  pip install -r requirements.txt
@@ -189,9 +189,9 @@ dependencies = [
189
189
 
190
190
  [[package]]
191
191
  name = "pyo3"
192
- version = "0.22.0"
192
+ version = "0.23.1"
193
193
  source = "registry+https://github.com/rust-lang/crates.io-index"
194
- checksum = "1962a33ed2a201c637fc14a4e0fd4e06e6edfdeee6a5fede0dab55507ad74cf7"
194
+ checksum = "7ebb0c0cc0de9678e53be9ccf8a2ab53045e6e3a8be03393ceccc5e7396ccb40"
195
195
  dependencies = [
196
196
  "cfg-if",
197
197
  "indoc",
@@ -207,9 +207,9 @@ dependencies = [
207
207
 
208
208
  [[package]]
209
209
  name = "pyo3-build-config"
210
- version = "0.22.0"
210
+ version = "0.23.1"
211
211
  source = "registry+https://github.com/rust-lang/crates.io-index"
212
- checksum = "ab7164b2202753bd33afc7f90a10355a719aa973d1f94502c50d06f3488bc420"
212
+ checksum = "80e3ce69c4ec34476534b490e412b871ba03a82e35604c3dfb95fcb6bfb60c09"
213
213
  dependencies = [
214
214
  "once_cell",
215
215
  "python3-dll-a",
@@ -218,9 +218,9 @@ dependencies = [
218
218
 
219
219
  [[package]]
220
220
  name = "pyo3-ffi"
221
- version = "0.22.0"
221
+ version = "0.23.1"
222
222
  source = "registry+https://github.com/rust-lang/crates.io-index"
223
- checksum = "c6424906ca49013c0829c5c1ed405e20e2da2dc78b82d198564880a704e6a7b7"
223
+ checksum = "3b09f311c76b36dfd6dd6f7fa6f9f18e7e46a1c937110d283e80b12ba2468a75"
224
224
  dependencies = [
225
225
  "libc",
226
226
  "pyo3-build-config",
@@ -228,9 +228,9 @@ dependencies = [
228
228
 
229
229
  [[package]]
230
230
  name = "pyo3-macros"
231
- version = "0.22.0"
231
+ version = "0.23.1"
232
232
  source = "registry+https://github.com/rust-lang/crates.io-index"
233
- checksum = "82b2f19e153122d64afd8ce7aaa72f06a00f52e34e1d1e74b6d71baea396460a"
233
+ checksum = "fd4f74086536d1e1deaff99ec0387481fb3325c82e4e48be0e75ab3d3fcb487a"
234
234
  dependencies = [
235
235
  "proc-macro2",
236
236
  "pyo3-macros-backend",
@@ -240,9 +240,9 @@ dependencies = [
240
240
 
241
241
  [[package]]
242
242
  name = "pyo3-macros-backend"
243
- version = "0.22.0"
243
+ version = "0.23.1"
244
244
  source = "registry+https://github.com/rust-lang/crates.io-index"
245
- checksum = "dd698c04cac17cf0fe63d47790ab311b8b25542f5cb976b65c374035c50f1eef"
245
+ checksum = "9e77dfeb76b32bbf069144a5ea0a36176ab59c8db9ce28732d0f06f096bbfbc8"
246
246
  dependencies = [
247
247
  "heck",
248
248
  "proc-macro2",
@@ -342,9 +342,9 @@ checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
342
342
 
343
343
  [[package]]
344
344
  name = "uuid"
345
- version = "1.9.1"
345
+ version = "1.11.0"
346
346
  source = "registry+https://github.com/rust-lang/crates.io-index"
347
- checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
347
+ checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
348
348
  dependencies = [
349
349
  "atomic",
350
350
  "getrandom",
@@ -355,7 +355,7 @@ dependencies = [
355
355
 
356
356
  [[package]]
357
357
  name = "uuid-utils"
358
- version = "0.9.0"
358
+ version = "0.10.0"
359
359
  dependencies = [
360
360
  "mac_address",
361
361
  "pyo3",
@@ -0,0 +1,14 @@
1
+ [package]
2
+ name = "uuid-utils"
3
+ version = "0.10.0"
4
+ edition = "2021"
5
+
6
+ [lib]
7
+ name = "uuid_utils"
8
+ crate-type = ["cdylib"]
9
+
10
+ [dependencies]
11
+ mac_address = "1.1.7"
12
+ pyo3 = { version = "0.23.1", features = ["extension-module", "generate-import-lib", 'abi3-py39'] }
13
+ rand = "0.8.5"
14
+ uuid = { version = "1.11.0", features = ["v1", "v3", "v4", "v5", "v6", "v7", "v8", "fast-rng"]}
@@ -1,15 +1,15 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: uuid_utils
3
- Version: 0.9.0
3
+ Version: 0.10.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Programming Language :: Python
6
6
  Classifier: Programming Language :: Python :: 3
7
7
  Classifier: Programming Language :: Python :: 3 :: Only
8
- Classifier: Programming Language :: Python :: 3.8
9
8
  Classifier: Programming Language :: Python :: 3.9
10
9
  Classifier: Programming Language :: Python :: 3.10
11
10
  Classifier: Programming Language :: Python :: 3.11
12
11
  Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
13
  Classifier: Programming Language :: Rust
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: License :: OSI Approved :: BSD License
@@ -18,7 +18,7 @@ License-File: LICENSE.md
18
18
  Summary: Drop-in replacement for Python UUID in Rust
19
19
  Keywords: rust,uuid
20
20
  Author-email: Amin Alaee <me@aminalaee.dev>
21
- Requires-Python: >=3.8
21
+ Requires-Python: >=3.9
22
22
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
23
23
  Project-URL: Documentation, https://github.com/aminalaee/uuid-utils
24
24
  Project-URL: Issues, https://github.com/aminalaee/uuid-utils/issues
@@ -106,16 +106,18 @@ UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')
106
106
 
107
107
  ## Benchmarks
108
108
 
109
- | Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
110
- | ---------------- | ----- | ----- | ----- | ------------- | ------------- | ------------- |
111
- | UUID v1 | 0.058 | 0.059 | 0.058 | 0.005 (12.0x) | 0.005 (11.9x) | 0.005 (12.0x) |
112
- | UUID v3 | 0.063 | 0.064 | 0.063 | 0.008 (7.9x) | 0.008 (8.1x) | 0.008 (8.0x) |
113
- | UUID v4 | 0.041 | 0.041 | 0.041 | 0.004 (11.1x) | 0.004 (10.8x) | 0.004 (10.9x) |
114
- | UUID v5 | 0.064 | 0.066 | 0.065 | 0.008 (8.1x) | 0.008 (8.1x) | 0.008 (8.1x) |
115
- | UUID from hex | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.6x) |
116
- | UUID from bytes | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.7x) |
117
- | UUID from int | 0.024 | 0.025 | 0.024 | 0.004 (6.6x) | 0.004 (6.7x) | 0.004 (6.6x) |
118
- | UUID from fields | 0.028 | 0.028 | 0.028 | 0.009 (3.1x) | 0.009 (3.1x) | 0.009 (3.1x) |
109
+ | Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
110
+ |------------------|---------|---------|---------|-----------------|-----------------|-----------------|
111
+ | UUID v1 | 0.061 | 0.299 | 0.194 | 0.019 (3.3x) | 0.019 (15.4x) | 0.019 (10.1x) |
112
+ | UUID v3 | 0.267 | 0.307 | 0.293 | 0.035 (7.6x) | 0.041 (7.5x) | 0.039 (7.5x) |
113
+ | UUID v4 | 0.145 | 0.301 | 0.249 | 0.004 (38.5x) | 0.005 (54.8x) | 0.005 (53.0x) |
114
+ | UUID v5 | 0.058 | 0.189 | 0.146 | 0.008 (7.6x) | 0.038 (5.0x) | 0.016 (9.0x) |
115
+ | UUID from hex | 0.128 | 0.139 | 0.135 | 0.016 (8.2x) | 0.017 (8.0x) | 0.016 (8.3x) |
116
+ | UUID from bytes | 0.031 | 0.135 | 0.093 | 0.016 (2.0x) | 0.016 (8.6x) | 0.016 (5.9x) |
117
+ | UUID from int | 0.027 | 0.102 | 0.043 | 0.003 (8.3x) | 0.004 (25.0x) | 0.003 (12.4x) |
118
+ | UUID from fields | 0.031 | 0.162 | 0.077 | 0.005 (6.0x) | 0.005 (30.6x) | 0.005 (14.7x) |
119
+
120
+ <sup>Benchmark results might vary in different environments, but in most cases the uuid_utils should outperform stdlib uuid.</sup><br>
119
121
 
120
122
  ## How to develop locally
121
123
 
@@ -80,16 +80,18 @@ UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')
80
80
 
81
81
  ## Benchmarks
82
82
 
83
- | Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
84
- | ---------------- | ----- | ----- | ----- | ------------- | ------------- | ------------- |
85
- | UUID v1 | 0.058 | 0.059 | 0.058 | 0.005 (12.0x) | 0.005 (11.9x) | 0.005 (12.0x) |
86
- | UUID v3 | 0.063 | 0.064 | 0.063 | 0.008 (7.9x) | 0.008 (8.1x) | 0.008 (8.0x) |
87
- | UUID v4 | 0.041 | 0.041 | 0.041 | 0.004 (11.1x) | 0.004 (10.8x) | 0.004 (10.9x) |
88
- | UUID v5 | 0.064 | 0.066 | 0.065 | 0.008 (8.1x) | 0.008 (8.1x) | 0.008 (8.1x) |
89
- | UUID from hex | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.6x) |
90
- | UUID from bytes | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.7x) |
91
- | UUID from int | 0.024 | 0.025 | 0.024 | 0.004 (6.6x) | 0.004 (6.7x) | 0.004 (6.6x) |
92
- | UUID from fields | 0.028 | 0.028 | 0.028 | 0.009 (3.1x) | 0.009 (3.1x) | 0.009 (3.1x) |
83
+ | Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
84
+ |------------------|---------|---------|---------|-----------------|-----------------|-----------------|
85
+ | UUID v1 | 0.061 | 0.299 | 0.194 | 0.019 (3.3x) | 0.019 (15.4x) | 0.019 (10.1x) |
86
+ | UUID v3 | 0.267 | 0.307 | 0.293 | 0.035 (7.6x) | 0.041 (7.5x) | 0.039 (7.5x) |
87
+ | UUID v4 | 0.145 | 0.301 | 0.249 | 0.004 (38.5x) | 0.005 (54.8x) | 0.005 (53.0x) |
88
+ | UUID v5 | 0.058 | 0.189 | 0.146 | 0.008 (7.6x) | 0.038 (5.0x) | 0.016 (9.0x) |
89
+ | UUID from hex | 0.128 | 0.139 | 0.135 | 0.016 (8.2x) | 0.017 (8.0x) | 0.016 (8.3x) |
90
+ | UUID from bytes | 0.031 | 0.135 | 0.093 | 0.016 (2.0x) | 0.016 (8.6x) | 0.016 (5.9x) |
91
+ | UUID from int | 0.027 | 0.102 | 0.043 | 0.003 (8.3x) | 0.004 (25.0x) | 0.003 (12.4x) |
92
+ | UUID from fields | 0.031 | 0.162 | 0.077 | 0.005 (6.0x) | 0.005 (30.6x) | 0.005 (14.7x) |
93
+
94
+ <sup>Benchmark results might vary in different environments, but in most cases the uuid_utils should outperform stdlib uuid.</sup><br>
93
95
 
94
96
  ## How to develop locally
95
97
 
@@ -80,16 +80,18 @@ UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')
80
80
 
81
81
  ## Benchmarks
82
82
 
83
- | Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
84
- | ---------------- | ----- | ----- | ----- | ------------- | ------------- | ------------- |
85
- | UUID v1 | 0.058 | 0.059 | 0.058 | 0.005 (12.0x) | 0.005 (11.9x) | 0.005 (12.0x) |
86
- | UUID v3 | 0.063 | 0.064 | 0.063 | 0.008 (7.9x) | 0.008 (8.1x) | 0.008 (8.0x) |
87
- | UUID v4 | 0.041 | 0.041 | 0.041 | 0.004 (11.1x) | 0.004 (10.8x) | 0.004 (10.9x) |
88
- | UUID v5 | 0.064 | 0.066 | 0.065 | 0.008 (8.1x) | 0.008 (8.1x) | 0.008 (8.1x) |
89
- | UUID from hex | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.6x) |
90
- | UUID from bytes | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.7x) |
91
- | UUID from int | 0.024 | 0.025 | 0.024 | 0.004 (6.6x) | 0.004 (6.7x) | 0.004 (6.6x) |
92
- | UUID from fields | 0.028 | 0.028 | 0.028 | 0.009 (3.1x) | 0.009 (3.1x) | 0.009 (3.1x) |
83
+ | Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
84
+ |------------------|---------|---------|---------|-----------------|-----------------|-----------------|
85
+ | UUID v1 | 0.061 | 0.299 | 0.194 | 0.019 (3.3x) | 0.019 (15.4x) | 0.019 (10.1x) |
86
+ | UUID v3 | 0.267 | 0.307 | 0.293 | 0.035 (7.6x) | 0.041 (7.5x) | 0.039 (7.5x) |
87
+ | UUID v4 | 0.145 | 0.301 | 0.249 | 0.004 (38.5x) | 0.005 (54.8x) | 0.005 (53.0x) |
88
+ | UUID v5 | 0.058 | 0.189 | 0.146 | 0.008 (7.6x) | 0.038 (5.0x) | 0.016 (9.0x) |
89
+ | UUID from hex | 0.128 | 0.139 | 0.135 | 0.016 (8.2x) | 0.017 (8.0x) | 0.016 (8.3x) |
90
+ | UUID from bytes | 0.031 | 0.135 | 0.093 | 0.016 (2.0x) | 0.016 (8.6x) | 0.016 (5.9x) |
91
+ | UUID from int | 0.027 | 0.102 | 0.043 | 0.003 (8.3x) | 0.004 (25.0x) | 0.003 (12.4x) |
92
+ | UUID from fields | 0.031 | 0.162 | 0.077 | 0.005 (6.0x) | 0.005 (30.6x) | 0.005 (14.7x) |
93
+
94
+ <sup>Benchmark results might vary in different environments, but in most cases the uuid_utils should outperform stdlib uuid.</sup><br>
93
95
 
94
96
  ## How to develop locally
95
97
 
@@ -7,17 +7,17 @@ name = "uuid_utils"
7
7
  description = "Drop-in replacement for Python UUID in Rust"
8
8
  authors = [{ name = "Amin Alaee", email = "me@aminalaee.dev" }]
9
9
  keywords = ["rust", "uuid"]
10
- requires-python = ">=3.8"
10
+ requires-python = ">=3.9"
11
11
  classifiers = [
12
12
  "Development Status :: 3 - Alpha",
13
13
  "Programming Language :: Python",
14
14
  "Programming Language :: Python :: 3",
15
15
  "Programming Language :: Python :: 3 :: Only",
16
- "Programming Language :: Python :: 3.8",
17
16
  "Programming Language :: Python :: 3.9",
18
17
  "Programming Language :: Python :: 3.10",
19
18
  "Programming Language :: Python :: 3.11",
20
19
  "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
21
  "Programming Language :: Rust",
22
22
  "Intended Audience :: Developers",
23
23
  "License :: OSI Approved :: BSD License",
@@ -1,3 +1,5 @@
1
+ from uuid import SafeUUID
2
+
1
3
  from ._uuid_utils import (
2
4
  NAMESPACE_DNS,
3
5
  NAMESPACE_OID,
@@ -29,6 +31,7 @@ __all__ = [
29
31
  "RESERVED_NCS",
30
32
  "RFC_4122",
31
33
  "UUID",
34
+ "SafeUUID",
32
35
  "__version__",
33
36
  "getnode",
34
37
  "uuid1",
@@ -1,21 +1,14 @@
1
+ import builtins
1
2
  import sys
2
- from enum import Enum
3
+ from uuid import SafeUUID
3
4
 
4
- from _typeshed import Unused
5
5
  from typing_extensions import TypeAlias
6
6
 
7
7
  # Because UUID has properties called int and bytes we need to rename these temporarily.
8
- _Int: TypeAlias = int
9
- _Bytes: TypeAlias = bytes
10
8
  _FieldsType: TypeAlias = tuple[int, int, int, int, int, int]
11
9
 
12
10
  __version__: str
13
11
 
14
- class SafeUUID(Enum):
15
- safe: int
16
- unsafe: int
17
- unknown: None
18
-
19
12
  class UUID:
20
13
  """Instances of the UUID class represent UUIDs as specified in RFC 4122.
21
14
  UUID objects are immutable, hashable, and usable as dictionary keys.
@@ -74,44 +67,44 @@ class UUID:
74
67
  def __init__(
75
68
  self,
76
69
  hex: str | None = None,
77
- bytes: _Bytes | None = None,
78
- bytes_le: _Bytes | None = None,
70
+ bytes: builtins.bytes | None = None,
71
+ bytes_le: builtins.bytes | None = None,
79
72
  fields: _FieldsType | None = None,
80
- int: _Int | None = None,
81
- version: _Int | None = None,
73
+ int: builtins.int | None = None,
74
+ version: builtins.int | None = None,
82
75
  *,
83
76
  is_safe: SafeUUID = ...,
84
77
  ) -> None: ...
85
78
  @property
86
79
  def is_safe(self) -> SafeUUID: ...
87
80
  @property
88
- def bytes(self) -> _Bytes: ...
81
+ def bytes(self) -> builtins.bytes: ...
89
82
  @property
90
- def bytes_le(self) -> _Bytes: ...
83
+ def bytes_le(self) -> builtins.bytes: ...
91
84
  @property
92
- def clock_seq(self) -> _Int: ...
85
+ def clock_seq(self) -> builtins.int: ...
93
86
  @property
94
- def clock_seq_hi_variant(self) -> _Int: ...
87
+ def clock_seq_hi_variant(self) -> builtins.int: ...
95
88
  @property
96
- def clock_seq_low(self) -> _Int: ...
89
+ def clock_seq_low(self) -> builtins.int: ...
97
90
  @property
98
91
  def fields(self) -> _FieldsType: ...
99
92
  @property
100
93
  def hex(self) -> str: ...
101
94
  @property
102
- def int(self) -> _Int: ...
95
+ def int(self) -> builtins.int: ...
103
96
  @property
104
- def node(self) -> _Int: ...
97
+ def node(self) -> builtins.int: ...
105
98
  @property
106
- def time(self) -> _Int: ...
99
+ def time(self) -> builtins.int: ...
107
100
  @property
108
- def time_hi_version(self) -> _Int: ...
101
+ def time_hi_version(self) -> builtins.int: ...
109
102
  @property
110
- def time_low(self) -> _Int: ...
103
+ def time_low(self) -> builtins.int: ...
111
104
  @property
112
- def time_mid(self) -> _Int: ...
105
+ def time_mid(self) -> builtins.int: ...
113
106
  @property
114
- def timestamp(self) -> _Int:
107
+ def timestamp(self) -> builtins.int:
115
108
  """Get UUID timestamp milliseconds since epoch.
116
109
  Only works for UUID versions 1, 6 and 7, otherwise raises ValueError."""
117
110
  ...
@@ -121,21 +114,16 @@ class UUID:
121
114
  @property
122
115
  def variant(self) -> str: ...
123
116
  @property
124
- def version(self) -> _Int | None: ...
125
- def __int__(self) -> _Int: ...
117
+ def version(self) -> builtins.int | None: ...
118
+ def __int__(self) -> builtins.int: ...
126
119
  def __eq__(self, other: object) -> bool: ...
127
120
  def __lt__(self, other: UUID) -> bool: ...
128
121
  def __le__(self, other: UUID) -> bool: ...
129
122
  def __gt__(self, other: UUID) -> bool: ...
130
123
  def __ge__(self, other: UUID) -> bool: ...
131
124
 
132
- if sys.version_info >= (3, 9):
133
- def getnode() -> int: ...
134
-
135
- else:
136
- def getnode(*, getters: Unused = None) -> int: ... # undocumented
137
-
138
- def uuid1(node: _Int | None = None, clock_seq: _Int | None = None) -> UUID:
125
+ def getnode() -> int: ...
126
+ def uuid1(node: int | None = None, clock_seq: int | None = None) -> UUID:
139
127
  """Generate a UUID from a host ID, sequence number, and the current time.
140
128
  If 'node' is not given, getnode() is used to obtain the hardware
141
129
  address. If 'clock_seq' is given, it is used as the sequence number;
@@ -165,7 +153,7 @@ else:
165
153
  ...
166
154
 
167
155
  def uuid6(
168
- node: _Int | None = None, timestamp: _Int | None = None, nanos: _Int | None = None
156
+ node: int | None = None, timestamp: int | None = None, nanos: int | None = None
169
157
  ) -> UUID:
170
158
  """Generate a version 6 UUID using the given timestamp and a host ID.
171
159
  This is similar to version 1 UUIDs,
@@ -173,11 +161,11 @@ def uuid6(
173
161
  """
174
162
  ...
175
163
 
176
- def uuid7(timestamp: _Int | None = None, nanos: _Int | None = None) -> UUID:
164
+ def uuid7(timestamp: int | None = None, nanos: int | None = None) -> UUID:
177
165
  """Generate a version 7 UUID using a time value and random bytes."""
178
166
  ...
179
167
 
180
- def uuid8(bytes: _Bytes) -> UUID:
168
+ def uuid8(bytes: bytes) -> UUID:
181
169
  """Generate a custom UUID comprised almost entirely of user-supplied bytes."""
182
170
  ...
183
171
 
@@ -189,3 +177,25 @@ RESERVED_NCS: str
189
177
  RFC_4122: str
190
178
  RESERVED_MICROSOFT: str
191
179
  RESERVED_FUTURE: str
180
+
181
+ __all__ = [
182
+ "NAMESPACE_DNS",
183
+ "NAMESPACE_OID",
184
+ "NAMESPACE_URL",
185
+ "NAMESPACE_X500",
186
+ "RESERVED_FUTURE",
187
+ "RESERVED_MICROSOFT",
188
+ "RESERVED_NCS",
189
+ "RFC_4122",
190
+ "UUID",
191
+ "SafeUUID",
192
+ "__version__",
193
+ "getnode",
194
+ "uuid1",
195
+ "uuid3",
196
+ "uuid4",
197
+ "uuid5",
198
+ "uuid6",
199
+ "uuid7",
200
+ "uuid8",
201
+ ]
@@ -0,0 +1,5 @@
1
+ mkdocs==1.6.1
2
+ mkdocs-material==9.5.34
3
+ mypy==1.11.2
4
+ pytest==8.3.2
5
+ ruff==0.6.4
@@ -1,14 +1,18 @@
1
1
  use mac_address::get_mac_address;
2
2
  use pyo3::{
3
3
  exceptions::{PyTypeError, PyValueError},
4
+ ffi,
4
5
  prelude::*,
5
6
  pyclass::CompareOp,
6
7
  types::{PyBytes, PyDict},
7
8
  };
8
9
  use rand::RngCore;
9
- use std::hash::Hasher;
10
- use std::sync::atomic::{AtomicU64, Ordering};
11
10
  use std::{collections::hash_map::DefaultHasher, hash::Hash};
11
+ use std::{hash::Hasher, sync::atomic::AtomicPtr};
12
+ use std::{
13
+ ptr::null_mut,
14
+ sync::atomic::{AtomicU64, Ordering},
15
+ };
12
16
  use uuid::{Builder, Bytes, Context, Timestamp, Uuid, Variant, Version};
13
17
 
14
18
  static NODE: AtomicU64 = AtomicU64::new(0);
@@ -134,7 +138,7 @@ impl UUID {
134
138
  }
135
139
 
136
140
  pub fn __deepcopy__(&self, py: Python, _memo: &Bound<'_, PyDict>) -> Py<PyAny> {
137
- self.clone().into_py(py)
141
+ self.clone().into_pyobject(py).unwrap().into_any().unbind()
138
142
  }
139
143
 
140
144
  #[getter]
@@ -154,7 +158,7 @@ impl UUID {
154
158
  bytes[3], bytes[2], bytes[1], bytes[0], bytes[5], bytes[4], bytes[7], bytes[6],
155
159
  bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
156
160
  ];
157
- PyBytes::new_bound(py, &bytes)
161
+ PyBytes::new(py, &bytes)
158
162
  }
159
163
 
160
164
  #[getter]
@@ -306,6 +310,11 @@ impl UUID {
306
310
  uuid: Uuid::from_u128(int),
307
311
  })
308
312
  }
313
+
314
+ #[getter]
315
+ fn is_safe(&self) -> *mut ffi::PyObject {
316
+ return SAFE_UUID_UNKNOWN.load(Ordering::Relaxed);
317
+ }
309
318
  }
310
319
 
311
320
  #[pyfunction]
@@ -429,6 +438,9 @@ fn _getnode() -> u64 {
429
438
  node
430
439
  }
431
440
 
441
+ // ptr to python stdlib uuid.SafeUUID.unknown
442
+ static SAFE_UUID_UNKNOWN: AtomicPtr<ffi::PyObject> = AtomicPtr::new(null_mut());
443
+
432
444
  #[pyfunction]
433
445
  fn getnode() -> PyResult<u64> {
434
446
  Ok(_getnode())
@@ -436,6 +448,18 @@ fn getnode() -> PyResult<u64> {
436
448
 
437
449
  #[pymodule]
438
450
  fn _uuid_utils(m: &Bound<'_, PyModule>) -> PyResult<()> {
451
+ let safe_uuid_unknown = Python::with_gil(|py| {
452
+ return PyModule::import(py, "uuid")
453
+ .unwrap()
454
+ .getattr("SafeUUID")
455
+ .unwrap()
456
+ .getattr("unknown")
457
+ .unwrap()
458
+ .unbind();
459
+ });
460
+
461
+ SAFE_UUID_UNKNOWN.store(safe_uuid_unknown.into_ptr(), Ordering::Relaxed);
462
+
439
463
  m.add("__version__", env!("CARGO_PKG_VERSION"))?;
440
464
  m.add_class::<UUID>()?;
441
465
  m.add_function(wrap_pyfunction!(uuid1, m)?)?;
@@ -2,7 +2,7 @@ import copy
2
2
  import pickle
3
3
  import sys
4
4
  from datetime import datetime
5
- from uuid import UUID, getnode
5
+ from uuid import UUID, SafeUUID, getnode
6
6
 
7
7
  import pytest
8
8
  import uuid_utils
@@ -200,6 +200,11 @@ def test_copy() -> None:
200
200
  assert copy.deepcopy(uuid) == uuid
201
201
 
202
202
 
203
+ def test_is_safe() -> None:
204
+ assert uuid_utils.uuid1().is_safe is SafeUUID.unknown
205
+ assert uuid_utils.uuid4().is_safe is SafeUUID.unknown
206
+
207
+
203
208
  @pytest.mark.xfail(sys.platform == "linux", reason="Might fail in Github Actions")
204
209
  def test_getnode() -> None:
205
210
  assert uuid_utils.getnode() == getnode()
@@ -1,14 +0,0 @@
1
- [package]
2
- name = "uuid-utils"
3
- version = "0.9.0"
4
- edition = "2021"
5
-
6
- [lib]
7
- name = "uuid_utils"
8
- crate-type = ["cdylib"]
9
-
10
- [dependencies]
11
- mac_address = "1.1.7"
12
- pyo3 = { version = "0.22.0", features = ["extension-module", "generate-import-lib"] }
13
- rand = "0.8.5"
14
- uuid = { version = "1.9.1", features = ["v1", "v3", "v4", "v5", "v6", "v7", "v8", "fast-rng"]}
@@ -1,5 +0,0 @@
1
- mkdocs==1.6.0
2
- mkdocs-material==9.5.26
3
- mypy==1.10.0
4
- pytest==8.2.0
5
- ruff==0.4.8
File without changes
File without changes
File without changes
File without changes
File without changes