summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>2025-03-31 12:32:54 (GMT)
committerGitHub <noreply@github.com>2025-03-31 12:32:54 (GMT)
commitba11f45dd969dfb039dfb47270de4f8c6a03d241 (patch)
treece94bd7282a6eff4ce5a1841983b1daeff97b7b8
parentbab1398a47f6d0cfc1be70497f306874c749ef7c (diff)
downloadcpython-ba11f45dd969dfb039dfb47270de4f8c6a03d241.zip
cpython-ba11f45dd969dfb039dfb47270de4f8c6a03d241.tar.gz
cpython-ba11f45dd969dfb039dfb47270de4f8c6a03d241.tar.bz2
gh-130843: expose 48-bit timestamp for UUIDv7 (#131838)
-rw-r--r--Doc/library/uuid.rst17
-rwxr-xr-xLib/test/test_uuid.py5
-rw-r--r--Lib/uuid.py19
3 files changed, 29 insertions, 12 deletions
diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst
index 1c46d7d..13c00d2 100644
--- a/Doc/library/uuid.rst
+++ b/Doc/library/uuid.rst
@@ -103,28 +103,29 @@ which relays any information about the UUID's safety, using this enumeration:
- Meaning
* - .. attribute:: UUID.time_low
- - The first 32 bits of the UUID.
+ - The first 32 bits of the UUID. Only relevant to version 1.
* - .. attribute:: UUID.time_mid
- - The next 16 bits of the UUID.
+ - The next 16 bits of the UUID. Only relevant to version 1.
* - .. attribute:: UUID.time_hi_version
- - The next 16 bits of the UUID.
+ - The next 16 bits of the UUID. Only relevant to version 1.
* - .. attribute:: UUID.clock_seq_hi_variant
- - The next 8 bits of the UUID.
+ - The next 8 bits of the UUID. Only relevant to versions 1 and 6.
* - .. attribute:: UUID.clock_seq_low
- - The next 8 bits of the UUID.
+ - The next 8 bits of the UUID. Only relevant to versions 1 and 6.
* - .. attribute:: UUID.node
- - The last 48 bits of the UUID.
+ - The last 48 bits of the UUID. Only relevant to version 1.
* - .. attribute:: UUID.time
- - The 60-bit timestamp.
+ - The 60-bit timestamp for version 1 and 6,
+ or the 48-bit timestamp for version 7.
* - .. attribute:: UUID.clock_seq
- - The 14-bit sequence number.
+ - The 14-bit sequence number. Only relevant to versions 1 and 6.
.. attribute:: UUID.hex
diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
index 9121092..958be54 100755
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -913,6 +913,7 @@ class BaseTestUUID:
equal(self.uuid._last_counter_v7, counter)
unix_ts_ms = timestamp_ms & 0xffff_ffff_ffff
+ equal(u.time, unix_ts_ms)
equal((u.int >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
equal((u.int >> 75) & 1, 0) # check that the MSB is 0
@@ -966,6 +967,7 @@ class BaseTestUUID:
urand.assert_called_once_with(10)
equal(self.uuid._last_timestamp_v7, timestamp_ms)
equal(self.uuid._last_counter_v7, counter)
+ equal(u1.time, timestamp_ms)
equal((u1.int >> 64) & 0xfff, counter_hi)
equal((u1.int >> 32) & 0x3fff_ffff, counter_lo)
equal(u1.int & 0xffff_ffff, tail)
@@ -988,6 +990,7 @@ class BaseTestUUID:
equal(self.uuid._last_timestamp_v7, timestamp_ms)
# 42-bit counter advanced by 1
equal(self.uuid._last_counter_v7, counter + 1)
+ equal(u2.time, timestamp_ms)
equal((u2.int >> 64) & 0xfff, counter_hi)
equal((u2.int >> 32) & 0x3fff_ffff, counter_lo + 1)
equal(u2.int & 0xffff_ffff, next_fail)
@@ -1025,6 +1028,7 @@ class BaseTestUUID:
equal(u.version, 7)
equal(self.uuid._last_timestamp_v7, fake_last_timestamp_v7 + 1)
unix_ts_ms = (fake_last_timestamp_v7 + 1) & 0xffff_ffff_ffff
+ equal(u.time, unix_ts_ms)
equal((u.int >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
# 42-bit counter advanced by 1
equal(self.uuid._last_counter_v7, counter + 1)
@@ -1064,6 +1068,7 @@ class BaseTestUUID:
# timestamp advanced due to overflow
equal(self.uuid._last_timestamp_v7, timestamp_ms + 1)
unix_ts_ms = (timestamp_ms + 1) & 0xffff_ffff_ffff
+ equal(u.time, unix_ts_ms)
equal((u.int >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
# counter overflowed, so we picked a new one
equal(self.uuid._last_counter_v7, new_counter)
diff --git a/Lib/uuid.py b/Lib/uuid.py
index 9849815..2c16c3f 100644
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -134,9 +134,16 @@ class UUID:
fields a tuple of the six integer fields of the UUID,
which are also available as six individual attributes
- and two derived attributes. The time_* attributes are
- only relevant to version 1, while the others are only
- relevant to versions 1 and 6:
+ and two derived attributes. Those attributes are not
+ always relevant to all UUID versions:
+
+ The 'time_*' attributes are only relevant to version 1.
+
+ The 'clock_seq*' and 'node' attributes are only relevant
+ to versions 1 and 6.
+
+ The 'time' attribute is only relevant to versions 1, 6
+ and 7.
time_low the first 32 bits of the UUID
time_mid the next 16 bits of the UUID
@@ -145,7 +152,8 @@ class UUID:
clock_seq_low the next 8 bits of the UUID
node the last 48 bits of the UUID
- time the 60-bit timestamp
+ time the 60-bit timestamp for UUIDv1/v6,
+ or the 48-bit timestamp for UUIDv7
clock_seq the 14-bit sequence number
hex the UUID as a 32-character hexadecimal string
@@ -366,6 +374,9 @@ class UUID:
time_hi = self.int >> 96
time_lo = (self.int >> 64) & 0x0fff
return time_hi << 28 | (self.time_mid << 12) | time_lo
+ elif self.version == 7:
+ # unix_ts_ms (48) | ... (80)
+ return self.int >> 80
else:
# time_lo (32) | time_mid (16) | ver (4) | time_hi (12) | ... (64)
#