| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,8 @@ | |||
| 1 | - :mod:`!uuid` --- UUID objects according to :rfc:`4122` | ||
| 1 | + :mod:`!uuid` --- UUID objects according to :rfc:`9562` | ||
| 2 | 2 | ====================================================== | |
| 3 | 3 | ||
| 4 | 4 | .. module:: uuid | |
| 5 | - :synopsis: UUID objects (universally unique identifiers) according to RFC 4122 | ||
| 5 | + :synopsis: UUID objects (universally unique identifiers) according to RFC 9562 | ||
| 6 | 6 | .. moduleauthor:: Ka-Ping Yee <ping@zesty.ca> | |
| 7 | 7 | .. sectionauthor:: George Yoshida <quiver@users.sourceforge.net> | |
| 8 | 8 | ||
@@ -12,7 +12,8 @@ | |||
| 12 | 12 | ||
| 13 | 13 | This module provides immutable :class:`UUID` objects (the :class:`UUID` class) | |
| 14 | 14 | and the functions :func:`uuid1`, :func:`uuid3`, :func:`uuid4`, :func:`uuid5` for | |
| 15 | - generating version 1, 3, 4, and 5 UUIDs as specified in :rfc:`4122`. | ||
| 15 | + generating version 1, 3, 4, 5, and 8 UUIDs as specified in :rfc:`9562` (which | ||
| 16 | + supersedes :rfc:`4122`). | ||
| 16 | 17 | ||
| 17 | 18 | If all you want is a unique ID, you should probably call :func:`uuid1` or | |
| 18 | 19 | :func:`uuid4`. Note that :func:`uuid1` may compromise privacy since it creates | |
@@ -65,7 +66,7 @@ which relays any information about the UUID's safety, using this enumeration: | |||
| 65 | 66 | ||
| 66 | 67 | Exactly one of *hex*, *bytes*, *bytes_le*, *fields*, or *int* must be given. | |
| 67 | 68 | The *version* argument is optional; if given, the resulting UUID will have its | |
| 68 | - variant and version number set according to :rfc:`4122`, overriding bits in the | ||
| 69 | + variant and version number set according to :rfc:`9562`, overriding bits in the | ||
| 69 | 70 | given *hex*, *bytes*, *bytes_le*, *fields*, or *int*. | |
| 70 | 71 | ||
| 71 | 72 | Comparison of UUID objects are made by way of comparing their | |
@@ -137,7 +138,7 @@ which relays any information about the UUID's safety, using this enumeration: | |||
| 137 | 138 | ||
| 138 | 139 | .. attribute:: UUID.urn | |
| 139 | 140 | ||
| 140 | - The UUID as a URN as specified in :rfc:`4122`. | ||
| 141 | + The UUID as a URN as specified in :rfc:`9562`. | ||
| 141 | 142 | ||
| 142 | 143 | ||
| 143 | 144 | .. attribute:: UUID.variant | |
@@ -149,9 +150,13 @@ which relays any information about the UUID's safety, using this enumeration: | |||
| 149 | 150 | ||
| 150 | 151 | .. attribute:: UUID.version | |
| 151 | 152 | ||
| 152 | - The UUID version number (1 through 5, meaningful only when the variant is | ||
| 153 | + The UUID version number (1 through 8, meaningful only when the variant is | ||
| 153 | 154 | :const:`RFC_4122`). | |
| 154 | 155 | ||
| 156 | + .. versionchanged:: next | ||
| 157 | + Added UUID version 8. | ||
| 158 | + | ||
| 159 | + | ||
| 155 | 160 | .. attribute:: UUID.is_safe | |
| 156 | 161 | ||
| 157 | 162 | An enumeration of :class:`SafeUUID` which indicates whether the platform | |
@@ -216,6 +221,23 @@ The :mod:`uuid` module defines the following functions: | |||
| 216 | 221 | ||
| 217 | 222 | .. index:: single: uuid5 | |
| 218 | 223 | ||
| 224 | + | ||
| 225 | + .. function:: uuid8(a=None, b=None, c=None) | ||
| 226 | + | ||
| 227 | + Generate a pseudo-random UUID according to | ||
| 228 | + :rfc:`RFC 9562, §5.8 <9562#section-5.8>`. | ||
| 229 | + | ||
| 230 | + When specified, the parameters *a*, *b* and *c* are expected to be | ||
| 231 | + positive integers of 48, 12 and 62 bits respectively. If they exceed | ||
| 232 | + their expected bit count, only their least significant bits are kept; | ||
| 233 | + non-specified arguments are substituted for a pseudo-random integer of | ||
| 234 | + appropriate size. | ||
| 235 | + | ||
| 236 | + .. versionadded:: next | ||
| 237 | + | ||
| 238 | + .. index:: single: uuid8 | ||
| 239 | + | ||
| 240 | + | ||
| 219 | 241 | The :mod:`uuid` module defines the following namespace identifiers for use with | |
| 220 | 242 | :func:`uuid3` or :func:`uuid5`. | |
| 221 | 243 | ||
@@ -252,7 +274,9 @@ of the :attr:`~UUID.variant` attribute: | |||
| 252 | 274 | ||
| 253 | 275 | .. data:: RFC_4122 | |
| 254 | 276 | ||
| 255 | - Specifies the UUID layout given in :rfc:`4122`. | ||
| 277 | + Specifies the UUID layout given in :rfc:`4122`. This constant is kept | ||
| 278 | + for backward compatibility even though :rfc:`4122` has been superseded | ||
| 279 | + by :rfc:`9562`. | ||
| 256 | 280 | ||
| 257 | 281 | ||
| 258 | 282 | .. data:: RESERVED_MICROSOFT | |
@@ -267,7 +291,7 @@ of the :attr:`~UUID.variant` attribute: | |||
| 267 | 291 | ||
| 268 | 292 | .. seealso:: | |
| 269 | 293 | ||
| 270 | - :rfc:`4122` - A Universally Unique IDentifier (UUID) URN Namespace | ||
| 294 | + :rfc:`9562` - A Universally Unique IDentifier (UUID) URN Namespace | ||
| 271 | 295 | This specification defines a Uniform Resource Name namespace for UUIDs, the | |
| 272 | 296 | internal format of UUIDs, and methods of generating UUIDs. | |
| 273 | 297 | ||
@@ -283,7 +307,7 @@ The :mod:`uuid` module can be executed as a script from the command line. | |||
| 283 | 307 | ||
| 284 | 308 | .. code-block:: sh | |
| 285 | 309 | ||
| 286 | - python -m uuid [-h] [-u {uuid1,uuid3,uuid4,uuid5}] [-n NAMESPACE] [-N NAME] | ||
| 310 | + python -m uuid [-h] [-u {uuid1,uuid3,uuid4,uuid5,uuid8}] [-n NAMESPACE] [-N NAME] | ||
| 287 | 311 | ||
| 288 | 312 | The following options are accepted: | |
| 289 | 313 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -517,6 +517,14 @@ unittest | |||
| 517 | 517 | (Contributed by Jacob Walls in :gh:`80958`.) | |
| 518 | 518 | ||
| 519 | 519 | ||
| 520 | + uuid | ||
| 521 | + ---- | ||
| 522 | + | ||
| 523 | + * Add support for UUID version 8 via :func:`uuid.uuid8` as specified | ||
| 524 | + in :rfc:`9562`. | ||
| 525 | + (Contributed by Bénédikt Tran in :gh:`89083`.) | ||
| 526 | + | ||
| 527 | + | ||
| 520 | 528 | .. Add improved modules above alphabetically, not here at the end. | |
| 521 | 529 | ||
| 522 | 530 | Optimizations | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,8 +8,10 @@ | |||
| 8 | 8 | import io | |
| 9 | 9 | import os | |
| 10 | 10 | import pickle | |
| 11 | + import random | ||
| 11 | 12 | import sys | |
| 12 | 13 | import weakref | |
| 14 | + from itertools import product | ||
| 13 | 15 | from unittest import mock | |
| 14 | 16 | ||
| 15 | 17 | py_uuid = import_helper.import_fresh_module('uuid', blocked=['_uuid']) | |
@@ -267,7 +269,7 @@ def test_exceptions(self): | |||
| 267 | 269 | ||
| 268 | 270 | # Version number out of range. | |
| 269 | 271 | badvalue(lambda: self.uuid.UUID('00'*16, version=0)) | |
| 270 | - badvalue(lambda: self.uuid.UUID('00'*16, version=6)) | ||
| 272 | + badvalue(lambda: self.uuid.UUID('00'*16, version=42)) | ||
| 271 | 273 | ||
| 272 | 274 | # Integer value out of range. | |
| 273 | 275 | badvalue(lambda: self.uuid.UUID(int=-1)) | |
@@ -681,6 +683,37 @@ def test_uuid5(self): | |||
| 681 | 683 | equal(u, self.uuid.UUID(v)) | |
| 682 | 684 | equal(str(u), v) | |
| 683 | 685 | ||
| 686 | + def test_uuid8(self): | ||
| 687 | + equal = self.assertEqual | ||
| 688 | + u = self.uuid.uuid8() | ||
| 689 | + | ||
| 690 | + equal(u.variant, self.uuid.RFC_4122) | ||
| 691 | + equal(u.version, 8) | ||
| 692 | + | ||
| 693 | + for (_, hi, mid, lo) in product( | ||
| 694 | + range(10), # repeat 10 times | ||
| 695 | + [None, 0, random.getrandbits(48)], | ||
| 696 | + [None, 0, random.getrandbits(12)], | ||
| 697 | + [None, 0, random.getrandbits(62)], | ||
| 698 | + ): | ||
| 699 | + u = self.uuid.uuid8(hi, mid, lo) | ||
| 700 | + equal(u.variant, self.uuid.RFC_4122) | ||
| 701 | + equal(u.version, 8) | ||
| 702 | + if hi is not None: | ||
| 703 | + equal((u.int >> 80) & 0xffffffffffff, hi) | ||
| 704 | + if mid is not None: | ||
| 705 | + equal((u.int >> 64) & 0xfff, mid) | ||
| 706 | + if lo is not None: | ||
| 707 | + equal(u.int & 0x3fffffffffffffff, lo) | ||
| 708 | + | ||
| 709 | + def test_uuid8_uniqueness(self): | ||
| 710 | + # Test that UUIDv8-generated values are unique | ||
| 711 | + # (up to a negligible probability of failure). | ||
| 712 | + u1 = self.uuid.uuid8() | ||
| 713 | + u2 = self.uuid.uuid8() | ||
| 714 | + self.assertNotEqual(u1.int, u2.int) | ||
| 715 | + self.assertEqual(u1.version, u2.version) | ||
| 716 | + | ||
| 684 | 717 | @support.requires_fork() | |
| 685 | 718 | def testIssue8621(self): | |
| 686 | 719 | # On at least some versions of OSX self.uuid.uuid4 generates | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,8 @@ | |||
| 1 | - r"""UUID objects (universally unique identifiers) according to RFC 4122. | ||
| 1 | + r"""UUID objects (universally unique identifiers) according to RFC 4122/9562. | ||
| 2 | 2 | ||
| 3 | 3 | This module provides immutable UUID objects (class UUID) and the functions | |
| 4 | - uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5 | ||
| 5 | - UUIDs as specified in RFC 4122. | ||
| 4 | + uuid1(), uuid3(), uuid4(), uuid5(), and uuid8() for generating version 1, 3, | ||
| 5 | + 4, 5, and 8 UUIDs as specified in RFC 4122/9562. | ||
| 6 | 6 | ||
| 7 | 7 | If all you want is a unique ID, you should probably call uuid1() or uuid4(). | |
| 8 | 8 | Note that uuid1() may compromise privacy since it creates a UUID containing | |
@@ -124,12 +124,12 @@ class UUID: | |||
| 124 | 124 | ||
| 125 | 125 | int the UUID as a 128-bit integer | |
| 126 | 126 | ||
| 127 | - urn the UUID as a URN as specified in RFC 4122 | ||
| 127 | + urn the UUID as a URN as specified in RFC 4122/9562 | ||
| 128 | 128 | ||
| 129 | 129 | variant the UUID variant (one of the constants RESERVED_NCS, | |
| 130 | 130 | RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) | |
| 131 | 131 | ||
| 132 | - version the UUID version number (1 through 5, meaningful only | ||
| 132 | + version the UUID version number (1 through 8, meaningful only | ||
| 133 | 133 | when the variant is RFC_4122) | |
| 134 | 134 | ||
| 135 | 135 | is_safe An enum indicating whether the UUID has been generated in | |
@@ -214,9 +214,9 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, | |||
| 214 | 214 | if not 0 <= int < 1<<128: | |
| 215 | 215 | raise ValueError('int is out of range (need a 128-bit value)') | |
| 216 | 216 | if version is not None: | |
| 217 | - if not 1 <= version <= 5: | ||
| 217 | + if not 1 <= version <= 8: | ||
| 218 | 218 | raise ValueError('illegal version number') | |
| 219 | - # Set the variant to RFC 4122. | ||
| 219 | + # Set the variant to RFC 4122/9562. | ||
| 220 | 220 | int &= ~(0xc000 << 48) | |
| 221 | 221 | int |= 0x8000 << 48 | |
| 222 | 222 | # Set the version number. | |
@@ -355,7 +355,7 @@ def variant(self): | |||
| 355 | 355 | ||
| 356 | 356 | @property | |
| 357 | 357 | def version(self): | |
| 358 | - # The version bits are only meaningful for RFC 4122 UUIDs. | ||
| 358 | + # The version bits are only meaningful for RFC 4122/9562 UUIDs. | ||
| 359 | 359 | if self.variant == RFC_4122: | |
| 360 | 360 | return int((self.int >> 76) & 0xf) | |
| 361 | 361 | ||
@@ -719,14 +719,37 @@ def uuid5(namespace, name): | |||
| 719 | 719 | hash = sha1(namespace.bytes + name).digest() | |
| 720 | 720 | return UUID(bytes=hash[:16], version=5) | |
| 721 | 721 | ||
| 722 | + def uuid8(a=None, b=None, c=None): | ||
| 723 | + """Generate a UUID from three custom blocks. | ||
| 724 | + | ||
| 725 | + * 'a' is the first 48-bit chunk of the UUID (octets 0-5); | ||
| 726 | + * 'b' is the mid 12-bit chunk (octets 6-7); | ||
| 727 | + * 'c' is the last 62-bit chunk (octets 8-15). | ||
| 728 | + | ||
| 729 | + When a value is not specified, a pseudo-random value is generated. | ||
| 730 | + """ | ||
| 731 | + if a is None: | ||
| 732 | + import random | ||
| 733 | + a = random.getrandbits(48) | ||
| 734 | + if b is None: | ||
| 735 | + import random | ||
| 736 | + b = random.getrandbits(12) | ||
| 737 | + if c is None: | ||
| 738 | + import random | ||
| 739 | + c = random.getrandbits(62) | ||
| 740 | + int_uuid_8 = (a & 0xffff_ffff_ffff) << 80 | ||
| 741 | + int_uuid_8 |= (b & 0xfff) << 64 | ||
| 742 | + int_uuid_8 |= c & 0x3fff_ffff_ffff_ffff | ||
| 743 | + return UUID(int=int_uuid_8, version=8) | ||
| 722 | 744 | ||
| 723 | 745 | def main(): | |
| 724 | 746 | """Run the uuid command line interface.""" | |
| 725 | 747 | uuid_funcs = { | |
| 726 | 748 | "uuid1": uuid1, | |
| 727 | 749 | "uuid3": uuid3, | |
| 728 | 750 | "uuid4": uuid4, | |
| 729 | - "uuid5": uuid5 | ||
| 751 | + "uuid5": uuid5, | ||
| 752 | + "uuid8": uuid8, | ||
| 730 | 753 | } | |
| 731 | 754 | uuid_namespace_funcs = ("uuid3", "uuid5") | |
| 732 | 755 | namespaces = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Add :func:`uuid.uuid8` for generating UUIDv8 objects as specified in | ||
| 2 | + :rfc:`9562`. Patch by Bénédikt Tran | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments