uuid-utils 0.7.0__tar.gz → 0.8.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.7.0 → uuid_utils-0.8.0}/.github/workflows/ci.yml +18 -10
  2. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/Cargo.lock +1 -1
  3. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/Cargo.toml +1 -1
  4. uuid_utils-0.8.0/Makefile +39 -0
  5. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/PKG-INFO +22 -17
  6. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/README.md +21 -16
  7. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/benchmarks/bench_generator.py +4 -4
  8. uuid_utils-0.8.0/docs/api.md +27 -0
  9. uuid_utils-0.8.0/docs/index.md +105 -0
  10. uuid_utils-0.8.0/mkdocs.yml +45 -0
  11. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/pyproject.toml +9 -3
  12. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/python/uuid_utils/__init__.pyi +26 -11
  13. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/python/uuid_utils/compat/__init__.pyi +45 -7
  14. uuid_utils-0.8.0/requirements.txt +5 -0
  15. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/src/lib.rs +32 -12
  16. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/tests/test_compat/test_compat.py +0 -1
  17. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/tests/test_uuid.py +19 -5
  18. uuid_utils-0.7.0/Makefile +0 -28
  19. uuid_utils-0.7.0/requirements.txt +0 -5
  20. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/.gitignore +0 -0
  21. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/LICENSE.md +0 -0
  22. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/benchmarks/README.md +0 -0
  23. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/benchmarks/bench_parser.py +0 -0
  24. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/python/uuid_utils/__init__.py +0 -0
  25. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/python/uuid_utils/compat/__init__.py +0 -0
  26. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/python/uuid_utils/py.typed +0 -0
  27. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/tests/__init__.py +0 -0
  28. {uuid_utils-0.7.0 → uuid_utils-0.8.0}/tests/test_compat/__init__.py +0 -0
@@ -8,9 +8,6 @@ on:
8
8
  - "*"
9
9
  pull_request:
10
10
 
11
- permissions:
12
- contents: read
13
-
14
11
  env:
15
12
  RUSTFLAGS: "--cfg uuid_unstable"
16
13
 
@@ -26,23 +23,22 @@ jobs:
26
23
  - name: Install dependencies
27
24
  run: pip install -r requirements.txt
28
25
  - name: Check code
29
- run: |
30
- black --check --diff .
31
- isort --check --project=uuid_utils .
32
- mypy .
33
- ruff .
26
+ run: make lint
27
+ - name: Check docs
28
+ run: make docs_build
34
29
 
35
30
  linux:
36
- name: "Linux: ${{ matrix.target }}"
31
+ name: "Linux: ${{ matrix.target }} Python ${{ matrix.python-version }}"
37
32
  runs-on: ubuntu-latest
38
33
  strategy:
39
34
  matrix:
40
35
  target: [x86_64, i686]
36
+ python-version: ["3.10", "3.11", "3.12"]
41
37
  steps:
42
38
  - uses: actions/checkout@v3
43
39
  - uses: actions/setup-python@v4
44
40
  with:
45
- python-version: "3.11"
41
+ python-version: "${{ matrix.python-version }}"
46
42
  - name: Build wheels
47
43
  uses: PyO3/maturin-action@v1
48
44
  with:
@@ -261,3 +257,15 @@ jobs:
261
257
  with:
262
258
  command: upload
263
259
  args: --skip-existing *
260
+
261
+ docs:
262
+ name: Publish docs
263
+ runs-on: ubuntu-latest
264
+ if: "startsWith(github.ref, 'refs/tags/')"
265
+ needs: [release]
266
+ steps:
267
+ - uses: actions/checkout@v3
268
+ - name: Build and publish docs
269
+ run: |
270
+ pip install -r requirements.txt
271
+ make docs_build && make docs_deploy
@@ -406,7 +406,7 @@ dependencies = [
406
406
 
407
407
  [[package]]
408
408
  name = "uuid-utils"
409
- version = "0.7.0"
409
+ version = "0.8.0"
410
410
  dependencies = [
411
411
  "mac_address",
412
412
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "uuid-utils"
3
- version = "0.7.0"
3
+ version = "0.8.0"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -0,0 +1,39 @@
1
+ .DEFAULT_GOAL := all
2
+
3
+ .PHONY: build
4
+ build:
5
+ RUSTFLAGS="--cfg uuid_unstable" maturin develop --release
6
+
7
+ .PHONY: format
8
+ format:
9
+ ruff check --fix python/ tests/
10
+ ruff format python/ tests/
11
+ cargo fmt
12
+
13
+ .PHONY: lint
14
+ lint:
15
+ ruff check python/ tests/
16
+ ruff format --check --diff python/ tests/
17
+ mypy python/ tests/
18
+ .PHONY: test
19
+ test:
20
+ pytest tests -vvv
21
+
22
+ .PHONY: bench
23
+ bench:
24
+ richbench benchmarks/
25
+
26
+ .PHONY: docs_build
27
+ docs_build:
28
+ mkdocs build
29
+
30
+ .PHONY: docs_serve
31
+ docs_serve:
32
+ mkdocs serve --dev-addr localhost:8080
33
+
34
+ .PHONY: docs_deploy
35
+ docs_deploy:
36
+ mkdocs gh-deploy --force
37
+
38
+ .PHONY: all
39
+ all: format build lint test
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: uuid_utils
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Programming Language :: Python
6
6
  Classifier: Programming Language :: Python :: 3
@@ -41,8 +41,8 @@ Python UUID implementation using Rust's UUID library.
41
41
  This will make `uuid4` function around 10x faster.
42
42
 
43
43
  This package can be a drop-in replacement to the standard library UUID
44
- which implements existing UUID versions like V4 in Rust
45
- and also adds draft UUID versions like V6.
44
+ which implements existing UUID versions like v4 in Rust
45
+ and also adds draft UUID versions like v6.
46
46
 
47
47
  Avaialble UUID versions:
48
48
 
@@ -57,10 +57,15 @@ Avaialble UUID versions:
57
57
  <sup>Please note that UUID versions 6, 7 and 8 are still in draft RFC.</sup><br>
58
58
 
59
59
  ## Installation
60
-
60
+ Using `pip`:
61
61
  ```shell
62
62
  $ pip install uuid-utils
63
63
  ```
64
+ or, using `conda`:
65
+
66
+ ```shell
67
+ $ conda install -c conda-forge uuid-utils
68
+ ```
64
69
 
65
70
  ## Example
66
71
 
@@ -84,12 +89,12 @@ UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
84
89
  UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
85
90
  ```
86
91
 
87
- ## Compat module
92
+ ## Compatibility
88
93
 
89
- In some cases you might need `UUID` instances to be returned
94
+ In some cases, for example if you are using `Django`, you might need `UUID` instances to be returned
90
95
  from the standrad-library `uuid`, not a custom `UUID` class.
91
96
  In that case you can use the `uuid_utils.compat` which comes with a performance penalty
92
- in comparison with the `uuid_utils` default behaviour, but still faster than the standard-library.
97
+ in comparison with the `uuid_utils` default behaviour, but is still faster than the standard-library.
93
98
 
94
99
  ```py
95
100
  >>> import uuid_utils.compat as uuid
@@ -101,16 +106,16 @@ UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')
101
106
 
102
107
  ## Benchmarks
103
108
 
104
- | Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
105
- |-----------------|---------|---------|---------|-----------------|-----------------|-----------------|
106
- | UUID V1 | 0.058 | 0.059 | 0.058 | 0.005 (12.0x) | 0.005 (11.9x) | 0.005 (12.0x) |
107
- | UUID V3 | 0.063 | 0.064 | 0.063 | 0.008 (7.9x) | 0.008 (8.1x) | 0.008 (8.0x) |
108
- | UUID V4 | 0.041 | 0.041 | 0.041 | 0.004 (11.1x) | 0.004 (10.8x) | 0.004 (10.9x) |
109
- | UUID V5 | 0.064 | 0.066 | 0.065 | 0.008 (8.1x) | 0.008 (8.1x) | 0.008 (8.1x) |
110
- | UUID from hex | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.6x) |
111
- | UUID from bytes | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.7x) |
112
- | UUID from int | 0.024 | 0.025 | 0.024 | 0.004 (6.6x) | 0.004 (6.7x) | 0.004 (6.6x) |
113
- | 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.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) |
114
119
 
115
120
  ## How to develop locally
116
121
 
@@ -15,8 +15,8 @@ Python UUID implementation using Rust's UUID library.
15
15
  This will make `uuid4` function around 10x faster.
16
16
 
17
17
  This package can be a drop-in replacement to the standard library UUID
18
- which implements existing UUID versions like V4 in Rust
19
- and also adds draft UUID versions like V6.
18
+ which implements existing UUID versions like v4 in Rust
19
+ and also adds draft UUID versions like v6.
20
20
 
21
21
  Avaialble UUID versions:
22
22
 
@@ -31,10 +31,15 @@ Avaialble UUID versions:
31
31
  <sup>Please note that UUID versions 6, 7 and 8 are still in draft RFC.</sup><br>
32
32
 
33
33
  ## Installation
34
-
34
+ Using `pip`:
35
35
  ```shell
36
36
  $ pip install uuid-utils
37
37
  ```
38
+ or, using `conda`:
39
+
40
+ ```shell
41
+ $ conda install -c conda-forge uuid-utils
42
+ ```
38
43
 
39
44
  ## Example
40
45
 
@@ -58,12 +63,12 @@ UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
58
63
  UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
59
64
  ```
60
65
 
61
- ## Compat module
66
+ ## Compatibility
62
67
 
63
- In some cases you might need `UUID` instances to be returned
68
+ In some cases, for example if you are using `Django`, you might need `UUID` instances to be returned
64
69
  from the standrad-library `uuid`, not a custom `UUID` class.
65
70
  In that case you can use the `uuid_utils.compat` which comes with a performance penalty
66
- in comparison with the `uuid_utils` default behaviour, but still faster than the standard-library.
71
+ in comparison with the `uuid_utils` default behaviour, but is still faster than the standard-library.
67
72
 
68
73
  ```py
69
74
  >>> import uuid_utils.compat as uuid
@@ -75,16 +80,16 @@ UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')
75
80
 
76
81
  ## Benchmarks
77
82
 
78
- | Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
79
- |-----------------|---------|---------|---------|-----------------|-----------------|-----------------|
80
- | UUID V1 | 0.058 | 0.059 | 0.058 | 0.005 (12.0x) | 0.005 (11.9x) | 0.005 (12.0x) |
81
- | UUID V3 | 0.063 | 0.064 | 0.063 | 0.008 (7.9x) | 0.008 (8.1x) | 0.008 (8.0x) |
82
- | UUID V4 | 0.041 | 0.041 | 0.041 | 0.004 (11.1x) | 0.004 (10.8x) | 0.004 (10.9x) |
83
- | UUID V5 | 0.064 | 0.066 | 0.065 | 0.008 (8.1x) | 0.008 (8.1x) | 0.008 (8.1x) |
84
- | UUID from hex | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.6x) |
85
- | UUID from bytes | 0.024 | 0.025 | 0.024 | 0.004 (6.7x) | 0.004 (6.6x) | 0.004 (6.7x) |
86
- | UUID from int | 0.024 | 0.025 | 0.024 | 0.004 (6.6x) | 0.004 (6.7x) | 0.004 (6.6x) |
87
- | 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.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) |
88
93
 
89
94
  ## How to develop locally
90
95
 
@@ -46,8 +46,8 @@ def uuid_utils_uuid5() -> None:
46
46
 
47
47
 
48
48
  __benchmarks__ = [
49
- (uuid_uuid1, uuid_utils_uuid1, "UUID V1"),
50
- (uuid_uuid3, uuid_utils_uuid3, "UUID V3"),
51
- (uuid_uuid4, uuid_utils_uuid4, "UUID V4"),
52
- (uuid_uuid5, uuid_utils_uuid5, "UUID V5"),
49
+ (uuid_uuid1, uuid_utils_uuid1, "UUID v1"),
50
+ (uuid_uuid3, uuid_utils_uuid3, "UUID v3"),
51
+ (uuid_uuid4, uuid_utils_uuid4, "UUID v4"),
52
+ (uuid_uuid5, uuid_utils_uuid5, "UUID v5"),
53
53
  ]
@@ -0,0 +1,27 @@
1
+ class `uuid_utils.UUID`
2
+
3
+ | Property | Description |
4
+ | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
5
+ | `bytes` | the UUID as a 16-byte string (containing the six integer fields in big-endian byte order) |
6
+ | `bytes_le` | the UUID as a 16-byte string (with time_low, time_mid, and time_hi_version in little-endian byte order) |
7
+ | `fields` | a tuple of the six integer fields of the UUID, which are also available as six individual attributes and two derived attributes |
8
+ | `hex` | the UUID as a 32-character hexadecimal string |
9
+ | `int` | the UUID as a 128-bit integer |
10
+ | `urn` | the UUID as a URN as specified in RFC 4122 |
11
+ | `variant` | the UUID variant (one of the constants RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) |
12
+ | `version` | the UUID version number |
13
+ | `is_safe` | An enum indicating whether the UUID has been generated in a way that is safe for multiprocessing applications, via `uuid_generate_time_safe(3)` |
14
+ | `timestamp` | The timestamp of the UUID in milliseconds since epoch. Only works for UUID versions 1, 6 and 7, otherwise raises `ValueError`. |
15
+
16
+ module `uuid_utils`
17
+
18
+ | Function | Description |
19
+ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
20
+ | `uuid1` | Generate a UUID from a host ID, sequence number, and the current time. If `node` is not given, `getnode()` is used to obtain the hardware address. If `clock_seq` is given, it is used as the sequence number; otherwise a random 14-bit sequence number is chosen. |
21
+ | `uuid3` | Generate a UUID from the MD5 hash of a namespace UUID and a name. |
22
+ | `uuid4` | Generate a random UUID. |
23
+ | `uuid5` | Generate a UUID from the SHA-1 hash of a namespace UUID and a name. |
24
+ | `uuid6` | Generate a version 6 UUID using the given timestamp and a host ID. This is similar to version 1 UUIDs, except that it is lexicographically sortable by timestamp. |
25
+ | `uuid7` | Generate a version 7 UUID using a time value and random bytes. |
26
+ | `uuid8` | Generate a custom UUID comprised almost entirely of user-supplied bytes. |
27
+ | `getnode` | Get the hardware address as a 48-bit positive integer. |
@@ -0,0 +1,105 @@
1
+ # Python UUID Utils
2
+
3
+ <p align="center">
4
+ <a href="https://pypi.org/project/uuid-utils/">
5
+ <img src="https://badge.fury.io/py/uuid-utils.svg" alt="Package version">
6
+ </a>
7
+ <a href="https://pypi.org/project/uuid-utils" target="_blank">
8
+ <img src="https://img.shields.io/pypi/pyversions/uuid-utils.svg?color=%2334D058" alt="Supported Python versions">
9
+ </a>
10
+ </p>
11
+
12
+ ---
13
+
14
+ Python UUID implementation using Rust's UUID library.
15
+ This will make `uuid4` function around 10x faster.
16
+
17
+ This package can be a drop-in replacement to the standard library UUID
18
+ which implements existing UUID versions like v4 in Rust
19
+ and also adds draft UUID versions like v6.
20
+
21
+ Avaialble UUID versions:
22
+
23
+ - `uuid1` - Version 1 UUIDs using a timestamp and monotonic counter.
24
+ - `uuid3` - Version 3 UUIDs based on the MD5 hash of some data.
25
+ - `uuid4` - Version 4 UUIDs with random data.
26
+ - `uuid5` - Version 5 UUIDs based on the SHA1 hash of some data.
27
+ - `uuid6` - Version 6 UUIDs using a timestamp and monotonic counter.
28
+ - `uuid7` - Version 7 UUIDs using a Unix timestamp ordered by time.
29
+ - `uuid8` - Version 8 UUIDs using user-defined data.
30
+
31
+ <sup>Please note that UUID versions 6, 7 and 8 are still in draft RFC.</sup><br>
32
+
33
+ ## Installation
34
+ Using `pip`:
35
+ ```shell
36
+ $ pip install uuid-utils
37
+ ```
38
+ or, using `conda`:
39
+
40
+ ```shell
41
+ $ conda install -c conda-forge uuid-utils
42
+ ```
43
+
44
+ ## Example
45
+
46
+ ```shell
47
+ >>> import uuid_utils as uuid
48
+
49
+ >>> # make a random UUID
50
+ >>> uuid.uuid4()
51
+ UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')
52
+
53
+ >>> # make a random UUID using a Unix timestamp which is time-ordered.
54
+ >>> uuid.uuid7()
55
+ UUID('018afa4a-0d21-7e6c-b857-012bc678552b')
56
+
57
+ >>> # make a UUID using a SHA-1 hash of a namespace UUID and a name
58
+ >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
59
+ UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
60
+
61
+ >>> # make a UUID using an MD5 hash of a namespace UUID and a name
62
+ >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
63
+ UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
64
+ ```
65
+
66
+ ## Compatibility
67
+
68
+ In some cases, for example if you are using `Django`, you might need `UUID` instances to be returned
69
+ from the standrad-library `uuid`, not a custom `UUID` class.
70
+ In that case you can use the `uuid_utils.compat` which comes with a performance penalty
71
+ in comparison with the `uuid_utils` default behaviour, but is still faster than the standard-library.
72
+
73
+ ```py
74
+ >>> import uuid_utils.compat as uuid
75
+
76
+ >>> # make a random UUID
77
+ >>> uuid.uuid4()
78
+ UUID('ffe95fcc-b818-4aca-a350-e0a35b9de6ec')
79
+ ```
80
+
81
+ ## Benchmarks
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) |
93
+
94
+ ## How to develop locally
95
+
96
+ ```shell
97
+ $ make build
98
+ $ make test
99
+ ```
100
+
101
+ Or:
102
+
103
+ ```shell
104
+ $ RUSTFLAGS="--cfg uuid_unstable" maturin develop --release
105
+ ```
@@ -0,0 +1,45 @@
1
+ site_name: UUID-Utils
2
+ site_description: Python bindings to Rust UUID
3
+ site_url: https://aminalaee.dev/uuid-utils
4
+
5
+ theme:
6
+ name: "material"
7
+ palette:
8
+ primary: white
9
+ features:
10
+ - content.code.copy
11
+
12
+ repo_name: aminalaee/uuid-utils
13
+ repo_url: https://github.com/aminalaee/uuid-utils
14
+ edit_uri: ""
15
+
16
+ nav:
17
+ - Introduction: "index.md"
18
+ - API: "api.md"
19
+
20
+ markdown_extensions:
21
+ - markdown.extensions.codehilite:
22
+ guess_lang: false
23
+ - tables
24
+ - pymdownx.details
25
+ - pymdownx.highlight
26
+ - pymdownx.tabbed
27
+ - pymdownx.superfences
28
+
29
+ watch:
30
+ - python/
31
+
32
+ plugins:
33
+ - search
34
+
35
+ extra:
36
+ analytics:
37
+ provider: google
38
+ property: G-MV427T1Z9X
39
+ social:
40
+ - icon: fontawesome/brands/github
41
+ link: https://github.com/aminalaee
42
+ - icon: fontawesome/brands/twitter
43
+ link: https://twitter.com/aminalaee
44
+ - icon: fontawesome/brands/linkedin
45
+ link: https://www.linkedin.com/in/amin-alaee
@@ -42,6 +42,12 @@ ignore_missing_imports = true
42
42
  show_error_codes = true
43
43
  no_implicit_optional = true
44
44
 
45
- [tool.isort]
46
- profile = "black"
47
- combine_as_imports = true
45
+ [tool.ruff.lint]
46
+ select = [
47
+ "E",
48
+ "W",
49
+ "F",
50
+ "I",
51
+ "C4",
52
+ "UP",
53
+ ]
@@ -60,12 +60,15 @@ class UUID:
60
60
  variant the UUID variant (one of the constants RESERVED_NCS,
61
61
  RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
62
62
 
63
- version the UUID version number (1 through 5, meaningful only
64
- when the variant is RFC_4122)
63
+ version the UUID version number
65
64
 
66
65
  is_safe An enum indicating whether the UUID has been generated in
67
66
  a way that is safe for multiprocessing applications, via
68
67
  uuid_generate_time_safe(3).
68
+
69
+ timestamp The timestamp of the UUID in milliseconds since epoch.
70
+ Only works for UUID versions 1, 6 and 7,
71
+ otherwise raises ValueError.
69
72
  """
70
73
 
71
74
  def __init__(
@@ -139,31 +142,43 @@ def uuid1(node: _Int | None = None, clock_seq: _Int | None = None) -> UUID:
139
142
  otherwise a random 14-bit sequence number is chosen."""
140
143
  ...
141
144
 
142
- def uuid3(namespace: UUID, name: str) -> UUID:
143
- """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
144
- ...
145
+ if sys.version_info >= (3, 12):
146
+ def uuid3(namespace: UUID, name: str | bytes) -> UUID:
147
+ """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
148
+ ...
149
+ else:
150
+ def uuid3(namespace: UUID, name: str) -> UUID:
151
+ """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
152
+ ...
145
153
 
146
154
  def uuid4() -> UUID:
147
155
  """Generate a random UUID."""
148
156
  ...
149
157
 
150
- def uuid5(namespace: UUID, name: str) -> UUID:
151
- """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
152
- ...
158
+ if sys.version_info >= (3, 12):
159
+ def uuid5(namespace: UUID, name: str | bytes) -> UUID:
160
+ """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
161
+ ...
162
+ else:
163
+ def uuid5(namespace: UUID, name: str) -> UUID:
164
+ """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
165
+ ...
153
166
 
154
- def uuid6(node: _Int | None = None, timestamp: _Int | None = None) -> UUID:
167
+ def uuid6(
168
+ node: _Int | None = None, timestamp: _Int | None = None, nanos: _Int | None = None
169
+ ) -> UUID:
155
170
  """Generate a version 6 UUID using the given timestamp and a host ID.
156
171
  This is similar to version 1 UUIDs,
157
172
  except that it is lexicographically sortable by timestamp.
158
173
  """
159
174
  ...
160
175
 
161
- def uuid7(timestamp: _Int | None = None) -> UUID:
176
+ def uuid7(timestamp: _Int | None = None, nanos: _Int | None = None) -> UUID:
162
177
  """Generate a version 7 UUID using a time value and random bytes."""
163
178
  ...
164
179
 
165
180
  def uuid8(bytes: _Bytes) -> UUID:
166
- """Generate a custom UUID comprised almost entirely of user-supplied bytes.."""
181
+ """Generate a custom UUID comprised almost entirely of user-supplied bytes."""
167
182
  ...
168
183
 
169
184
  NAMESPACE_DNS: UUID
@@ -1,7 +1,34 @@
1
- from uuid import UUID
1
+ import sys
2
+ from uuid import (
3
+ NAMESPACE_DNS,
4
+ NAMESPACE_OID,
5
+ NAMESPACE_URL,
6
+ NAMESPACE_X500,
7
+ RESERVED_FUTURE,
8
+ RESERVED_MICROSOFT,
9
+ RESERVED_NCS,
10
+ RFC_4122,
11
+ UUID,
12
+ SafeUUID,
13
+ getnode,
14
+ )
2
15
 
3
16
  from typing_extensions import TypeAlias
4
17
 
18
+ __all__ = [
19
+ "NAMESPACE_DNS",
20
+ "NAMESPACE_OID",
21
+ "NAMESPACE_URL",
22
+ "NAMESPACE_X500",
23
+ "RESERVED_FUTURE",
24
+ "RESERVED_MICROSOFT",
25
+ "RESERVED_NCS",
26
+ "RFC_4122",
27
+ "UUID",
28
+ "SafeUUID",
29
+ "getnode",
30
+ ]
31
+
5
32
  # Because UUID has properties called int and bytes we need to rename these temporarily.
6
33
  _Int: TypeAlias = int
7
34
  _Bytes: TypeAlias = bytes
@@ -13,17 +40,28 @@ def uuid1(node: _Int | None = None, clock_seq: _Int | None = None) -> UUID:
13
40
  otherwise a random 14-bit sequence number is chosen."""
14
41
  ...
15
42
 
16
- def uuid3(namespace: UUID, name: str) -> UUID:
17
- """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
18
- ...
43
+ if sys.version_info >= (3, 12):
44
+ def uuid3(namespace: UUID, name: str | bytes) -> UUID:
45
+ """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
46
+ ...
47
+
48
+ else:
49
+ def uuid3(namespace: UUID, name: str) -> UUID:
50
+ """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
51
+ ...
19
52
 
20
53
  def uuid4() -> UUID:
21
54
  """Generate a random UUID."""
22
55
  ...
23
56
 
24
- def uuid5(namespace: UUID, name: str) -> UUID:
25
- """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
26
- ...
57
+ if sys.version_info >= (3, 12):
58
+ def uuid5(namespace: UUID, name: str | bytes) -> UUID:
59
+ """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
60
+ ...
61
+ else:
62
+ def uuid5(namespace: UUID, name: str) -> UUID:
63
+ """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
64
+ ...
27
65
 
28
66
  def uuid6(node: _Int | None = None, timestamp: _Int | None = None) -> UUID:
29
67
  """Generate a version 6 UUID using the given timestamp and a host ID.
@@ -0,0 +1,5 @@
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
@@ -18,6 +18,14 @@ pub const RFC_4122: &str = "specified in RFC 4122";
18
18
  pub const RESERVED_MICROSOFT: &str = "reserved for Microsoft compatibility";
19
19
  pub const RESERVED_FUTURE: &str = "reserved for future definition";
20
20
 
21
+ #[derive(FromPyObject)]
22
+ enum StringOrBytes {
23
+ #[pyo3(transparent, annotation = "str")]
24
+ String(String),
25
+ #[pyo3(transparent, annotation = "bytes")]
26
+ Bytes(Vec<u8>),
27
+ }
28
+
21
29
  #[pyclass(subclass, module = "uuid_utils")]
22
30
  #[derive(Clone, Debug)]
23
31
  struct UUID {
@@ -317,10 +325,15 @@ fn uuid1(node: Option<u64>, clock_seq: Option<u64>) -> PyResult<UUID> {
317
325
  }
318
326
 
319
327
  #[pyfunction]
320
- fn uuid3(namespace: UUID, name: &str) -> PyResult<UUID> {
321
- Ok(UUID {
322
- uuid: Uuid::new_v3(&namespace.uuid, name.as_bytes()),
323
- })
328
+ fn uuid3(namespace: UUID, name: StringOrBytes) -> PyResult<UUID> {
329
+ match name {
330
+ StringOrBytes::String(name) => Ok(UUID {
331
+ uuid: Uuid::new_v3(&namespace.uuid, name.as_bytes()),
332
+ }),
333
+ StringOrBytes::Bytes(name) => Ok(UUID {
334
+ uuid: Uuid::new_v3(&namespace.uuid, &name),
335
+ }),
336
+ }
324
337
  }
325
338
 
326
339
  #[pyfunction]
@@ -331,14 +344,19 @@ fn uuid4() -> PyResult<UUID> {
331
344
  }
332
345
 
333
346
  #[pyfunction]
334
- fn uuid5(namespace: &UUID, name: &str) -> PyResult<UUID> {
335
- Ok(UUID {
336
- uuid: Uuid::new_v5(&namespace.uuid, name.as_bytes()),
337
- })
347
+ fn uuid5(namespace: &UUID, name: StringOrBytes) -> PyResult<UUID> {
348
+ match name {
349
+ StringOrBytes::String(name) => Ok(UUID {
350
+ uuid: Uuid::new_v5(&namespace.uuid, name.as_bytes()),
351
+ }),
352
+ StringOrBytes::Bytes(name) => Ok(UUID {
353
+ uuid: Uuid::new_v5(&namespace.uuid, &name),
354
+ }),
355
+ }
338
356
  }
339
357
 
340
358
  #[pyfunction]
341
- fn uuid6(node: Option<u64>, timestamp: Option<u64>) -> PyResult<UUID> {
359
+ fn uuid6(node: Option<u64>, timestamp: Option<u64>, nanos: Option<u32>) -> PyResult<UUID> {
342
360
  let node = match node {
343
361
  Some(node) => node.to_ne_bytes(),
344
362
  None => _getnode().to_ne_bytes(),
@@ -347,7 +365,8 @@ fn uuid6(node: Option<u64>, timestamp: Option<u64>) -> PyResult<UUID> {
347
365
 
348
366
  let uuid = match timestamp {
349
367
  Some(timestamp) => {
350
- let timestamp = Timestamp::from_unix(&Context::new_random(), timestamp, 0);
368
+ let timestamp =
369
+ Timestamp::from_unix(&Context::new_random(), timestamp, nanos.unwrap_or(0));
351
370
  return Ok(UUID {
352
371
  uuid: Uuid::new_v6(timestamp, node),
353
372
  });
@@ -358,10 +377,11 @@ fn uuid6(node: Option<u64>, timestamp: Option<u64>) -> PyResult<UUID> {
358
377
  }
359
378
 
360
379
  #[pyfunction]
361
- fn uuid7(timestamp: Option<u64>) -> PyResult<UUID> {
380
+ fn uuid7(timestamp: Option<u64>, nanos: Option<u32>) -> PyResult<UUID> {
362
381
  let uuid = match timestamp {
363
382
  Some(timestamp) => {
364
- let timestamp = Timestamp::from_unix(&Context::new_random(), timestamp, 0);
383
+ let timestamp =
384
+ Timestamp::from_unix(&Context::new_random(), timestamp, nanos.unwrap_or(0));
365
385
  return Ok(UUID {
366
386
  uuid: Uuid::new_v7(timestamp),
367
387
  });
@@ -2,7 +2,6 @@ import uuid
2
2
  from typing import Callable
3
3
 
4
4
  import pytest
5
-
6
5
  from uuid_utils.compat import uuid1, uuid3, uuid4, uuid5, uuid6, uuid7, uuid8
7
6
 
8
7
 
@@ -1,10 +1,10 @@
1
1
  import copy
2
2
  import pickle
3
3
  import sys
4
+ from datetime import datetime
4
5
  from uuid import UUID, getnode
5
6
 
6
7
  import pytest
7
-
8
8
  import uuid_utils
9
9
 
10
10
 
@@ -73,8 +73,9 @@ def test_uuid1() -> None:
73
73
  assert isinstance(uuid, uuid_utils.UUID)
74
74
 
75
75
 
76
- def test_uuid3() -> None:
77
- uuid = uuid_utils.uuid3(namespace=uuid_utils.NAMESPACE_DNS, name="python.org")
76
+ @pytest.mark.parametrize("name", ["python.org", b"python.org"])
77
+ def test_uuid3(name: str) -> None:
78
+ uuid = uuid_utils.uuid3(namespace=uuid_utils.NAMESPACE_DNS, name=name)
78
79
  assert isinstance(uuid, uuid_utils.UUID)
79
80
 
80
81
 
@@ -83,8 +84,9 @@ def test_uuid4() -> None:
83
84
  assert isinstance(uuid, uuid_utils.UUID)
84
85
 
85
86
 
86
- def test_uuid5() -> None:
87
- uuid = uuid_utils.uuid5(namespace=uuid_utils.NAMESPACE_DNS, name="python.org")
87
+ @pytest.mark.parametrize("name", ["python.org", b"python.org"])
88
+ def test_uuid5(name: str) -> None:
89
+ uuid = uuid_utils.uuid5(namespace=uuid_utils.NAMESPACE_DNS, name=name)
88
90
  assert isinstance(uuid, uuid_utils.UUID)
89
91
 
90
92
 
@@ -92,6 +94,9 @@ def test_uuid6() -> None:
92
94
  uuid = uuid_utils.uuid6(getnode(), 1679665408)
93
95
  assert isinstance(uuid, uuid_utils.UUID)
94
96
 
97
+ uuid = uuid_utils.uuid6(getnode(), 1679665408, 123)
98
+ assert isinstance(uuid, uuid_utils.UUID)
99
+
95
100
  uuid = uuid_utils.uuid6()
96
101
  assert isinstance(uuid, uuid_utils.UUID)
97
102
 
@@ -100,9 +105,18 @@ def test_uuid7() -> None:
100
105
  uuid = uuid_utils.uuid7(1679665408)
101
106
  assert isinstance(uuid, uuid_utils.UUID)
102
107
 
108
+ uuid = uuid_utils.uuid7(1679665408, 999)
109
+ assert isinstance(uuid, uuid_utils.UUID)
110
+
103
111
  uuid = uuid_utils.uuid7()
104
112
  assert isinstance(uuid, uuid_utils.UUID)
105
113
 
114
+ ts = datetime(
115
+ year=2024, month=1, day=2, hour=3, minute=4, second=5, microsecond=123000
116
+ )
117
+ uuid = uuid_utils.uuid7(int(ts.timestamp()), ts.microsecond * 1_000)
118
+ assert uuid.timestamp == int(ts.timestamp() * 1000)
119
+
106
120
 
107
121
  def test_uuid8() -> None:
108
122
  uuid = uuid_utils.uuid8(b"1234567812345678")
uuid_utils-0.7.0/Makefile DELETED
@@ -1,28 +0,0 @@
1
- .DEFAULT_GOAL := all
2
-
3
- .PHONY: build
4
- build:
5
- RUSTFLAGS="--cfg uuid_unstable" maturin develop --release
6
-
7
- .PHONY: format
8
- format:
9
- ruff --fix python/ tests/
10
- black python/ tests/
11
- cargo fmt
12
-
13
- .PHONY: lint
14
- lint:
15
- ruff python/ tests/
16
- black --check --diff python/ tests/
17
- mypy python/ tests/
18
- .PHONY: test
19
- test:
20
- pytest tests -vvv
21
-
22
-
23
- .PHONY: bench
24
- bench:
25
- richbench benchmarks/
26
-
27
- .PHONY: all
28
- all: format build lint test
@@ -1,5 +0,0 @@
1
- black==24.4.2
2
- isort==5.13.2
3
- mypy==1.10.0
4
- pytest==8.2.0
5
- ruff==0.4.2
File without changes
File without changes
File without changes