Skip to content

bpo-22807: Expose platform UUID generation safety information. #138

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

Merged
merged 12 commits into from
Feb 18, 2017

Conversation

warsaw
Copy link
Member

@warsaw warsaw commented Feb 16, 2017

Add an enum SafeUUID which describes whether the platform has generated a UUID in a safe manner (i.e. ensuring that no two processes can generate the same UUID). Also add UUID.is_safe attribute which relays the information from the underlying platform.

@@ -182,6 +196,7 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
int &= ~(0xf000 << 64)
int |= version << 76
self.__dict__['int'] = int
self.__dict__['is_safe'] = is_safe
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want to assert the type of is_safe ? There seem to extensive checking of the rest of the parameters.
Not that I imagine people creating UUID object in their own code, but is_safe feel also a lot like a Boolean.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure it's worth type checking is_safe. The other ones are checked to ensure sane, compliant UUIDs, but is_safe is just a flag with some extra information (which may or may not be helpful to an application). If someone wants to manually instantiate UUIDs with bogus is_safe flags, oh well.

Lib/uuid.py Outdated
@@ -104,7 +114,7 @@ class UUID(object):
"""

def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
int=None, version=None):
int=None, version=None, is_safe=SafeUUID.unknown):
Copy link
Contributor

Choose a reason for hiding this comment

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

I changed my mind on whether this should affect older versions of Python.

If so, you can also consider making it kwarg-only. As you are already using is as a kwarg. Not sure if that's useful, or worth it. It's may also be a question of taste, and leaving it as is seem perfectly fine.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the review! I did think about that, and it might indeed make sense, but it's a matter of style in this case, and I wasn't sure I wanted to introduce that to the API. But on thinking about it again now that you bring it up, I does make sense.

Copy link
Contributor

@Carreau Carreau left a comment

Choose a reason for hiding this comment

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

Thanks for the review!

My pleasure !

I did think about that, and it might indeed make sense, but it's a matter of style in this case, and I wasn't sure I wanted to introduce that to the API. But on thinking about it again now that you bring it up, I does make sense.

Happy to be of some use :-)

Copy link
Member

@orsenthil orsenthil left a comment

Choose a reason for hiding this comment

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

LGTM.

Copy link
Member

@berkerpeksag berkerpeksag left a comment

Choose a reason for hiding this comment

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

I just left some comments, but the PR looks good to me.

.. class:: UUID(hex=None, bytes=None, bytes_le=None, fields=None, int=None, version=None)
.. class:: SafeUUID

.. attribute:: SafeUUID.safe
Copy link
Member

Choose a reason for hiding this comment

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

I know this is the current style in uuid.rst, but it might be better use the following style in new documentation:

.. class:: SafeUUID

   .. versionadded:: 3.7

   .. attribute:: safe
      The UUID was generated by the platform in a multiprocessing-safe way.

   ...

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, that looks nice, thanks. The one problem is that SafeUUID still gets labeled as a class in the HTML. Okay, technically it is a class, but it would be nice to have an enum:: markup. I grep'd around in the source and couldn't find any such examples, so I don't know if we support that yet.

Copy link
Member

Choose a reason for hiding this comment

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

You're right. We don't have an enum directive now, but it should be easy to add one. You can add me to nosy list if you create an issue on bugs.p.o :)

@@ -340,6 +340,46 @@ def test_uuid1(self):
equal(((u.clock_seq_hi_variant & 0x3f) << 8) |
u.clock_seq_low, 0x3fff)

@unittest.skipUnless(importable('ctypes'), 'requires ctypes')
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: I'd flip the order of the decorators.

Copy link
Member Author

Choose a reason for hiding this comment

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

+1

# unknown (unless I suppose the platform is buggy).
self.assertNotEqual(u.is_safe, uuid.SafeUUID.unknown)

@unittest.skipUnless(importable('ctypes'), 'requires ctypes')
Copy link
Member

Choose a reason for hiding this comment

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

Just a suggestion: Using self.subTest() would make the following four tests much shorter and IMO easier to understand.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've played a bit with subTest() and I'm not entirely thrilled with it. AFAICT, subtests only print output when they fail, not when they succeed. In verbose mode, I'd want to see all 4 tests printed individually. (That's one of the things I'd like to eventually fix.) For now, I think I'll leave them as separate tests.


.. versionadded:: 3.7

.. class:: UUID(hex=None, bytes=None, bytes_le=None, fields=None, int=None, version=None, *, is_safe=SafeUUID.unknown)
Copy link
Member

Choose a reason for hiding this comment

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

Currently, the body of UUID() documentation briefly describes all its arguments so I think we can just copy is_safe documentation in Lib/uuid.py

Copy link
Member Author

Choose a reason for hiding this comment

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

+1

``local.getlocale(locale.LC_CTYPE)`` and
``locale.getpreferredencoding(False)`` may give different answers
in some cases (such as the ``en_IN`` locale).

``re.LOCALE`` uses the latter, so update the test case to match.
@serhiy-storchaka serhiy-storchaka added the type-feature A feature request or enhancement label Feb 18, 2017
@warsaw warsaw merged commit 8c130d7 into python:master Feb 18, 2017
@warsaw warsaw deleted the bpo-22807 branch February 18, 2017 20:46
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 22, 2017
Replace STACKLESS_PROPOSE(func) in do_call() and ext_do_call() by
STACKLESS_PROPOSE_ALL().
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2017
- Initialize variable 'len' in function unwrap_frame_arg().
- Assign to '*valid' in function slp_find_execname().
- Disable GCC warning -Waddress in macro TASKLET_SETVAL(task, val).
- Update Stackless/changelog.txt for issues python#138, python#140
akruis pushed a commit to akruis/cpython that referenced this pull request Jun 19, 2018
Replace STACKLESS_PROPOSE(func) in do_call() and ext_do_call() by
STACKLESS_PROPOSE_ALL().
(cherry picked from commit ae3d7a2)
akruis pushed a commit to akruis/cpython that referenced this pull request Jun 19, 2018
- Assign to '*valid' in function slp_find_execname().
- Disable GCC warning -Waddress in macro TASKLET_SETVAL(task, val).
- Update Stackless/changelog.txt for issues python#138, python#140

(cherry picked from commit 3461ccf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants