Skip to content

Commit ba11f45

Browse files
authored
gh-130843: expose 48-bit timestamp for UUIDv7 (#131838)
1 parent bab1398 commit ba11f45

File tree

3 files changed

+29
-12
lines changed

3 files changed

+29
-12
lines changed

Diff for: Doc/library/uuid.rst

+9-8
Original file line numberDiff line numberDiff line change
@@ -103,28 +103,29 @@ which relays any information about the UUID's safety, using this enumeration:
103103
- Meaning
104104

105105
* - .. attribute:: UUID.time_low
106-
- The first 32 bits of the UUID.
106+
- The first 32 bits of the UUID. Only relevant to version 1.
107107

108108
* - .. attribute:: UUID.time_mid
109-
- The next 16 bits of the UUID.
109+
- The next 16 bits of the UUID. Only relevant to version 1.
110110

111111
* - .. attribute:: UUID.time_hi_version
112-
- The next 16 bits of the UUID.
112+
- The next 16 bits of the UUID. Only relevant to version 1.
113113

114114
* - .. attribute:: UUID.clock_seq_hi_variant
115-
- The next 8 bits of the UUID.
115+
- The next 8 bits of the UUID. Only relevant to versions 1 and 6.
116116

117117
* - .. attribute:: UUID.clock_seq_low
118-
- The next 8 bits of the UUID.
118+
- The next 8 bits of the UUID. Only relevant to versions 1 and 6.
119119

120120
* - .. attribute:: UUID.node
121-
- The last 48 bits of the UUID.
121+
- The last 48 bits of the UUID. Only relevant to version 1.
122122

123123
* - .. attribute:: UUID.time
124-
- The 60-bit timestamp.
124+
- The 60-bit timestamp for version 1 and 6,
125+
or the 48-bit timestamp for version 7.
125126

126127
* - .. attribute:: UUID.clock_seq
127-
- The 14-bit sequence number.
128+
- The 14-bit sequence number. Only relevant to versions 1 and 6.
128129

129130

130131
.. attribute:: UUID.hex

Diff for: Lib/test/test_uuid.py

+5
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,7 @@ def test_uuid7(self):
913913
equal(self.uuid._last_counter_v7, counter)
914914

915915
unix_ts_ms = timestamp_ms & 0xffff_ffff_ffff
916+
equal(u.time, unix_ts_ms)
916917
equal((u.int >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
917918

918919
equal((u.int >> 75) & 1, 0) # check that the MSB is 0
@@ -966,6 +967,7 @@ def test_uuid7_monotonicity(self):
966967
urand.assert_called_once_with(10)
967968
equal(self.uuid._last_timestamp_v7, timestamp_ms)
968969
equal(self.uuid._last_counter_v7, counter)
970+
equal(u1.time, timestamp_ms)
969971
equal((u1.int >> 64) & 0xfff, counter_hi)
970972
equal((u1.int >> 32) & 0x3fff_ffff, counter_lo)
971973
equal(u1.int & 0xffff_ffff, tail)
@@ -988,6 +990,7 @@ def test_uuid7_monotonicity(self):
988990
equal(self.uuid._last_timestamp_v7, timestamp_ms)
989991
# 42-bit counter advanced by 1
990992
equal(self.uuid._last_counter_v7, counter + 1)
993+
equal(u2.time, timestamp_ms)
991994
equal((u2.int >> 64) & 0xfff, counter_hi)
992995
equal((u2.int >> 32) & 0x3fff_ffff, counter_lo + 1)
993996
equal(u2.int & 0xffff_ffff, next_fail)
@@ -1025,6 +1028,7 @@ def test_uuid7_timestamp_backwards(self):
10251028
equal(u.version, 7)
10261029
equal(self.uuid._last_timestamp_v7, fake_last_timestamp_v7 + 1)
10271030
unix_ts_ms = (fake_last_timestamp_v7 + 1) & 0xffff_ffff_ffff
1031+
equal(u.time, unix_ts_ms)
10281032
equal((u.int >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
10291033
# 42-bit counter advanced by 1
10301034
equal(self.uuid._last_counter_v7, counter + 1)
@@ -1064,6 +1068,7 @@ def test_uuid7_overflow_counter(self):
10641068
# timestamp advanced due to overflow
10651069
equal(self.uuid._last_timestamp_v7, timestamp_ms + 1)
10661070
unix_ts_ms = (timestamp_ms + 1) & 0xffff_ffff_ffff
1071+
equal(u.time, unix_ts_ms)
10671072
equal((u.int >> 80) & 0xffff_ffff_ffff, unix_ts_ms)
10681073
# counter overflowed, so we picked a new one
10691074
equal(self.uuid._last_counter_v7, new_counter)

Diff for: Lib/uuid.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,16 @@ class UUID:
134134
135135
fields a tuple of the six integer fields of the UUID,
136136
which are also available as six individual attributes
137-
and two derived attributes. The time_* attributes are
138-
only relevant to version 1, while the others are only
139-
relevant to versions 1 and 6:
137+
and two derived attributes. Those attributes are not
138+
always relevant to all UUID versions:
139+
140+
The 'time_*' attributes are only relevant to version 1.
141+
142+
The 'clock_seq*' and 'node' attributes are only relevant
143+
to versions 1 and 6.
144+
145+
The 'time' attribute is only relevant to versions 1, 6
146+
and 7.
140147
141148
time_low the first 32 bits of the UUID
142149
time_mid the next 16 bits of the UUID
@@ -145,7 +152,8 @@ class UUID:
145152
clock_seq_low the next 8 bits of the UUID
146153
node the last 48 bits of the UUID
147154
148-
time the 60-bit timestamp
155+
time the 60-bit timestamp for UUIDv1/v6,
156+
or the 48-bit timestamp for UUIDv7
149157
clock_seq the 14-bit sequence number
150158
151159
hex the UUID as a 32-character hexadecimal string
@@ -366,6 +374,9 @@ def time(self):
366374
time_hi = self.int >> 96
367375
time_lo = (self.int >> 64) & 0x0fff
368376
return time_hi << 28 | (self.time_mid << 12) | time_lo
377+
elif self.version == 7:
378+
# unix_ts_ms (48) | ... (80)
379+
return self.int >> 80
369380
else:
370381
# time_lo (32) | time_mid (16) | ver (4) | time_hi (12) | ... (64)
371382
#

0 commit comments

Comments
 (0)