]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-128427: Add `uuid.NIL` and `uuid.MAX` (#128429)
authorNick Pope <nick@nickpope.me.uk>
Mon, 27 Jan 2025 16:17:17 +0000 (16:17 +0000)
committerGitHub <noreply@github.com>
Mon, 27 Jan 2025 16:17:17 +0000 (18:17 +0200)
Doc/library/uuid.rst
Doc/whatsnew/3.14.rst
Lib/test/test_uuid.py
Lib/uuid.py
Misc/ACKS
Misc/NEWS.d/next/Library/2025-01-02-20-34-04.gh-issue-128427.onPoQZ.rst [new file with mode: 0644]

index 39e82d0e19a9ac28e387b7461bb5886a708eac7d..09b4d4ac4ffd5616b0037148eb7a3538fd387b2f 100644 (file)
@@ -289,6 +289,25 @@ of the :attr:`~UUID.variant` attribute:
    Reserved for future definition.
 
 
+The :mod:`uuid` module defines the special Nil and Max UUID values:
+
+
+.. data:: NIL
+
+   A special form of UUID that is specified to have all 128 bits set to zero
+   according to :rfc:`RFC 9562, §5.9 <9562#section-5.9>`.
+
+   .. versionadded:: next
+
+
+.. data:: MAX
+
+   A special form of UUID that is specified to have all 128 bits set to one
+   according to :rfc:`RFC 9562, §5.10 <9562#section-5.10>`.
+
+   .. versionadded:: next
+
+
 .. seealso::
 
    :rfc:`9562` - A Universally Unique IDentifier (UUID) URN Namespace
@@ -380,6 +399,14 @@ Here are some examples of typical usage of the :mod:`uuid` module::
    >>> uuid.UUID(bytes=x.bytes)
    UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
 
+   >>> # get the Nil UUID
+   >>> uuid.NIL
+   UUID('00000000-0000-0000-0000-000000000000')
+
+   >>> # get the Max UUID
+   >>> uuid.MAX
+   UUID('ffffffff-ffff-ffff-ffff-ffffffffffff')
+
 
 .. _uuid-cli-example:
 
index 53281441f691e5b4abf3fee44d04f5f8e67e0754..2c10d7fefd44ab598a46363925e1e28337d256a9 100644 (file)
@@ -731,6 +731,11 @@ uuid
   in :rfc:`9562`.
   (Contributed by Bénédikt Tran in :gh:`89083`.)
 
+* :const:`uuid.NIL` and :const:`uuid.MAX` are now available to represent the
+  Nil and Max UUID formats as defined by :rfc:`9562`.
+  (Contributed by Nick Pope in :gh:`128427`.)
+
+
 zipinfo
 -------
 
index 8f40dd97f42fdce91d859591df7e7f5f967ca0b1..74c8e2838efc8f1ab3e24ca53bc192682ea68674 100755 (executable)
@@ -34,6 +34,47 @@ def mock_get_command_stdout(data):
 class BaseTestUUID:
     uuid = None
 
+    def test_nil_uuid(self):
+        nil_uuid = self.uuid.NIL
+
+        s = '00000000-0000-0000-0000-000000000000'
+        i = 0
+        self.assertEqual(nil_uuid, self.uuid.UUID(s))
+        self.assertEqual(nil_uuid, self.uuid.UUID(int=i))
+        self.assertEqual(nil_uuid.int, i)
+        self.assertEqual(str(nil_uuid), s)
+        # The Nil UUID falls within the range of the Apollo NCS variant as per
+        # RFC 9562.
+        # See https://www.rfc-editor.org/rfc/rfc9562.html#section-5.9-4
+        self.assertEqual(nil_uuid.variant, self.uuid.RESERVED_NCS)
+        # A version field of all zeros is "Unused" in RFC 9562, but the version
+        # field also only applies to the 10xx variant, i.e. the variant
+        # specified in RFC 9562. As such, because the Nil UUID falls under a
+        # different variant, its version is considered undefined.
+        # See https://www.rfc-editor.org/rfc/rfc9562.html#table2
+        self.assertIsNone(nil_uuid.version)
+
+    def test_max_uuid(self):
+        max_uuid = self.uuid.MAX
+
+        s = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
+        i = (1 << 128) - 1
+        self.assertEqual(max_uuid, self.uuid.UUID(s))
+        self.assertEqual(max_uuid, self.uuid.UUID(int=i))
+        self.assertEqual(max_uuid.int, i)
+        self.assertEqual(str(max_uuid), s)
+        # The Max UUID falls within the range of the "yet-to-be defined" future
+        # UUID variant as per RFC 9562.
+        # See https://www.rfc-editor.org/rfc/rfc9562.html#section-5.10-4
+        self.assertEqual(max_uuid.variant, self.uuid.RESERVED_FUTURE)
+        # A version field of all ones is "Reserved for future definition" in
+        # RFC 9562, but the version field also only applies to the 10xx
+        # variant, i.e. the variant specified in RFC 9562. As such, because the
+        # Max UUID falls under a different variant, its version is considered
+        # undefined.
+        # See https://www.rfc-editor.org/rfc/rfc9562.html#table2
+        self.assertIsNone(max_uuid.version)
+
     def test_safe_uuid_enum(self):
         class CheckedSafeUUID(enum.Enum):
             safe = 0
index cd1f3530ab63e1919972d0fd6663d3c4b49a71c5..36809b85cb8ceb48ab6d4fb6b48f5a5d726cc52d 100644 (file)
@@ -42,6 +42,14 @@ Typical usage:
     # make a UUID from a 16-byte string
     >>> uuid.UUID(bytes=x.bytes)
     UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
+
+    # get the Nil UUID
+    >>> uuid.NIL
+    UUID('00000000-0000-0000-0000-000000000000')
+
+    # get the Max UUID
+    >>> uuid.MAX
+    UUID('ffffffff-ffff-ffff-ffff-ffffffffffff')
 """
 
 import os
@@ -830,5 +838,10 @@ NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
 NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
 NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')
 
+# RFC 9562 Sections 5.9 and 5.10 define the special Nil and Max UUID formats.
+
+NIL = UUID('00000000-0000-0000-0000-000000000000')
+MAX = UUID('ffffffff-ffff-ffff-ffff-ffffffffffff')
+
 if __name__ == "__main__":
     main()
index 7759bd0b95ed8beac9bdf812552e7ec401c993af..4901609a178bc33e767b7950c5fadc7c78773220 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1475,6 +1475,7 @@ Michael Pomraning
 Martin Pool
 Iustin Pop
 Claudiu Popa
+Nick Pope
 John Popplewell
 Matheus Vieira Portela
 Davin Potts
diff --git a/Misc/NEWS.d/next/Library/2025-01-02-20-34-04.gh-issue-128427.onPoQZ.rst b/Misc/NEWS.d/next/Library/2025-01-02-20-34-04.gh-issue-128427.onPoQZ.rst
new file mode 100644 (file)
index 0000000..54cae43
--- /dev/null
@@ -0,0 +1,2 @@
+:const:`uuid.NIL` and :const:`uuid.MAX` are now available to represent the Nil
+and Max UUID formats as defined by :rfc:`9562`.