summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_uuid.py20
-rw-r--r--Lib/uuid.py43
-rw-r--r--Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst3
3 files changed, 47 insertions, 19 deletions
diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
index 992ef0c..92642d2 100644
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -462,8 +462,7 @@ class BaseTestUUID:
with unittest.mock.patch.multiple(
self.uuid,
_node=None, # Ignore any cached node value.
- _NODE_GETTERS_WIN32=[too_large_getter],
- _NODE_GETTERS_UNIX=[too_large_getter],
+ _GETTERS=[too_large_getter],
):
node = self.uuid.getnode()
self.assertTrue(0 < node < (1 << 48), '%012x' % node)
@@ -673,7 +672,7 @@ class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
class BaseTestInternals:
- uuid = None
+ _uuid = py_uuid
@unittest.skipUnless(os.name == 'posix', 'requires Posix')
def test_find_mac(self):
@@ -708,27 +707,32 @@ eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
self.assertTrue(0 < node < (1 << 48),
"%s is not an RFC 4122 node ID" % hex)
- @unittest.skipUnless(os.name == 'posix', 'requires Posix')
+ @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS,
+ "ifconfig is not used for introspection on this platform")
def test_ifconfig_getnode(self):
node = self.uuid._ifconfig_getnode()
self.check_node(node, 'ifconfig')
- @unittest.skipUnless(os.name == 'posix', 'requires Posix')
+ @unittest.skipUnless(_uuid._ip_getnode in _uuid._GETTERS,
+ "ip is not used for introspection on this platform")
def test_ip_getnode(self):
node = self.uuid._ip_getnode()
self.check_node(node, 'ip')
- @unittest.skipUnless(os.name == 'posix', 'requires Posix')
+ @unittest.skipUnless(_uuid._arp_getnode in _uuid._GETTERS,
+ "arp is not used for introspection on this platform")
def test_arp_getnode(self):
node = self.uuid._arp_getnode()
self.check_node(node, 'arp')
- @unittest.skipUnless(os.name == 'posix', 'requires Posix')
+ @unittest.skipUnless(_uuid._lanscan_getnode in _uuid._GETTERS,
+ "lanscan is not used for introspection on this platform")
def test_lanscan_getnode(self):
node = self.uuid._lanscan_getnode()
self.check_node(node, 'lanscan')
- @unittest.skipUnless(os.name == 'posix', 'requires Posix')
+ @unittest.skipUnless(_uuid._netstat_getnode in _uuid._GETTERS,
+ "netstat is not used for introspection on this platform")
def test_netstat_getnode(self):
node = self.uuid._netstat_getnode()
self.check_node(node, 'netstat')
diff --git a/Lib/uuid.py b/Lib/uuid.py
index ddc63cc..7aa01bb 100644
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -45,6 +45,7 @@ Typical usage:
"""
import os
+import platform
import sys
from enum import Enum
@@ -52,6 +53,12 @@ from enum import Enum
__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
+# The recognized platforms - known behaviors
+_AIX = platform.system() == 'AIX'
+_DARWIN = platform.system() == 'Darwin'
+_LINUX = platform.system() == 'Linux'
+_WINDOWS = platform.system() == 'Windows'
+
RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
'reserved for NCS compatibility', 'specified in RFC 4122',
'reserved for Microsoft compatibility', 'reserved for future definition']
@@ -673,12 +680,31 @@ def _random_getnode():
return random.getrandbits(48) | (1 << 40)
-_node = None
-
-_NODE_GETTERS_WIN32 = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
+# _OS_GETTERS, when known, are targetted for a specific OS or platform.
+# The order is by 'common practice' on the specified platform.
+# Note: 'posix' and 'windows' _OS_GETTERS are prefixed by a dll/dlload() method
+# which, when successful, means none of these "external" methods are called.
+# _GETTERS is (also) used by test_uuid.py to SkipUnless(), e.g.,
+# @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, ...)
+if _LINUX:
+ _OS_GETTERS = [_ip_getnode, _ifconfig_getnode]
+elif _DARWIN:
+ _OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode]
+elif _WINDOWS:
+ _OS_GETTERS = [_netbios_getnode, _ipconfig_getnode]
+elif _AIX:
+ _OS_GETTERS = [_netstat_getnode]
+else:
+ _OS_GETTERS = [_ifconfig_getnode, _ip_getnode, _arp_getnode,
+ _netstat_getnode, _lanscan_getnode]
+if os.name == 'posix':
+ _GETTERS = [_unix_getnode] + _OS_GETTERS
+elif os.name == 'nt':
+ _GETTERS = [_windll_getnode] + _OS_GETTERS
+else:
+ _GETTERS = _OS_GETTERS
-_NODE_GETTERS_UNIX = [_unix_getnode, _ifconfig_getnode, _ip_getnode,
- _arp_getnode, _lanscan_getnode, _netstat_getnode]
+_node = None
def getnode(*, getters=None):
"""Get the hardware address as a 48-bit positive integer.
@@ -692,12 +718,7 @@ def getnode(*, getters=None):
if _node is not None:
return _node
- if sys.platform == 'win32':
- getters = _NODE_GETTERS_WIN32
- else:
- getters = _NODE_GETTERS_UNIX
-
- for getter in getters + [_random_getnode]:
+ for getter in _GETTERS + [_random_getnode]:
try:
_node = getter()
except:
diff --git a/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst b/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst
new file mode 100644
index 0000000..2336407
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst
@@ -0,0 +1,3 @@
+Modify the test_uuid logic to test when a program is available
+AND can be used to obtain a MACADDR as basis for an UUID.
+Patch by M. Felt