diff options
author | Michael Felt <aixtools@users.noreply.github.com> | 2019-06-15 15:52:29 (GMT) |
---|---|---|
committer | Nick Coghlan <ncoghlan@gmail.com> | 2019-06-15 15:52:29 (GMT) |
commit | 3a1d50e7e573efb577714146bed5c03b9c95f466 (patch) | |
tree | cc30e69b8b2f3027fd524f4c71e25ff44871c7af /Lib/uuid.py | |
parent | 7a68f8c28bb78d957555a5001dac4df6345434a0 (diff) | |
download | cpython-3a1d50e7e573efb577714146bed5c03b9c95f466.zip cpython-3a1d50e7e573efb577714146bed5c03b9c95f466.tar.gz cpython-3a1d50e7e573efb577714146bed5c03b9c95f466.tar.bz2 |
bpo-28009: Fix uuid SkipUnless logic to be based on platform programs capable of introspection (GH-12777)
uuid could try fallback methods that had no chance of working on a particular
platform, and this could cause spurious test failures, as well as degraded
performance as fallback options were tried and failed.
This fixes both the uuid module and its test's SkipUnless logic to use a
prefiltered list of techniques that may at least potentially work on that platform.
Patch by Michael Felt (aixtools).
Diffstat (limited to 'Lib/uuid.py')
-rw-r--r-- | Lib/uuid.py | 43 |
1 files changed, 32 insertions, 11 deletions
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: |