[Python-checkins] cpython (3.2): Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

georg.brandl python-checkins at python.org
Tue Sep 30 19:35:00 CEST 2014


https://hg.python.org/cpython/rev/f9cd915410d2
changeset:   92677:f9cd915410d2
branch:      3.2
parent:      92674:2802f5cd1384
user:        Georg Brandl <georg at python.org>
date:        Tue Sep 30 19:34:19 2014 +0200
summary:
  Issue #19855: uuid.getnode() on Unix now looks on the PATH for the
executables used to find the mac address, with /sbin and /usr/sbin as
fallbacks.

Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with
virtual interface.  Original patch by Kent Frazier.

Issue #18784: The uuid module no more attempts to load libc via ctypes.CDLL,
if all necessary functions are already found in libuuid.
Patch by Evgeny Sologubov.

Issue #16102: Make uuid._netbios_getnode() work again on Python 3.

files:
  Lib/test/test_uuid.py |  21 +++++++++++++
  Lib/uuid.py           |  47 ++++++++++++++++++++----------
  Misc/ACKS             |   2 +
  Misc/NEWS             |  13 ++++++++
  4 files changed, 67 insertions(+), 16 deletions(-)


diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
--- a/Lib/test/test_uuid.py
+++ b/Lib/test/test_uuid.py
@@ -1,6 +1,8 @@
 from unittest import TestCase
 from test import support
 import builtins
+import io
+import os
 import uuid
 
 def importable(name):
@@ -360,6 +362,25 @@
 
         self.assertEqual(node1, node2)
 
+    def test_find_mac(self):
+        data = '''\
+
+fake hwaddr
+cscotun0  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+eth0      Link encap:Ethernet  HWaddr 12:34:56:78:90:ab
+'''
+        def mock_popen(cmd):
+            return io.StringIO(data)
+
+        with support.swap_attr(os, 'popen', mock_popen):
+            mac = uuid._find_mac(
+                command='ifconfig',
+                args='',
+                hw_identifiers=['hwaddr'],
+                get_index=lambda x: x + 1,
+            )
+            self.assertEqual(mac, 0x1234567890ab)
+
     def test_uuid1(self):
         # uuid1 requires ctypes.
         try:
diff --git a/Lib/uuid.py b/Lib/uuid.py
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -313,25 +313,38 @@
 
 def _find_mac(command, args, hw_identifiers, get_index):
     import os
-    for dir in ['', '/sbin/', '/usr/sbin']:
+    path = os.environ.get("PATH", os.defpath).split(os.pathsep)
+    path.extend(('/sbin', '/usr/sbin'))
+    for dir in path:
         executable = os.path.join(dir, command)
-        if not os.path.exists(executable):
-            continue
+        if (os.path.exists(executable) and
+            os.access(executable, os.F_OK | os.X_OK) and
+            not os.path.isdir(executable)):
+            break
+    else:
+        return None
 
-        try:
-            # LC_ALL to get English output, 2>/dev/null to
-            # prevent output on stderr
-            cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
-            with os.popen(cmd) as pipe:
-                for line in pipe:
-                    words = line.lower().split()
-                    for i in range(len(words)):
-                        if words[i] in hw_identifiers:
+    try:
+        # LC_ALL to ensure English output, 2>/dev/null to
+        # prevent output on stderr
+        cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
+        with os.popen(cmd) as pipe:
+            for line in pipe:
+                words = line.lower().split()
+                for i in range(len(words)):
+                    if words[i] in hw_identifiers:
+                        try:
                             return int(
                                 words[get_index(i)].replace(':', ''), 16)
-        except IOError:
-            continue
-    return None
+                        except (ValueError, IndexError):
+                            # Virtual interfaces, such as those provided by
+                            # VPNs, do not have a colon-delimited MAC address
+                            # as expected, but a 16-byte HWAddr separated by
+                            # dashes. These should be ignored in favor of a
+                            # real MAC address
+                            pass
+    except IOError:
+        pass
 
 def _ifconfig_getnode():
     """Get the hardware address on Unix by running ifconfig."""
@@ -406,7 +419,7 @@
         if win32wnet.Netbios(ncb) != 0:
             continue
         status._unpack()
-        bytes = map(ord, status.adapter_address)
+        bytes = status.adapter_address
         return ((bytes[0]<<40) + (bytes[1]<<32) + (bytes[2]<<24) +
                 (bytes[3]<<16) + (bytes[4]<<8) + bytes[5])
 
@@ -429,6 +442,8 @@
             _uuid_generate_random = lib.uuid_generate_random
         if hasattr(lib, 'uuid_generate_time'):
             _uuid_generate_time = lib.uuid_generate_time
+            if _uuid_generate_random is not None:
+                break  # found everything we were looking for
 
     # The uuid_generate_* functions are broken on MacOS X 10.5, as noted
     # in issue #8621 the function generates the same sequence of values
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -353,6 +353,7 @@
 John Fouhy
 Stefan Franke
 Martin Franklin
+Kent Frazier
 Robin Friedrich
 Bradley Froehle
 Ivan Frohne
@@ -1028,6 +1029,7 @@
 Rafal Smotrzyk
 Dirk Soede
 Paul Sokolovsky
+Evgeny Sologubov
 Cody Somerville
 Clay Spence
 Stefan Sperling
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -47,6 +47,19 @@
   with non-standard cookie handling in some Web browsers.  Reported by
   Sergey Bobrov.
 
+- Issue #19855: uuid.getnode() on Unix now looks on the PATH for the
+  executables used to find the mac address, with /sbin and /usr/sbin as
+  fallbacks.
+
+- Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with
+  virtual interface.  Original patch by Kent Frazier.
+
+- Issue #18784: The uuid module no more attempts to load libc via ctypes.CDLL,
+  if all necessary functions are already found in libuuid.
+  Patch by Evgeny Sologubov.
+
+- Issue #16102: Make uuid._netbios_getnode() work again on Python 3.
+
 - Issue #21766: Prevent a security hole in CGIHTTPServer by URL unquoting paths
   before checking for a CGI script at that path.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list