From 50c6294fe3e79d48da792945f49c86206c93ea6d Mon Sep 17 00:00:00 2001
From: Nick Pope <nick@nickpope.me.uk>
Date: Thu, 2 Jan 2025 15:50:35 +0000
Subject: [PATCH 1/7] Add `uuid.NIL` and `uuid.MAX`

---
 Doc/library/uuid.rst                          | 25 +++++++++++++++++++
 Doc/whatsnew/3.14.rst                         |  4 +++
 Lib/test/test_uuid.py                         | 12 +++++++++
 Lib/uuid.py                                   | 13 ++++++++++
 Misc/ACKS                                     |  1 +
 ...-01-02-20-34-04.gh-issue-128427.onPoQZ.rst |  2 ++
 6 files changed, 57 insertions(+)
 create mode 100644 Misc/NEWS.d/next/Library/2025-01-02-20-34-04.gh-issue-128427.onPoQZ.rst

diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst
index 39e82d0e19a9ac..866ecaa1d19ea8 100644
--- a/Doc/library/uuid.rst
+++ b/Doc/library/uuid.rst
@@ -288,6 +288,24 @@ 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:: 3.14
+
+
+.. 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:: 3.14
+
 
 .. seealso::
 
@@ -380,6 +398,13 @@ 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:
 
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 61f5ffdb6c89d1..f0bf52f613920e 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -665,6 +665,10 @@ uuid
   in :rfc:`9562`.
   (Contributed by Bénédikt Tran in :gh:`89083`.)
 
+* :data:`uuid.NIL` and :data:`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
 -------
 
diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
index 7bd26a8ca34b62..71043966decbb3 100755
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -34,6 +34,18 @@ def get_command_stdout(command, args):
 class BaseTestUUID:
     uuid = None
 
+    def test_nil_uuid(self):
+        self.assertEqual(
+            self.uuid.NIL,
+            self.uuid.UUID('00000000-0000-0000-0000-000000000000'),
+        )
+
+    def test_max_uuid(self):
+        self.assertEqual(
+            self.uuid.MAX,
+            self.uuid.UUID('ffffffff-ffff-ffff-ffff-ffffffffffff'),
+        )
+
     def test_safe_uuid_enum(self):
         class CheckedSafeUUID(enum.Enum):
             safe = 0
diff --git a/Lib/uuid.py b/Lib/uuid.py
index 9c6ad9643cf6d5..aab1a66d49d88c 100644
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -42,6 +42,14 @@
     # 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
@@ -799,5 +807,10 @@ def main():
 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()
diff --git a/Misc/ACKS b/Misc/ACKS
index c6e53317b37d78..5a59fb74cd8817 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1473,6 +1473,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
index 00000000000000..7ed7b72518f589
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-01-02-20-34-04.gh-issue-128427.onPoQZ.rst
@@ -0,0 +1,2 @@
+:data:`uuid.NIL` and :data:`uuid.MAX` are now available to represent the Nil
+and Max UUID formats as defined by :rfc:`9562`.

From fc14200c6583e53c568e297b855290aca6f9f1a8 Mon Sep 17 00:00:00 2001
From: Nick Pope <nick@nickpope.me.uk>
Date: Fri, 3 Jan 2025 10:36:06 +0000
Subject: [PATCH 2/7] Edits to documentation

---
 Doc/library/uuid.rst                                       | 6 ++++--
 Doc/whatsnew/3.14.rst                                      | 7 ++++---
 .../Library/2025-01-02-20-34-04.gh-issue-128427.onPoQZ.rst | 2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst
index 866ecaa1d19ea8..09b4d4ac4ffd56 100644
--- a/Doc/library/uuid.rst
+++ b/Doc/library/uuid.rst
@@ -288,6 +288,7 @@ of the :attr:`~UUID.variant` attribute:
 
    Reserved for future definition.
 
+
 The :mod:`uuid` module defines the special Nil and Max UUID values:
 
 
@@ -296,7 +297,7 @@ The :mod:`uuid` module defines the special Nil and Max UUID values:
    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:: 3.14
+   .. versionadded:: next
 
 
 .. data:: MAX
@@ -304,7 +305,7 @@ The :mod:`uuid` module defines the special Nil and Max UUID values:
    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:: 3.14
+   .. versionadded:: next
 
 
 .. seealso::
@@ -406,6 +407,7 @@ Here are some examples of typical usage of the :mod:`uuid` module::
    >>> uuid.MAX
    UUID('ffffffff-ffff-ffff-ffff-ffffffffffff')
 
+
 .. _uuid-cli-example:
 
 Command-Line Example
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index f0bf52f613920e..e17b686a5c733b 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -665,9 +665,10 @@ uuid
   in :rfc:`9562`.
   (Contributed by Bénédikt Tran in :gh:`89083`.)
 
-* :data:`uuid.NIL` and :data:`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`.)
+* :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
 -------
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
index 7ed7b72518f589..54cae43702ded7 100644
--- 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
@@ -1,2 +1,2 @@
-:data:`uuid.NIL` and :data:`uuid.MAX` are now available to represent the Nil
+:const:`uuid.NIL` and :const:`uuid.MAX` are now available to represent the Nil
 and Max UUID formats as defined by :rfc:`9562`.

From 8b71df2e837afe582c4a74f6ecc3d9597d36f71e Mon Sep 17 00:00:00 2001
From: Nick Pope <nick@nickpope.me.uk>
Date: Fri, 3 Jan 2025 12:13:23 +0000
Subject: [PATCH 3/7] Edits to tests

---
 Lib/test/test_uuid.py | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
index 71043966decbb3..5c0da80e718334 100755
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -35,16 +35,24 @@ class BaseTestUUID:
     uuid = None
 
     def test_nil_uuid(self):
-        self.assertEqual(
-            self.uuid.NIL,
-            self.uuid.UUID('00000000-0000-0000-0000-000000000000'),
-        )
+        nil_uuid = self.uuid.NIL
+
+        s = '00000000-0000-0000-0000-000000000000'
+        i = 0x00000000000000000000000000000000
+        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)
 
     def test_max_uuid(self):
-        self.assertEqual(
-            self.uuid.MAX,
-            self.uuid.UUID('ffffffff-ffff-ffff-ffff-ffffffffffff'),
-        )
+        max_uuid = self.uuid.MAX
+
+        s = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
+        i = 0xffffffffffffffffffffffffffffffff
+        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)
 
     def test_safe_uuid_enum(self):
         class CheckedSafeUUID(enum.Enum):

From 2fde894bce08048e822a08c3a7a437afa887ea57 Mon Sep 17 00:00:00 2001
From: Nick Pope <nick@nickpope.me.uk>
Date: Mon, 6 Jan 2025 13:38:05 +0000
Subject: [PATCH 4/7] More tweaks to test assertions

---
 Lib/test/test_uuid.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
index 5c0da80e718334..ef9695f80db080 100755
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -38,21 +38,25 @@ def test_nil_uuid(self):
         nil_uuid = self.uuid.NIL
 
         s = '00000000-0000-0000-0000-000000000000'
-        i = 0x00000000000000000000000000000000
+        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)
+        self.assertIsNone(nil_uuid.version)
+        self.assertEqual(nil_uuid.variant, self.uuid.RESERVED_NCS)
 
     def test_max_uuid(self):
         max_uuid = self.uuid.MAX
 
         s = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
-        i = 0xffffffffffffffffffffffffffffffff
+        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)
+        self.assertIsNone(max_uuid.version)
+        self.assertEqual(max_uuid.variant, self.uuid.RESERVED_FUTURE)
 
     def test_safe_uuid_enum(self):
         class CheckedSafeUUID(enum.Enum):

From ecf263a1290b885b5dabf0964756381b06993e63 Mon Sep 17 00:00:00 2001
From: Nick Pope <nick@nickpope.me.uk>
Date: Mon, 6 Jan 2025 14:29:03 +0000
Subject: [PATCH 5/7] Add comments to test assertions

---
 Lib/test/test_uuid.py | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
index ef9695f80db080..5585545f3ed013 100755
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -43,8 +43,17 @@ def test_nil_uuid(self):
         self.assertEqual(nil_uuid, self.uuid.UUID(int=i))
         self.assertEqual(nil_uuid.int, i)
         self.assertEqual(str(nil_uuid), s)
-        self.assertIsNone(nil_uuid.version)
+        # 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#table1
+        # 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
@@ -55,8 +64,18 @@ def test_max_uuid(self):
         self.assertEqual(max_uuid, self.uuid.UUID(int=i))
         self.assertEqual(max_uuid.int, i)
         self.assertEqual(str(max_uuid), s)
-        self.assertIsNone(max_uuid.version)
+        # 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#table1
+        # 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):

From cba80bc6d2fa81a5f2b4b4893ab5c8f1addde305 Mon Sep 17 00:00:00 2001
From: Nick Pope <nick@nickpope.me.uk>
Date: Mon, 6 Jan 2025 20:34:24 +0000
Subject: [PATCH 6/7] Empty commit to retrigger CI


From bf61ffee10fd42fdd9981282968ca4c965bd8cb2 Mon Sep 17 00:00:00 2001
From: Nick Pope <nick@nickpope.me.uk>
Date: Tue, 7 Jan 2025 08:53:00 +0000
Subject: [PATCH 7/7] Remove extra links

---
 Lib/test/test_uuid.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
index 5585545f3ed013..49fae4e38d1231 100755
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -45,7 +45,6 @@ def test_nil_uuid(self):
         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#table1
         # 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
@@ -66,7 +65,6 @@ def test_max_uuid(self):
         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#table1
         # 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