Skip to content

Instantly share code, notes, and snippets.

@staciax
Last active April 21, 2024 15:59
Show Gist options
  • Save staciax/a550d5d81ec901298aa48c9791464e4b to your computer and use it in GitHub Desktop.
Save staciax/a550d5d81ec901298aa48c9791464e4b to your computer and use it in GitHub Desktop.
Python uuid v7
# https://github.com/python/cpython/pull/29824
import uuid
class UUID(uuid.UUID):
def __init__(
self,
int: int | None = None,
version: int | None = None,
*,
is_safe: uuid.SafeUUID = uuid.SafeUUID.unknown,
) -> None:
if int is not None:
if not 0 <= int < 1 << 128:
raise ValueError('int is out of range (need a 128-bit value)')
if version is not None:
if not 1 <= version <= 7:
raise ValueError('illegal version number')
# Set the variant to RFC 4122.
int &= ~(0xC000 << 48) # type: ignore
int |= 0x8000 << 48 # type: ignore
# Set the version number.
int &= ~(0xF000 << 64) # type: ignore
int |= version << 76 # type: ignore
object.__setattr__(self, 'int', int)
object.__setattr__(self, 'is_safe', is_safe)
_last_v7_timestamp = None
def uuid7():
"""The UUIDv7 format is designed to encode a Unix timestamp with
arbitrary sub-second precision. The key property provided by UUIDv7
is that timestamp values generated by one system and parsed by
another are guaranteed to have sub-second precision of either the
generator or the parser, whichever is less. Additionally, the system
parsing the UUIDv7 value does not need to know which precision was
used during encoding in order to function correctly."""
global _last_v7_timestamp
import random
import time
nanoseconds = time.time_ns()
if _last_v7_timestamp is not None and nanoseconds <= _last_v7_timestamp:
nanoseconds = _last_v7_timestamp + 1
_last_v7_timestamp = nanoseconds
timestamp_s, timestamp_ns = divmod(nanoseconds, 10**9)
subsec_a = timestamp_ns >> 18
subsec_b = (timestamp_ns >> 6) & 0x0FFF
subsec_seq_node = (timestamp_ns & 0x3F) << 56
subsec_seq_node += random.SystemRandom().getrandbits(56)
uuid_int = (timestamp_s & 0x0FFFFFFFFF) << 92
uuid_int += subsec_a << 80
uuid_int += subsec_b << 64
uuid_int += subsec_seq_node
return UUID(int=uuid_int, version=7)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment