Llama-3.1-8B-DALv0.1
/
venv
/lib
/python3.12
/site-packages
/setuptools
/_distutils
/tests
/test_unixccompiler.py
"""Tests for distutils.unixccompiler.""" | |
import os | |
import sys | |
import unittest.mock as mock | |
from distutils import sysconfig | |
from distutils.compat import consolidate_linker_args | |
from distutils.errors import DistutilsPlatformError | |
from distutils.unixccompiler import UnixCCompiler | |
from distutils.util import _clear_cached_macosx_ver | |
import pytest | |
from . import support | |
from .compat.py38 import EnvironmentVarGuard | |
def save_values(monkeypatch): | |
monkeypatch.setattr(sys, 'platform', sys.platform) | |
monkeypatch.setattr(sysconfig, 'get_config_var', sysconfig.get_config_var) | |
monkeypatch.setattr(sysconfig, 'get_config_vars', sysconfig.get_config_vars) | |
def compiler_wrapper(request): | |
class CompilerWrapper(UnixCCompiler): | |
def rpath_foo(self): | |
return self.runtime_library_dir_option('/foo') | |
request.instance.cc = CompilerWrapper() | |
class TestUnixCCompiler(support.TempdirManager): | |
def test_runtime_libdir_option(self): # noqa: C901 | |
# Issue #5900; GitHub Issue #37 | |
# | |
# Ensure RUNPATH is added to extension modules with RPATH if | |
# GNU ld is used | |
# darwin | |
sys.platform = 'darwin' | |
darwin_ver_var = 'MACOSX_DEPLOYMENT_TARGET' | |
darwin_rpath_flag = '-Wl,-rpath,/foo' | |
darwin_lib_flag = '-L/foo' | |
# (macOS version from syscfg, macOS version from env var) -> flag | |
# Version value of None generates two tests: as None and as empty string | |
# Expected flag value of None means an mismatch exception is expected | |
darwin_test_cases = [ | |
((None, None), darwin_lib_flag), | |
((None, '11'), darwin_rpath_flag), | |
(('10', None), darwin_lib_flag), | |
(('10.3', None), darwin_lib_flag), | |
(('10.3.1', None), darwin_lib_flag), | |
(('10.5', None), darwin_rpath_flag), | |
(('10.5.1', None), darwin_rpath_flag), | |
(('10.3', '10.3'), darwin_lib_flag), | |
(('10.3', '10.5'), darwin_rpath_flag), | |
(('10.5', '10.3'), darwin_lib_flag), | |
(('10.5', '11'), darwin_rpath_flag), | |
(('10.4', '10'), None), | |
] | |
def make_darwin_gcv(syscfg_macosx_ver): | |
def gcv(var): | |
if var == darwin_ver_var: | |
return syscfg_macosx_ver | |
return "xxx" | |
return gcv | |
def do_darwin_test(syscfg_macosx_ver, env_macosx_ver, expected_flag): | |
env = os.environ | |
msg = f"macOS version = (sysconfig={syscfg_macosx_ver!r}, env={env_macosx_ver!r})" | |
# Save | |
old_gcv = sysconfig.get_config_var | |
old_env_macosx_ver = env.get(darwin_ver_var) | |
# Setup environment | |
_clear_cached_macosx_ver() | |
sysconfig.get_config_var = make_darwin_gcv(syscfg_macosx_ver) | |
if env_macosx_ver is not None: | |
env[darwin_ver_var] = env_macosx_ver | |
elif darwin_ver_var in env: | |
env.pop(darwin_ver_var) | |
# Run the test | |
if expected_flag is not None: | |
assert self.cc.rpath_foo() == expected_flag, msg | |
else: | |
with pytest.raises( | |
DistutilsPlatformError, match=darwin_ver_var + r' mismatch' | |
): | |
self.cc.rpath_foo() | |
# Restore | |
if old_env_macosx_ver is not None: | |
env[darwin_ver_var] = old_env_macosx_ver | |
elif darwin_ver_var in env: | |
env.pop(darwin_ver_var) | |
sysconfig.get_config_var = old_gcv | |
_clear_cached_macosx_ver() | |
for macosx_vers, expected_flag in darwin_test_cases: | |
syscfg_macosx_ver, env_macosx_ver = macosx_vers | |
do_darwin_test(syscfg_macosx_ver, env_macosx_ver, expected_flag) | |
# Bonus test cases with None interpreted as empty string | |
if syscfg_macosx_ver is None: | |
do_darwin_test("", env_macosx_ver, expected_flag) | |
if env_macosx_ver is None: | |
do_darwin_test(syscfg_macosx_ver, "", expected_flag) | |
if syscfg_macosx_ver is None and env_macosx_ver is None: | |
do_darwin_test("", "", expected_flag) | |
old_gcv = sysconfig.get_config_var | |
# hp-ux | |
sys.platform = 'hp-ux' | |
def gcv(v): | |
return 'xxx' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == ['+s', '-L/foo'] | |
def gcv(v): | |
return 'gcc' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == ['-Wl,+s', '-L/foo'] | |
def gcv(v): | |
return 'g++' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == ['-Wl,+s', '-L/foo'] | |
sysconfig.get_config_var = old_gcv | |
# GCC GNULD | |
sys.platform = 'bar' | |
def gcv(v): | |
if v == 'CC': | |
return 'gcc' | |
elif v == 'GNULD': | |
return 'yes' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == consolidate_linker_args([ | |
'-Wl,--enable-new-dtags', | |
'-Wl,-rpath,/foo', | |
]) | |
def gcv(v): | |
if v == 'CC': | |
return 'gcc -pthread -B /bar' | |
elif v == 'GNULD': | |
return 'yes' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == consolidate_linker_args([ | |
'-Wl,--enable-new-dtags', | |
'-Wl,-rpath,/foo', | |
]) | |
# GCC non-GNULD | |
sys.platform = 'bar' | |
def gcv(v): | |
if v == 'CC': | |
return 'gcc' | |
elif v == 'GNULD': | |
return 'no' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == '-Wl,-R/foo' | |
# GCC GNULD with fully qualified configuration prefix | |
# see #7617 | |
sys.platform = 'bar' | |
def gcv(v): | |
if v == 'CC': | |
return 'x86_64-pc-linux-gnu-gcc-4.4.2' | |
elif v == 'GNULD': | |
return 'yes' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == consolidate_linker_args([ | |
'-Wl,--enable-new-dtags', | |
'-Wl,-rpath,/foo', | |
]) | |
# non-GCC GNULD | |
sys.platform = 'bar' | |
def gcv(v): | |
if v == 'CC': | |
return 'cc' | |
elif v == 'GNULD': | |
return 'yes' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == consolidate_linker_args([ | |
'-Wl,--enable-new-dtags', | |
'-Wl,-rpath,/foo', | |
]) | |
# non-GCC non-GNULD | |
sys.platform = 'bar' | |
def gcv(v): | |
if v == 'CC': | |
return 'cc' | |
elif v == 'GNULD': | |
return 'no' | |
sysconfig.get_config_var = gcv | |
assert self.cc.rpath_foo() == '-Wl,-R/foo' | |
def test_cc_overrides_ldshared(self): | |
# Issue #18080: | |
# ensure that setting CC env variable also changes default linker | |
def gcv(v): | |
if v == 'LDSHARED': | |
return 'gcc-4.2 -bundle -undefined dynamic_lookup ' | |
return 'gcc-4.2' | |
def gcvs(*args, _orig=sysconfig.get_config_vars): | |
if args: | |
return list(map(sysconfig.get_config_var, args)) | |
return _orig() | |
sysconfig.get_config_var = gcv | |
sysconfig.get_config_vars = gcvs | |
with EnvironmentVarGuard() as env: | |
env['CC'] = 'my_cc' | |
del env['LDSHARED'] | |
sysconfig.customize_compiler(self.cc) | |
assert self.cc.linker_so[0] == 'my_cc' | |
def test_cc_overrides_ldshared_for_cxx_correctly(self): | |
""" | |
Ensure that setting CC env variable also changes default linker | |
correctly when building C++ extensions. | |
pypa/distutils#126 | |
""" | |
def gcv(v): | |
if v == 'LDSHARED': | |
return 'gcc-4.2 -bundle -undefined dynamic_lookup ' | |
elif v == 'LDCXXSHARED': | |
return 'g++-4.2 -bundle -undefined dynamic_lookup ' | |
elif v == 'CXX': | |
return 'g++-4.2' | |
elif v == 'CC': | |
return 'gcc-4.2' | |
return '' | |
def gcvs(*args, _orig=sysconfig.get_config_vars): | |
if args: | |
return list(map(sysconfig.get_config_var, args)) | |
return _orig() | |
sysconfig.get_config_var = gcv | |
sysconfig.get_config_vars = gcvs | |
with mock.patch.object( | |
self.cc, 'spawn', return_value=None | |
) as mock_spawn, mock.patch.object( | |
self.cc, '_need_link', return_value=True | |
), mock.patch.object( | |
self.cc, 'mkpath', return_value=None | |
), EnvironmentVarGuard() as env: | |
env['CC'] = 'ccache my_cc' | |
env['CXX'] = 'my_cxx' | |
del env['LDSHARED'] | |
sysconfig.customize_compiler(self.cc) | |
assert self.cc.linker_so[0:2] == ['ccache', 'my_cc'] | |
self.cc.link(None, [], 'a.out', target_lang='c++') | |
call_args = mock_spawn.call_args[0][0] | |
expected = ['my_cxx', '-bundle', '-undefined', 'dynamic_lookup'] | |
assert call_args[:4] == expected | |
def test_explicit_ldshared(self): | |
# Issue #18080: | |
# ensure that setting CC env variable does not change | |
# explicit LDSHARED setting for linker | |
def gcv(v): | |
if v == 'LDSHARED': | |
return 'gcc-4.2 -bundle -undefined dynamic_lookup ' | |
return 'gcc-4.2' | |
def gcvs(*args, _orig=sysconfig.get_config_vars): | |
if args: | |
return list(map(sysconfig.get_config_var, args)) | |
return _orig() | |
sysconfig.get_config_var = gcv | |
sysconfig.get_config_vars = gcvs | |
with EnvironmentVarGuard() as env: | |
env['CC'] = 'my_cc' | |
env['LDSHARED'] = 'my_ld -bundle -dynamic' | |
sysconfig.customize_compiler(self.cc) | |
assert self.cc.linker_so[0] == 'my_ld' | |
def test_has_function(self): | |
# Issue https://github.com/pypa/distutils/issues/64: | |
# ensure that setting output_dir does not raise | |
# FileNotFoundError: [Errno 2] No such file or directory: 'a.out' | |
self.cc.output_dir = 'scratch' | |
os.chdir(self.mkdtemp()) | |
self.cc.has_function('abort') | |
def test_find_library_file(self, monkeypatch): | |
compiler = UnixCCompiler() | |
compiler._library_root = lambda dir: dir | |
monkeypatch.setattr(os.path, 'exists', lambda d: 'existing' in d) | |
libname = 'libabc.dylib' if sys.platform != 'cygwin' else 'cygabc.dll' | |
dirs = ('/foo/bar/missing', '/foo/bar/existing') | |
assert ( | |
compiler.find_library_file(dirs, 'abc').replace('\\', '/') | |
== f'/foo/bar/existing/{libname}' | |
) | |
assert ( | |
compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/') | |
== f'/foo/bar/existing/{libname}' | |
) | |
monkeypatch.setattr( | |
os.path, | |
'exists', | |
lambda d: 'existing' in d and '.a' in d and '.dll.a' not in d, | |
) | |
assert ( | |
compiler.find_library_file(dirs, 'abc').replace('\\', '/') | |
== '/foo/bar/existing/libabc.a' | |
) | |
assert ( | |
compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/') | |
== '/foo/bar/existing/libabc.a' | |
) | |