diff -r 6e8f42fa4a86 Lib/test/test_uuid.py --- a/Lib/test/test_uuid.py Tue Oct 14 23:03:13 2014 +0200 +++ b/Lib/test/test_uuid.py Wed Oct 15 09:16:49 2014 +0200 @@ -1,9 +1,10 @@ -import unittest +import unittest.mock from test import support import builtins import io import os import shutil +import subprocess import uuid def importable(name): @@ -361,28 +362,26 @@ class TestUUID(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', 'requires Posix') def test_find_mac(self): - data = '''\ - + 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) - if shutil.which('ifconfig') is None: - path = os.pathsep.join(('/sbin', '/usr/sbin')) - if shutil.which('ifconfig', path=path) is None: - self.skipTest('requires ifconfig') + popen = unittest.mock.MagicMock() + popen.stdout = io.BytesIO(data.encode()) - 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) + with unittest.mock.patch.object(shutil, 'which', + return_value='/sbin/ifconfig'): + with unittest.mock.patch.object(subprocess, 'Popen', + return_value=popen): + mac = uuid._find_mac( + command='ifconfig', + args='', + hw_identifiers=[b'hwaddr'], + get_index=lambda x: x + 1, + ) + self.assertEqual(mac, 0x1234567890ab) @unittest.skipUnless(importable('ctypes'), 'requires ctypes') def test_uuid1(self): diff -r 6e8f42fa4a86 Lib/uuid.py --- a/Lib/uuid.py Tue Oct 14 23:03:13 2014 +0200 +++ b/Lib/uuid.py Wed Oct 15 09:16:49 2014 +0200 @@ -305,7 +305,7 @@ class UUID(object): return int((self.int >> 76) & 0xf) def _find_mac(command, args, hw_identifiers, get_index): - import os, shutil + import os, shutil, subprocess executable = shutil.which(command) if executable is None: path = os.pathsep.join(('/sbin', '/usr/sbin')) @@ -314,18 +314,27 @@ def _find_mac(command, args, hw_identifi return None try: - # LC_ALL to ensure English output, 2>/dev/null to prevent output on - # stderr (Note: we don't have an example where the words we search for - # are actually localized, but in theory some system could do so.) - cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args) - with os.popen(cmd) as pipe: - for line in pipe: + # LC_ALL=C to ensure English output, stderr=DEVNULL to prevent output + # on stderr (Note: we don't have an example where the words we search + # for are actually localized, but in theory some system could do so.) + env = os.environ.copy() + env['LC_ALL'] = 'C' + if args: + cmd = [executable, args] + else: + cmd = [executable] + proc = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + env=env) + with proc: + for line in proc.stdout: 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) + words[get_index(i)].replace(b':', b''), 16) except (ValueError, IndexError): # Virtual interfaces, such as those provided by # VPNs, do not have a colon-delimited MAC address @@ -341,7 +350,7 @@ def _ifconfig_getnode(): # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes. for args in ('', '-a', '-av'): - mac = _find_mac('ifconfig', args, ['hwaddr', 'ether'], lambda i: i+1) + mac = _find_mac('ifconfig', args, [b'hwaddr', b'ether'], lambda i: i+1) if mac: return mac @@ -349,12 +358,12 @@ def _ifconfig_getnode(): ip_addr = socket.gethostbyname(socket.gethostname()) # Try getting the MAC addr from arp based on our IP address (Solaris). - mac = _find_mac('arp', '-an', [ip_addr], lambda i: -1) + mac = _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1) if mac: return mac # This might work on HP-UX. - mac = _find_mac('lanscan', '-ai', ['lan0'], lambda i: 0) + mac = _find_mac('lanscan', '-ai', [b'lan0'], lambda i: 0) if mac: return mac