Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-89083: add support for UUID version 7 (RFC 9562) #121119

Open
wants to merge 46 commits into
base: main
Choose a base branch
from

Conversation

picnixz
Copy link
Member

@picnixz picnixz commented Jun 28, 2024

Based on the discussion in #89083 and https://discuss.python.org/t/rfc-4122-9562-uuid-version-7-and-8-implementation/56725/2, this is the implementation that I suggest for the standard library.

The documentation is still missing because I don't have a good formulation for now.

In this PR, I did not include the following:

  • mutex guards
  • timestamp offsets

The reason is that I want to keep the first implementation simple for the sake of review. In addition, we did not give the add mutex for UUIDv1 so I don't want to do it only for v7.

@sergeyprokhorenko I don't know if you have the answer, but is there any safe guards if the timestamp overflows actually? or do we just don't care at all for now? (like, leave the problem for the future generations?)


📚 Documentation preview 📚: https://cpython-previews--121119.org.readthedocs.build/

@sergeyprokhorenko
Copy link

sergeyprokhorenko commented Jun 28, 2024

@sergeyprokhorenko I don't know if you have the answer, but is there any safe guards if the timestamp overflows actually? or do we just don't care at all for now? (like, leave the problem for the future generations?)

You already have three counter overflow protections:

  1. Very long counter (42 bits)
  2. Counter segment (MSB) initialized to 0
  3. Incremented timestamp on overflow

The timestamp will not be full for about 6900 years. If the system clock stops and the timestamp is used as a counter, it will also last a long time.

You can be absolutely calm

@picnixz
Copy link
Member Author

picnixz commented Jun 28, 2024

Yes, but I wanted to know whether the RFC actually considered the case when you use your own offset. Let's say we want to generate a future UUID for some obscure reason, I was wondering "is there anything on that topics?" But I think I'll just leave it to future generations.

What I meant is "what do you do if the operation of incrementing the timestamp itself overflows"?

@sergeyprokhorenko
Copy link

sergeyprokhorenko commented Jun 28, 2024

Yes, but I wanted to know whether the RFC actually considered the case when you use your own offset. Let's say we want to generate a future UUID for some obscure reason, I was wondering "is there anything on that topics?" But I think I'll just leave it to future generations.

What I meant is "what do you do if the operation of incrementing the timestamp itself overflows"?

Don't set offsets to 6900 years or minus 2k years, and everything will be OK. Foolproofing is an implementation detail.

@sergeyprokhorenko
Copy link

sergeyprokhorenko commented Jun 28, 2024

When the timestamp goes beyond the upper or lower limit of the acceptable range, a zero offset can be applied. This is how I would do it. The RFC does not cover this issue.

I think timestamp offset could be a competitive advantage of this implementation without significant cost.

UUIDv1 can be forgotten and no longer upgraded. This is an outdated version

@picnixz picnixz changed the title gh-89083: add ref. impl. for UUID version 7 (RFC 9562) gh-89083: add support for UUID version 7 (RFC 9562) Jun 28, 2024
Lib/uuid.py Outdated Show resolved Hide resolved
@pretoriusdre
Copy link

Great job on this PR. One thing...

In the get_counter_and_tail method:
rand = int.from_bytes(os.urandom(10))

Might I suggest to explicitly specify the required byteorder using the byteorder argument?

Running this code in an older python env gives an error:
TypeError: from_bytes() missing required argument 'byteorder' (pos 2)

It seems like some default is now provided, but in my opinion, this could lead to some ambiguity. See below:
https://discuss.python.org/t/what-should-be-the-default-value-for-int-to-bytes-byteorder/10616

There is another usage of int.from_bytes in the same uuid module, perhaps if the above is being addressed, this could be put within same scope.

@picnixz
Copy link
Member Author

picnixz commented Jul 22, 2024

Running this code in an older python env gives an error:

This feature would only be put in 3.14 or later, so we can ignore this.

but in my opinion, this could lead to some ambiguity

It doesn't matter whether it's little or big endian here since we are only interested in randomness and not actual data. In addition, not specifying it might be a bit faster since the C implementation currently does:

    if (byteorder == NULL)
        little_endian = 0;
    else if (_PyUnicode_Equal(byteorder, &_Py_ID(little)))
        little_endian = 1;
    else if (_PyUnicode_Equal(byteorder, &_Py_ID(big)))
        little_endian = 0;

So, not specifying the byteorder, is equivalent to have byteorder being NULL out there, which saves a string comparison.

Copy link

@jnoring-pw jnoring-pw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few minor comments as I looked through this code (I'm interested in uuid7 suport in our project). Thanks for this! It's looking good.

Lib/uuid.py Outdated Show resolved Hide resolved
Lib/uuid.py Show resolved Hide resolved
@picnixz picnixz changed the title gh-89083: add support for UUID version 7 (RFC 9562) gh-89083: add support for UUID version 7 (RFC 9562) Aug 22, 2024
@hugovk
Copy link
Member

hugovk commented Nov 2, 2024

(What's New conflict resolved)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants