mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Update _osx_support from CPython 3.10.5
This commit is contained in:
1 parent
540a73fe61
commit
5afa6f76b2
2 files changed
+429
-361
No files matched your search
Vendored
+102
-30
@@ -52,7 +52,7 @@ def _find_executable(executable, path=None):
|
||||
return executable
|
||||
|
||||
|
||||
def _read_output(commandstring):
|
||||
def _read_output(commandstring, capture_stderr=False):
|
||||
"""Output from successful command execution or None"""
|
||||
# Similar to os.popen(commandstring, "r").read(),
|
||||
# but without actually using os.popen because that
|
||||
@@ -67,7 +67,10 @@ def _read_output(commandstring):
|
||||
os.getpid(),), "w+b")
|
||||
|
||||
with contextlib.closing(fp) as fp:
|
||||
cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name)
|
||||
if capture_stderr:
|
||||
cmd = "%s >'%s' 2>&1" % (commandstring, fp.name)
|
||||
else:
|
||||
cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name)
|
||||
return fp.read().decode('utf-8').strip() if not os.system(cmd) else None
|
||||
|
||||
|
||||
@@ -93,7 +96,7 @@ def _get_system_version():
|
||||
if _SYSTEM_VERSION is None:
|
||||
_SYSTEM_VERSION = ''
|
||||
try:
|
||||
f = open('/System/Library/CoreServices/SystemVersion.plist')
|
||||
f = open('/System/Library/CoreServices/SystemVersion.plist', encoding="utf-8")
|
||||
except OSError:
|
||||
# We're on a plain darwin box, fall back to the default
|
||||
# behaviour.
|
||||
@@ -110,6 +113,26 @@ def _get_system_version():
|
||||
|
||||
return _SYSTEM_VERSION
|
||||
|
||||
_SYSTEM_VERSION_TUPLE = None
|
||||
def _get_system_version_tuple():
|
||||
"""
|
||||
Return the macOS system version as a tuple
|
||||
|
||||
The return value is safe to use to compare
|
||||
two version numbers.
|
||||
"""
|
||||
global _SYSTEM_VERSION_TUPLE
|
||||
if _SYSTEM_VERSION_TUPLE is None:
|
||||
osx_version = _get_system_version()
|
||||
if osx_version:
|
||||
try:
|
||||
_SYSTEM_VERSION_TUPLE = tuple(int(i) for i in osx_version.split('.'))
|
||||
except ValueError:
|
||||
_SYSTEM_VERSION_TUPLE = ()
|
||||
|
||||
return _SYSTEM_VERSION_TUPLE
|
||||
|
||||
|
||||
def _remove_original_values(_config_vars):
|
||||
"""Remove original unmodified values for testing"""
|
||||
# This is needed for higher-level cross-platform tests of get_platform.
|
||||
@@ -125,6 +148,33 @@ def _save_modified_value(_config_vars, cv, newvalue):
|
||||
_config_vars[_INITPRE + cv] = oldvalue
|
||||
_config_vars[cv] = newvalue
|
||||
|
||||
|
||||
_cache_default_sysroot = None
|
||||
def _default_sysroot(cc):
|
||||
""" Returns the root of the default SDK for this system, or '/' """
|
||||
global _cache_default_sysroot
|
||||
|
||||
if _cache_default_sysroot is not None:
|
||||
return _cache_default_sysroot
|
||||
|
||||
contents = _read_output('%s -c -E -v - </dev/null' % (cc,), True)
|
||||
in_incdirs = False
|
||||
for line in contents.splitlines():
|
||||
if line.startswith("#include <...>"):
|
||||
in_incdirs = True
|
||||
elif line.startswith("End of search list"):
|
||||
in_incdirs = False
|
||||
elif in_incdirs:
|
||||
line = line.strip()
|
||||
if line == '/usr/include':
|
||||
_cache_default_sysroot = '/'
|
||||
elif line.endswith(".sdk/usr/include"):
|
||||
_cache_default_sysroot = line[:-12]
|
||||
if _cache_default_sysroot is None:
|
||||
_cache_default_sysroot = '/'
|
||||
|
||||
return _cache_default_sysroot
|
||||
|
||||
def _supports_universal_builds():
|
||||
"""Returns True if universal builds are supported on this system"""
|
||||
# As an approximation, we assume that if we are running on 10.4 or above,
|
||||
@@ -132,14 +182,18 @@ def _supports_universal_builds():
|
||||
# builds, in particular -isysroot and -arch arguments to the compiler. This
|
||||
# is in support of allowing 10.4 universal builds to run on 10.3.x systems.
|
||||
|
||||
osx_version = _get_system_version()
|
||||
if osx_version:
|
||||
try:
|
||||
osx_version = tuple(int(i) for i in osx_version.split('.'))
|
||||
except ValueError:
|
||||
osx_version = ''
|
||||
osx_version = _get_system_version_tuple()
|
||||
return bool(osx_version >= (10, 4)) if osx_version else False
|
||||
|
||||
def _supports_arm64_builds():
|
||||
"""Returns True if arm64 builds are supported on this system"""
|
||||
# There are two sets of systems supporting macOS/arm64 builds:
|
||||
# 1. macOS 11 and later, unconditionally
|
||||
# 2. macOS 10.15 with Xcode 12.2 or later
|
||||
# For now the second category is ignored.
|
||||
osx_version = _get_system_version_tuple()
|
||||
return osx_version >= (11, 0) if osx_version else False
|
||||
|
||||
|
||||
def _find_appropriate_compiler(_config_vars):
|
||||
"""Find appropriate C compiler for extension module builds"""
|
||||
@@ -211,7 +265,7 @@ def _remove_universal_flags(_config_vars):
|
||||
if cv in _config_vars and cv not in os.environ:
|
||||
flags = _config_vars[cv]
|
||||
flags = re.sub(r'-arch\s+\w+\s', ' ', flags, flags=re.ASCII)
|
||||
flags = re.sub('-isysroot [^ \t]*', ' ', flags)
|
||||
flags = re.sub(r'-isysroot\s*\S+', ' ', flags)
|
||||
_save_modified_value(_config_vars, cv, flags)
|
||||
|
||||
return _config_vars
|
||||
@@ -287,7 +341,7 @@ def _check_for_unavailable_sdk(_config_vars):
|
||||
# to /usr and /System/Library by either a standalone CLT
|
||||
# package or the CLT component within Xcode.
|
||||
cflags = _config_vars.get('CFLAGS', '')
|
||||
m = re.search(r'-isysroot\s+(\S+)', cflags)
|
||||
m = re.search(r'-isysroot\s*(\S+)', cflags)
|
||||
if m is not None:
|
||||
sdk = m.group(1)
|
||||
if not os.path.exists(sdk):
|
||||
@@ -295,7 +349,7 @@ def _check_for_unavailable_sdk(_config_vars):
|
||||
# Do not alter a config var explicitly overridden by env var
|
||||
if cv in _config_vars and cv not in os.environ:
|
||||
flags = _config_vars[cv]
|
||||
flags = re.sub(r'-isysroot\s+\S+(?:\s|$)', ' ', flags)
|
||||
flags = re.sub(r'-isysroot\s*\S+(?:\s|$)', ' ', flags)
|
||||
_save_modified_value(_config_vars, cv, flags)
|
||||
|
||||
return _config_vars
|
||||
@@ -320,7 +374,7 @@ def compiler_fixup(compiler_so, cc_args):
|
||||
stripArch = stripSysroot = True
|
||||
else:
|
||||
stripArch = '-arch' in cc_args
|
||||
stripSysroot = '-isysroot' in cc_args
|
||||
stripSysroot = any(arg for arg in cc_args if arg.startswith('-isysroot'))
|
||||
|
||||
if stripArch or 'ARCHFLAGS' in os.environ:
|
||||
while True:
|
||||
@@ -331,6 +385,12 @@ def compiler_fixup(compiler_so, cc_args):
|
||||
except ValueError:
|
||||
break
|
||||
|
||||
elif not _supports_arm64_builds():
|
||||
# Look for "-arch arm64" and drop that
|
||||
for idx in reversed(range(len(compiler_so))):
|
||||
if compiler_so[idx] == '-arch' and compiler_so[idx+1] == "arm64":
|
||||
del compiler_so[idx:idx+2]
|
||||
|
||||
if 'ARCHFLAGS' in os.environ and not stripArch:
|
||||
# User specified different -arch flags in the environ,
|
||||
# see also distutils.sysconfig
|
||||
@@ -338,29 +398,39 @@ def compiler_fixup(compiler_so, cc_args):
|
||||
|
||||
if stripSysroot:
|
||||
while True:
|
||||
try:
|
||||
index = compiler_so.index('-isysroot')
|
||||
indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')]
|
||||
if not indices:
|
||||
break
|
||||
index = indices[0]
|
||||
if compiler_so[index] == '-isysroot':
|
||||
# Strip this argument and the next one:
|
||||
del compiler_so[index:index+2]
|
||||
except ValueError:
|
||||
break
|
||||
else:
|
||||
# It's '-isysroot/some/path' in one arg
|
||||
del compiler_so[index:index+1]
|
||||
|
||||
# Check if the SDK that is used during compilation actually exists,
|
||||
# the universal build requires the usage of a universal SDK and not all
|
||||
# users have that installed by default.
|
||||
sysroot = None
|
||||
if '-isysroot' in cc_args:
|
||||
idx = cc_args.index('-isysroot')
|
||||
sysroot = cc_args[idx+1]
|
||||
elif '-isysroot' in compiler_so:
|
||||
idx = compiler_so.index('-isysroot')
|
||||
sysroot = compiler_so[idx+1]
|
||||
argvar = cc_args
|
||||
indices = [i for i,x in enumerate(cc_args) if x.startswith('-isysroot')]
|
||||
if not indices:
|
||||
argvar = compiler_so
|
||||
indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')]
|
||||
|
||||
for idx in indices:
|
||||
if argvar[idx] == '-isysroot':
|
||||
sysroot = argvar[idx+1]
|
||||
break
|
||||
else:
|
||||
sysroot = argvar[idx][len('-isysroot'):]
|
||||
break
|
||||
|
||||
if sysroot and not os.path.isdir(sysroot):
|
||||
from distutils import log
|
||||
log.warn("Compiling with an SDK that doesn't seem to exist: %s",
|
||||
sysroot)
|
||||
log.warn("Please check your Xcode installation")
|
||||
sys.stderr.write(f"Compiling with an SDK that doesn't seem to exist: {sysroot}\n")
|
||||
sys.stderr.write("Please check your Xcode installation\n")
|
||||
sys.stderr.flush()
|
||||
|
||||
return compiler_so
|
||||
|
||||
@@ -411,7 +481,7 @@ def customize_compiler(_config_vars):
|
||||
|
||||
This customization is performed when the first
|
||||
extension module build is requested
|
||||
in distutils.sysconfig.customize_compiler).
|
||||
in distutils.sysconfig.customize_compiler.
|
||||
"""
|
||||
|
||||
# Find a compiler to use for extension module builds
|
||||
@@ -454,10 +524,10 @@ def get_platform_osx(_config_vars, osname, release, machine):
|
||||
try:
|
||||
macrelease = tuple(int(i) for i in macrelease.split('.')[0:2])
|
||||
except ValueError:
|
||||
macrelease = (10, 0)
|
||||
macrelease = (10, 3)
|
||||
else:
|
||||
# assume no universal support
|
||||
macrelease = (10, 0)
|
||||
macrelease = (10, 3)
|
||||
|
||||
if (macrelease >= (10, 4)) and '-arch' in cflags.strip():
|
||||
# The universal build will build fat binaries, but not on
|
||||
@@ -470,6 +540,8 @@ def get_platform_osx(_config_vars, osname, release, machine):
|
||||
|
||||
if len(archs) == 1:
|
||||
machine = archs[0]
|
||||
elif archs == ('arm64', 'x86_64'):
|
||||
machine = 'universal2'
|
||||
elif archs == ('i386', 'ppc'):
|
||||
machine = 'fat'
|
||||
elif archs == ('i386', 'x86_64'):
|
||||
|
||||
Vendored
+327
-331
@@ -1,331 +1,327 @@
|
||||
"""
|
||||
Test suite for _osx_support: shared OS X support functions.
|
||||
"""
|
||||
|
||||
import os
|
||||
import platform
|
||||
import stat
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from test.support import os_helper
|
||||
|
||||
import _osx_support
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X")
|
||||
class Test_OSXSupport(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.maxDiff = None
|
||||
self.prog_name = 'bogus_program_xxxx'
|
||||
self.temp_path_dir = os.path.abspath(os.getcwd())
|
||||
self.env = os_helper.EnvironmentVarGuard()
|
||||
self.addCleanup(self.env.__exit__)
|
||||
for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS',
|
||||
'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC',
|
||||
'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
|
||||
'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS'):
|
||||
if cv in self.env:
|
||||
self.env.unset(cv)
|
||||
|
||||
def add_expected_saved_initial_values(self, config_vars, expected_vars):
|
||||
# Ensure that the initial values for all modified config vars
|
||||
# are also saved with modified keys.
|
||||
expected_vars.update(('_OSX_SUPPORT_INITIAL_'+ k,
|
||||
config_vars[k]) for k in config_vars
|
||||
if config_vars[k] != expected_vars[k])
|
||||
|
||||
def test__find_executable(self):
|
||||
if self.env['PATH']:
|
||||
self.env['PATH'] = self.env['PATH'] + ':'
|
||||
self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
|
||||
os_helper.unlink(self.prog_name)
|
||||
self.assertIsNone(_osx_support._find_executable(self.prog_name))
|
||||
self.addCleanup(os_helper.unlink, self.prog_name)
|
||||
with open(self.prog_name, 'w') as f:
|
||||
f.write("#!/bin/sh\n/bin/echo OK\n")
|
||||
os.chmod(self.prog_name, stat.S_IRWXU)
|
||||
self.assertEqual(self.prog_name,
|
||||
_osx_support._find_executable(self.prog_name))
|
||||
|
||||
def test__read_output(self):
|
||||
if self.env['PATH']:
|
||||
self.env['PATH'] = self.env['PATH'] + ':'
|
||||
self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
|
||||
os_helper.unlink(self.prog_name)
|
||||
self.addCleanup(os_helper.unlink, self.prog_name)
|
||||
with open(self.prog_name, 'w') as f:
|
||||
f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n")
|
||||
os.chmod(self.prog_name, stat.S_IRWXU)
|
||||
self.assertEqual('ExpectedOutput',
|
||||
_osx_support._read_output(self.prog_name))
|
||||
|
||||
def test__find_build_tool(self):
|
||||
out = _osx_support._find_build_tool('cc')
|
||||
self.assertTrue(os.path.isfile(out),
|
||||
'cc not found - check xcode-select')
|
||||
|
||||
def test__get_system_version(self):
|
||||
self.assertTrue(platform.mac_ver()[0].startswith(
|
||||
_osx_support._get_system_version()))
|
||||
|
||||
def test__remove_original_values(self):
|
||||
config_vars = {
|
||||
'CC': 'gcc-test -pthreads',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang -pthreads',
|
||||
}
|
||||
cv = 'CC'
|
||||
newvalue = 'clang -pthreads'
|
||||
_osx_support._save_modified_value(config_vars, cv, newvalue)
|
||||
self.assertNotEqual(expected_vars, config_vars)
|
||||
_osx_support._remove_original_values(config_vars)
|
||||
self.assertEqual(expected_vars, config_vars)
|
||||
|
||||
def test__save_modified_value(self):
|
||||
config_vars = {
|
||||
'CC': 'gcc-test -pthreads',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang -pthreads',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
cv = 'CC'
|
||||
newvalue = 'clang -pthreads'
|
||||
_osx_support._save_modified_value(config_vars, cv, newvalue)
|
||||
self.assertEqual(expected_vars, config_vars)
|
||||
|
||||
def test__save_modified_value_unchanged(self):
|
||||
config_vars = {
|
||||
'CC': 'gcc-test -pthreads',
|
||||
}
|
||||
expected_vars = config_vars.copy()
|
||||
cv = 'CC'
|
||||
newvalue = 'gcc-test -pthreads'
|
||||
_osx_support._save_modified_value(config_vars, cv, newvalue)
|
||||
self.assertEqual(expected_vars, config_vars)
|
||||
|
||||
def test__supports_universal_builds(self):
|
||||
import platform
|
||||
mac_ver_tuple = tuple(int(i) for i in
|
||||
platform.mac_ver()[0].split('.')[0:2])
|
||||
self.assertEqual(mac_ver_tuple >= (10, 4),
|
||||
_osx_support._supports_universal_builds())
|
||||
|
||||
def test__find_appropriate_compiler(self):
|
||||
compilers = (
|
||||
('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'),
|
||||
('clang', 'clang version 3.1'),
|
||||
)
|
||||
config_vars = {
|
||||
'CC': 'gcc-test -pthreads',
|
||||
'CXX': 'cc++-test',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang -pthreads',
|
||||
'CXX': 'clang++',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'clang -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
|
||||
self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
|
||||
for c_name, c_output in compilers:
|
||||
os_helper.unlink(c_name)
|
||||
self.addCleanup(os_helper.unlink, c_name)
|
||||
with open(c_name, 'w') as f:
|
||||
f.write("#!/bin/sh\n/bin/echo " + c_output)
|
||||
os.chmod(c_name, stat.S_IRWXU)
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._find_appropriate_compiler(
|
||||
config_vars))
|
||||
|
||||
def test__remove_universal_flags(self):
|
||||
config_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 ',
|
||||
'LDFLAGS': ' -g',
|
||||
'CPPFLAGS': '-I. ',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._remove_universal_flags(
|
||||
config_vars))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test__remove_universal_flags_alternate(self):
|
||||
# bpo-38360: also test the alternate single-argument form of -isysroot
|
||||
config_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot/Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 ',
|
||||
'LDFLAGS': ' -g',
|
||||
'CPPFLAGS': '-I. ',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._remove_universal_flags(
|
||||
config_vars))
|
||||
|
||||
def test__remove_unsupported_archs(self):
|
||||
config_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch i386 ',
|
||||
'LDFLAGS': ' -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
|
||||
self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
|
||||
c_name = 'clang'
|
||||
os_helper.unlink(c_name)
|
||||
self.addCleanup(os_helper.unlink, c_name)
|
||||
# exit status 255 means no PPC support in this compiler chain
|
||||
with open(c_name, 'w') as f:
|
||||
f.write("#!/bin/sh\nexit 255")
|
||||
os.chmod(c_name, stat.S_IRWXU)
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._remove_unsupported_archs(
|
||||
config_vars))
|
||||
|
||||
def test__override_all_archs(self):
|
||||
self.env['ARCHFLAGS'] = '-arch x86_64'
|
||||
config_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch x86_64',
|
||||
'LDFLAGS': ' -g -arch x86_64',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -g -arch x86_64',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -isysroot '
|
||||
'/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._override_all_archs(
|
||||
config_vars))
|
||||
|
||||
def test__check_for_unavailable_sdk(self):
|
||||
config_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.1.sdk',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.1.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
' ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. ',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
' -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._check_for_unavailable_sdk(
|
||||
config_vars))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test__check_for_unavailable_sdk_alternate(self):
|
||||
# bpo-38360: also test the alternate single-argument form of -isysroot
|
||||
config_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
'-isysroot/Developer/SDKs/MacOSX10.1.sdk',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.1.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot/Developer/SDKs/MacOSX10.1.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
' ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. ',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
' -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._check_for_unavailable_sdk(
|
||||
config_vars))
|
||||
|
||||
def test_get_platform_osx(self):
|
||||
# Note, get_platform_osx is currently tested more extensively
|
||||
# indirectly by test_sysconfig and test_distutils
|
||||
config_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.1.sdk',
|
||||
'MACOSX_DEPLOYMENT_TARGET': '10.6',
|
||||
}
|
||||
result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ')
|
||||
self.assertEqual(('macosx', '10.6', 'fat'), result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
"""
|
||||
Test suite for _osx_support: shared OS X support functions.
|
||||
"""
|
||||
|
||||
import os
|
||||
import platform
|
||||
import stat
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from test.support import os_helper
|
||||
|
||||
import _osx_support
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X")
|
||||
class Test_OSXSupport(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.maxDiff = None
|
||||
self.prog_name = 'bogus_program_xxxx'
|
||||
self.temp_path_dir = os.path.abspath(os.getcwd())
|
||||
self.env = os_helper.EnvironmentVarGuard()
|
||||
self.addCleanup(self.env.__exit__)
|
||||
for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS',
|
||||
'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC',
|
||||
'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
|
||||
'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS'):
|
||||
if cv in self.env:
|
||||
self.env.unset(cv)
|
||||
|
||||
def add_expected_saved_initial_values(self, config_vars, expected_vars):
|
||||
# Ensure that the initial values for all modified config vars
|
||||
# are also saved with modified keys.
|
||||
expected_vars.update(('_OSX_SUPPORT_INITIAL_'+ k,
|
||||
config_vars[k]) for k in config_vars
|
||||
if config_vars[k] != expected_vars[k])
|
||||
|
||||
def test__find_executable(self):
|
||||
if self.env['PATH']:
|
||||
self.env['PATH'] = self.env['PATH'] + ':'
|
||||
self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
|
||||
os_helper.unlink(self.prog_name)
|
||||
self.assertIsNone(_osx_support._find_executable(self.prog_name))
|
||||
self.addCleanup(os_helper.unlink, self.prog_name)
|
||||
with open(self.prog_name, 'w') as f:
|
||||
f.write("#!/bin/sh\n/bin/echo OK\n")
|
||||
os.chmod(self.prog_name, stat.S_IRWXU)
|
||||
self.assertEqual(self.prog_name,
|
||||
_osx_support._find_executable(self.prog_name))
|
||||
|
||||
def test__read_output(self):
|
||||
if self.env['PATH']:
|
||||
self.env['PATH'] = self.env['PATH'] + ':'
|
||||
self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
|
||||
os_helper.unlink(self.prog_name)
|
||||
self.addCleanup(os_helper.unlink, self.prog_name)
|
||||
with open(self.prog_name, 'w') as f:
|
||||
f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n")
|
||||
os.chmod(self.prog_name, stat.S_IRWXU)
|
||||
self.assertEqual('ExpectedOutput',
|
||||
_osx_support._read_output(self.prog_name))
|
||||
|
||||
def test__find_build_tool(self):
|
||||
out = _osx_support._find_build_tool('cc')
|
||||
self.assertTrue(os.path.isfile(out),
|
||||
'cc not found - check xcode-select')
|
||||
|
||||
def test__get_system_version(self):
|
||||
self.assertTrue(platform.mac_ver()[0].startswith(
|
||||
_osx_support._get_system_version()))
|
||||
|
||||
def test__remove_original_values(self):
|
||||
config_vars = {
|
||||
'CC': 'gcc-test -pthreads',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang -pthreads',
|
||||
}
|
||||
cv = 'CC'
|
||||
newvalue = 'clang -pthreads'
|
||||
_osx_support._save_modified_value(config_vars, cv, newvalue)
|
||||
self.assertNotEqual(expected_vars, config_vars)
|
||||
_osx_support._remove_original_values(config_vars)
|
||||
self.assertEqual(expected_vars, config_vars)
|
||||
|
||||
def test__save_modified_value(self):
|
||||
config_vars = {
|
||||
'CC': 'gcc-test -pthreads',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang -pthreads',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
cv = 'CC'
|
||||
newvalue = 'clang -pthreads'
|
||||
_osx_support._save_modified_value(config_vars, cv, newvalue)
|
||||
self.assertEqual(expected_vars, config_vars)
|
||||
|
||||
def test__save_modified_value_unchanged(self):
|
||||
config_vars = {
|
||||
'CC': 'gcc-test -pthreads',
|
||||
}
|
||||
expected_vars = config_vars.copy()
|
||||
cv = 'CC'
|
||||
newvalue = 'gcc-test -pthreads'
|
||||
_osx_support._save_modified_value(config_vars, cv, newvalue)
|
||||
self.assertEqual(expected_vars, config_vars)
|
||||
|
||||
def test__supports_universal_builds(self):
|
||||
import platform
|
||||
mac_ver_tuple = tuple(int(i) for i in
|
||||
platform.mac_ver()[0].split('.')[0:2])
|
||||
self.assertEqual(mac_ver_tuple >= (10, 4),
|
||||
_osx_support._supports_universal_builds())
|
||||
|
||||
def test__find_appropriate_compiler(self):
|
||||
compilers = (
|
||||
('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'),
|
||||
('clang', 'clang version 3.1'),
|
||||
)
|
||||
config_vars = {
|
||||
'CC': 'gcc-test -pthreads',
|
||||
'CXX': 'cc++-test',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang -pthreads',
|
||||
'CXX': 'clang++',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'clang -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
|
||||
self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
|
||||
for c_name, c_output in compilers:
|
||||
os_helper.unlink(c_name)
|
||||
self.addCleanup(os_helper.unlink, c_name)
|
||||
with open(c_name, 'w') as f:
|
||||
f.write("#!/bin/sh\n/bin/echo " + c_output)
|
||||
os.chmod(c_name, stat.S_IRWXU)
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._find_appropriate_compiler(
|
||||
config_vars))
|
||||
|
||||
def test__remove_universal_flags(self):
|
||||
config_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 ',
|
||||
'LDFLAGS': ' -g',
|
||||
'CPPFLAGS': '-I. ',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._remove_universal_flags(
|
||||
config_vars))
|
||||
|
||||
def test__remove_universal_flags_alternate(self):
|
||||
# bpo-38360: also test the alternate single-argument form of -isysroot
|
||||
config_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot/Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 ',
|
||||
'LDFLAGS': ' -g',
|
||||
'CPPFLAGS': '-I. ',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._remove_universal_flags(
|
||||
config_vars))
|
||||
|
||||
def test__remove_unsupported_archs(self):
|
||||
config_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch i386 ',
|
||||
'LDFLAGS': ' -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
|
||||
self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
|
||||
c_name = 'clang'
|
||||
os_helper.unlink(c_name)
|
||||
self.addCleanup(os_helper.unlink, c_name)
|
||||
# exit status 255 means no PPC support in this compiler chain
|
||||
with open(c_name, 'w') as f:
|
||||
f.write("#!/bin/sh\nexit 255")
|
||||
os.chmod(c_name, stat.S_IRWXU)
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._remove_unsupported_archs(
|
||||
config_vars))
|
||||
|
||||
def test__override_all_archs(self):
|
||||
self.env['ARCHFLAGS'] = '-arch x86_64'
|
||||
config_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch x86_64',
|
||||
'LDFLAGS': ' -g -arch x86_64',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -g -arch x86_64',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -isysroot '
|
||||
'/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._override_all_archs(
|
||||
config_vars))
|
||||
|
||||
def test__check_for_unavailable_sdk(self):
|
||||
config_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.1.sdk',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.1.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
' ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. ',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
' -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._check_for_unavailable_sdk(
|
||||
config_vars))
|
||||
|
||||
def test__check_for_unavailable_sdk_alternate(self):
|
||||
# bpo-38360: also test the alternate single-argument form of -isysroot
|
||||
config_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
'-isysroot/Developer/SDKs/MacOSX10.1.sdk',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.1.sdk',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
'-isysroot/Developer/SDKs/MacOSX10.1.sdk -g',
|
||||
}
|
||||
expected_vars = {
|
||||
'CC': 'clang',
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
' ',
|
||||
'LDFLAGS': '-arch ppc -arch i386 -g',
|
||||
'CPPFLAGS': '-I. ',
|
||||
'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
|
||||
'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
|
||||
' -g',
|
||||
}
|
||||
self.add_expected_saved_initial_values(config_vars, expected_vars)
|
||||
|
||||
self.assertEqual(expected_vars,
|
||||
_osx_support._check_for_unavailable_sdk(
|
||||
config_vars))
|
||||
|
||||
def test_get_platform_osx(self):
|
||||
# Note, get_platform_osx is currently tested more extensively
|
||||
# indirectly by test_sysconfig and test_distutils
|
||||
config_vars = {
|
||||
'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
|
||||
'-isysroot /Developer/SDKs/MacOSX10.1.sdk',
|
||||
'MACOSX_DEPLOYMENT_TARGET': '10.6',
|
||||
}
|
||||
result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ')
|
||||
self.assertEqual(('macosx', '10.6', 'fat'), result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user