Skip to content

Commit 62067ae

Browse files
authored
Update uuid from 3.13.7 (RustPython#6155)
1 parent b7d9d7d commit 62067ae

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

Lib/test/test_uuid.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import unittest
22
from test import support
33
from test.support import import_helper
4+
from test.support.script_helper import assert_python_ok
45
import builtins
56
import contextlib
67
import copy
@@ -32,8 +33,7 @@ def get_command_stdout(command, args):
3233
class BaseTestUUID:
3334
uuid = None
3435

35-
# TODO: RUSTPYTHON
36-
@unittest.expectedFailure
36+
@unittest.expectedFailure # TODO: RUSTPYTHON
3737
def test_safe_uuid_enum(self):
3838
class CheckedSafeUUID(enum.Enum):
3939
safe = 0
@@ -775,10 +775,37 @@ def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self):
775775
class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase):
776776
uuid = py_uuid
777777

778+
778779
@unittest.skipUnless(c_uuid, 'requires the C _uuid module')
779780
class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
780781
uuid = c_uuid
781782

783+
def check_has_stable_libuuid_extractable_node(self):
784+
if not self.uuid._has_stable_extractable_node:
785+
self.skipTest("libuuid cannot deduce MAC address")
786+
787+
@unittest.skipUnless(os.name == 'posix', 'POSIX only')
788+
def test_unix_getnode_from_libuuid(self):
789+
self.check_has_stable_libuuid_extractable_node()
790+
script = 'import uuid; print(uuid._unix_getnode())'
791+
_, n_a, _ = assert_python_ok('-c', script)
792+
_, n_b, _ = assert_python_ok('-c', script)
793+
n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
794+
self.assertTrue(n_a.isdigit())
795+
self.assertTrue(n_b.isdigit())
796+
self.assertEqual(n_a, n_b)
797+
798+
@unittest.skipUnless(os.name == 'nt', 'Windows only')
799+
def test_windows_getnode_from_libuuid(self):
800+
self.check_has_stable_libuuid_extractable_node()
801+
script = 'import uuid; print(uuid._windll_getnode())'
802+
_, n_a, _ = assert_python_ok('-c', script)
803+
_, n_b, _ = assert_python_ok('-c', script)
804+
n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
805+
self.assertTrue(n_a.isdigit())
806+
self.assertTrue(n_b.isdigit())
807+
self.assertEqual(n_a, n_b)
808+
782809

783810
class BaseTestInternals:
784811
_uuid = py_uuid

Lib/uuid.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -572,39 +572,43 @@ def _netstat_getnode():
572572
try:
573573
import _uuid
574574
_generate_time_safe = getattr(_uuid, "generate_time_safe", None)
575+
_has_stable_extractable_node = getattr(_uuid, "has_stable_extractable_node", False)
575576
_UuidCreate = getattr(_uuid, "UuidCreate", None)
576577
except ImportError:
577578
_uuid = None
578579
_generate_time_safe = None
580+
_has_stable_extractable_node = False
579581
_UuidCreate = None
580582

581583

582584
def _unix_getnode():
583585
"""Get the hardware address on Unix using the _uuid extension module."""
584-
if _generate_time_safe:
586+
if _generate_time_safe and _has_stable_extractable_node:
585587
uuid_time, _ = _generate_time_safe()
586588
return UUID(bytes=uuid_time).node
587589

588590
def _windll_getnode():
589591
"""Get the hardware address on Windows using the _uuid extension module."""
590-
if _UuidCreate:
592+
if _UuidCreate and _has_stable_extractable_node:
591593
uuid_bytes = _UuidCreate()
592594
return UUID(bytes_le=uuid_bytes).node
593595

594596
def _random_getnode():
595597
"""Get a random node ID."""
596-
# RFC 4122, $4.1.6 says "For systems with no IEEE address, a randomly or
597-
# pseudo-randomly generated value may be used; see Section 4.5. The
598-
# multicast bit must be set in such addresses, in order that they will
599-
# never conflict with addresses obtained from network cards."
598+
# RFC 9562, §6.10-3 says that
599+
#
600+
# Implementations MAY elect to obtain a 48-bit cryptographic-quality
601+
# random number as per Section 6.9 to use as the Node ID. [...] [and]
602+
# implementations MUST set the least significant bit of the first octet
603+
# of the Node ID to 1. This bit is the unicast or multicast bit, which
604+
# will never be set in IEEE 802 addresses obtained from network cards.
600605
#
601606
# The "multicast bit" of a MAC address is defined to be "the least
602607
# significant bit of the first octet". This works out to be the 41st bit
603608
# counting from 1 being the least significant bit, or 1<<40.
604609
#
605610
# See https://en.wikipedia.org/w/index.php?title=MAC_address&oldid=1128764812#Universal_vs._local_(U/L_bit)
606-
import random
607-
return random.getrandbits(48) | (1 << 40)
611+
return int.from_bytes(os.urandom(6)) | (1 << 40)
608612

609613

610614
# _OS_GETTERS, when known, are targeted for a specific OS or platform.

stdlib/src/uuid.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ mod _uuid {
3030
fn has_uuid_generate_time_safe(_vm: &VirtualMachine) -> u32 {
3131
0
3232
}
33+
34+
#[pyattr(name = "has_stable_extractable_node")]
35+
const HAS_STABLE_EXTRACTABLE_NODE: bool = false;
3336
}

0 commit comments

Comments
 (0)