Skip to content

Commit 7262622

Browse files
committed
gh-118993: Use OS-generated UUIDs for uuid.uuid1() on Windows
1 parent 5afbb60 commit 7262622

4 files changed

Lines changed: 32 additions & 10 deletions

File tree

Doc/library/uuid.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ The :mod:`!uuid` module defines the following functions:
201201
If *node* or *clock_seq* exceed their expected bit count,
202202
only their least significant bits are kept.
203203

204+
.. versionchanged:: next
205+
On Windows, when neither *node* nor *clock_seq* is given, the UUID is
206+
now generated by the system ``UuidCreateSequential()`` function and
207+
reported as safe by :attr:`UUID.is_safe`.
208+
204209

205210
.. function:: uuid3(namespace, name)
206211

Lib/test/test_uuid.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,17 @@ def test_uuid1_bogus_return_value(self):
636636
self.assertEqual(u.is_safe, self.uuid.SafeUUID.unknown)
637637
self.assertEqual(u.version, 1)
638638

639+
def test_uuid1_windows_safe(self):
640+
if self.uuid._UuidCreate is None:
641+
self.skipTest('requires _uuid.UuidCreate')
642+
u = self.uuid.uuid1()
643+
self.assertEqual(u.is_safe, self.uuid.SafeUUID.safe)
644+
self.assertEqual(u.version, 1)
645+
self.assertEqual(u.variant, self.uuid.RFC_4122)
646+
639647
def test_uuid1_time(self):
640648
with mock.patch.object(self.uuid, '_generate_time_safe', None), \
649+
mock.patch.object(self.uuid, '_UuidCreate', None), \
641650
mock.patch.object(self.uuid, '_last_timestamp', None), \
642651
mock.patch.object(self.uuid, 'getnode', return_value=93328246233727), \
643652
mock.patch('time.time_ns', return_value=1545052026752910643), \

Lib/uuid.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -729,16 +729,20 @@ def uuid1(node=None, clock_seq=None):
729729
address. If 'clock_seq' is given, it is used as the sequence number;
730730
otherwise a random 14-bit sequence number is chosen."""
731731

732-
# When the system provides a version-1 UUID generator, use it (but don't
733-
# use UuidCreate here because its UUIDs don't conform to RFC 4122).
734-
if _generate_time_safe is not None and node is clock_seq is None:
735-
uuid_time, safely_generated = _generate_time_safe()
736-
try:
737-
is_safe = SafeUUID(safely_generated)
738-
except ValueError:
739-
is_safe = SafeUUID.unknown
740-
# The version field is assumed to be handled by _generate_time_safe().
741-
return UUID(bytes=uuid_time, is_safe=is_safe)
732+
# When the system provides a version-1 UUID generator, use it.
733+
if node is clock_seq is None:
734+
if _generate_time_safe is not None:
735+
uuid_time, safely_generated = _generate_time_safe()
736+
try:
737+
is_safe = SafeUUID(safely_generated)
738+
except ValueError:
739+
is_safe = SafeUUID.unknown
740+
# The version field is assumed to be handled by
741+
# _generate_time_safe().
742+
return UUID(bytes=uuid_time, is_safe=is_safe)
743+
if _UuidCreate is not None:
744+
uuid_bytes = _UuidCreate()
745+
return UUID(bytes_le=uuid_bytes, is_safe=SafeUUID.safe)
742746

743747
global _last_timestamp
744748
nanoseconds = time.time_ns()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
On Windows, :func:`uuid.uuid1` now uses the system
2+
``UuidCreateSequential()`` function when neither *node* nor *clock_seq* is
3+
given, so concurrent processes no longer produce colliding UUIDs and the
4+
result is reported as safe by :attr:`uuid.UUID.is_safe`.

0 commit comments

Comments
 (0)