gh-130843: expose 48-bit timestamp for UUIDv7 (#131838)

This commit is contained in:
Bénédikt Tran 2025-03-31 14:32:54 +02:00 committed by GitHub
parent bab1398a47
commit ba11f45dd9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 12 deletions

View file

@ -103,28 +103,29 @@ which relays any information about the UUID's safety, using this enumeration:
- Meaning - Meaning
* - .. attribute:: UUID.time_low * - .. 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 * - .. 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 * - .. 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 * - .. 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 * - .. 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 * - .. 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 * - .. 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 * - .. attribute:: UUID.clock_seq
- The 14-bit sequence number. - The 14-bit sequence number. Only relevant to versions 1 and 6.
.. attribute:: UUID.hex .. attribute:: UUID.hex

View file

@ -913,6 +913,7 @@ class BaseTestUUID:
equal(self.uuid._last_counter_v7, counter) equal(self.uuid._last_counter_v7, counter)
unix_ts_ms = timestamp_ms & 0xffff_ffff_ffff 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 >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
equal((u.int >> 75) & 1, 0) # check that the MSB is 0 equal((u.int >> 75) & 1, 0) # check that the MSB is 0
@ -966,6 +967,7 @@ class BaseTestUUID:
urand.assert_called_once_with(10) urand.assert_called_once_with(10)
equal(self.uuid._last_timestamp_v7, timestamp_ms) equal(self.uuid._last_timestamp_v7, timestamp_ms)
equal(self.uuid._last_counter_v7, counter) equal(self.uuid._last_counter_v7, counter)
equal(u1.time, timestamp_ms)
equal((u1.int >> 64) & 0xfff, counter_hi) equal((u1.int >> 64) & 0xfff, counter_hi)
equal((u1.int >> 32) & 0x3fff_ffff, counter_lo) equal((u1.int >> 32) & 0x3fff_ffff, counter_lo)
equal(u1.int & 0xffff_ffff, tail) equal(u1.int & 0xffff_ffff, tail)
@ -988,6 +990,7 @@ class BaseTestUUID:
equal(self.uuid._last_timestamp_v7, timestamp_ms) equal(self.uuid._last_timestamp_v7, timestamp_ms)
# 42-bit counter advanced by 1 # 42-bit counter advanced by 1
equal(self.uuid._last_counter_v7, counter + 1) equal(self.uuid._last_counter_v7, counter + 1)
equal(u2.time, timestamp_ms)
equal((u2.int >> 64) & 0xfff, counter_hi) equal((u2.int >> 64) & 0xfff, counter_hi)
equal((u2.int >> 32) & 0x3fff_ffff, counter_lo + 1) equal((u2.int >> 32) & 0x3fff_ffff, counter_lo + 1)
equal(u2.int & 0xffff_ffff, next_fail) equal(u2.int & 0xffff_ffff, next_fail)
@ -1025,6 +1028,7 @@ class BaseTestUUID:
equal(u.version, 7) equal(u.version, 7)
equal(self.uuid._last_timestamp_v7, fake_last_timestamp_v7 + 1) equal(self.uuid._last_timestamp_v7, fake_last_timestamp_v7 + 1)
unix_ts_ms = (fake_last_timestamp_v7 + 1) & 0xffff_ffff_ffff 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) equal((u.int >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
# 42-bit counter advanced by 1 # 42-bit counter advanced by 1
equal(self.uuid._last_counter_v7, counter + 1) equal(self.uuid._last_counter_v7, counter + 1)
@ -1064,6 +1068,7 @@ class BaseTestUUID:
# timestamp advanced due to overflow # timestamp advanced due to overflow
equal(self.uuid._last_timestamp_v7, timestamp_ms + 1) equal(self.uuid._last_timestamp_v7, timestamp_ms + 1)
unix_ts_ms = (timestamp_ms + 1) & 0xffff_ffff_ffff 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) equal((u.int >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
# counter overflowed, so we picked a new one # counter overflowed, so we picked a new one
equal(self.uuid._last_counter_v7, new_counter) equal(self.uuid._last_counter_v7, new_counter)

View file

@ -134,9 +134,16 @@ class UUID:
fields a tuple of the six integer fields of the UUID, fields a tuple of the six integer fields of the UUID,
which are also available as six individual attributes which are also available as six individual attributes
and two derived attributes. The time_* attributes are and two derived attributes. Those attributes are not
only relevant to version 1, while the others are only always relevant to all UUID versions:
relevant to versions 1 and 6:
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_low the first 32 bits of the UUID
time_mid the next 16 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 clock_seq_low the next 8 bits of the UUID
node the last 48 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 clock_seq the 14-bit sequence number
hex the UUID as a 32-character hexadecimal string hex the UUID as a 32-character hexadecimal string
@ -366,6 +374,9 @@ class UUID:
time_hi = self.int >> 96 time_hi = self.int >> 96
time_lo = (self.int >> 64) & 0x0fff time_lo = (self.int >> 64) & 0x0fff
return time_hi << 28 | (self.time_mid << 12) | time_lo return time_hi << 28 | (self.time_mid << 12) | time_lo
elif self.version == 7:
# unix_ts_ms (48) | ... (80)
return self.int >> 80
else: else:
# time_lo (32) | time_mid (16) | ver (4) | time_hi (12) | ... (64) # time_lo (32) | time_mid (16) | ver (4) | time_hi (12) | ... (64)
# #