https://github.com/python/cpython/commit/ba11f45dd969dfb039dfb47270de4f8c6a03d241 commit: ba11f45dd969dfb039dfb47270de4f8c6a03d241 branch: main author: Bénédikt Tran <10796600+picn...@users.noreply.github.com> committer: picnixz <10796600+picn...@users.noreply.github.com> date: 2025-03-31T14:32:54+02:00 summary:
gh-130843: expose 48-bit timestamp for UUIDv7 (#131838) files: M Doc/library/uuid.rst M Lib/test/test_uuid.py M Lib/uuid.py diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index 1c46d7d40bbdfa..13c00d22ef0299 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 91210923991f8e..958be5408ce90a 100755 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -913,6 +913,7 @@ def test_uuid7(self): 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 @@ def test_uuid7_monotonicity(self): 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 @@ def test_uuid7_monotonicity(self): 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 @@ def test_uuid7_timestamp_backwards(self): 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 @@ def test_uuid7_overflow_counter(self): # 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 984981512d64a6..2c16c3f0f5a5b5 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 @@ def time(self): 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) # _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com