8th day of python challenges 111-117

This commit is contained in:
abd.shallal
2019-08-04 15:26:35 +03:00
parent b04c1b055f
commit 627802c383
3215 changed files with 760227 additions and 491 deletions

View File

@@ -0,0 +1,220 @@
from __future__ import division, absolute_import, print_function
import os
import sys
from tempfile import TemporaryFile
from numpy.distutils import exec_command
from numpy.distutils.exec_command import get_pythonexe
from numpy.testing import tempdir, assert_, assert_warns
# In python 3 stdout, stderr are text (unicode compliant) devices, so to
# emulate them import StringIO from the io module.
if sys.version_info[0] >= 3:
from io import StringIO
else:
from StringIO import StringIO
class redirect_stdout(object):
"""Context manager to redirect stdout for exec_command test."""
def __init__(self, stdout=None):
self._stdout = stdout or sys.stdout
def __enter__(self):
self.old_stdout = sys.stdout
sys.stdout = self._stdout
def __exit__(self, exc_type, exc_value, traceback):
self._stdout.flush()
sys.stdout = self.old_stdout
# note: closing sys.stdout won't close it.
self._stdout.close()
class redirect_stderr(object):
"""Context manager to redirect stderr for exec_command test."""
def __init__(self, stderr=None):
self._stderr = stderr or sys.stderr
def __enter__(self):
self.old_stderr = sys.stderr
sys.stderr = self._stderr
def __exit__(self, exc_type, exc_value, traceback):
self._stderr.flush()
sys.stderr = self.old_stderr
# note: closing sys.stderr won't close it.
self._stderr.close()
class emulate_nonposix(object):
"""Context manager to emulate os.name != 'posix' """
def __init__(self, osname='non-posix'):
self._new_name = osname
def __enter__(self):
self._old_name = os.name
os.name = self._new_name
def __exit__(self, exc_type, exc_value, traceback):
os.name = self._old_name
def test_exec_command_stdout():
# Regression test for gh-2999 and gh-2915.
# There are several packages (nose, scipy.weave.inline, Sage inline
# Fortran) that replace stdout, in which case it doesn't have a fileno
# method. This is tested here, with a do-nothing command that fails if the
# presence of fileno() is assumed in exec_command.
# The code has a special case for posix systems, so if we are on posix test
# both that the special case works and that the generic code works.
# Test posix version:
with redirect_stdout(StringIO()):
with redirect_stderr(TemporaryFile()):
with assert_warns(DeprecationWarning):
exec_command.exec_command("cd '.'")
if os.name == 'posix':
# Test general (non-posix) version:
with emulate_nonposix():
with redirect_stdout(StringIO()):
with redirect_stderr(TemporaryFile()):
with assert_warns(DeprecationWarning):
exec_command.exec_command("cd '.'")
def test_exec_command_stderr():
# Test posix version:
with redirect_stdout(TemporaryFile(mode='w+')):
with redirect_stderr(StringIO()):
with assert_warns(DeprecationWarning):
exec_command.exec_command("cd '.'")
if os.name == 'posix':
# Test general (non-posix) version:
with emulate_nonposix():
with redirect_stdout(TemporaryFile()):
with redirect_stderr(StringIO()):
with assert_warns(DeprecationWarning):
exec_command.exec_command("cd '.'")
class TestExecCommand(object):
def setup(self):
self.pyexe = get_pythonexe()
def check_nt(self, **kws):
s, o = exec_command.exec_command('cmd /C echo path=%path%')
assert_(s == 0)
assert_(o != '')
s, o = exec_command.exec_command(
'"%s" -c "import sys;sys.stderr.write(sys.platform)"' % self.pyexe)
assert_(s == 0)
assert_(o == 'win32')
def check_posix(self, **kws):
s, o = exec_command.exec_command("echo Hello", **kws)
assert_(s == 0)
assert_(o == 'Hello')
s, o = exec_command.exec_command('echo $AAA', **kws)
assert_(s == 0)
assert_(o == '')
s, o = exec_command.exec_command('echo "$AAA"', AAA='Tere', **kws)
assert_(s == 0)
assert_(o == 'Tere')
s, o = exec_command.exec_command('echo "$AAA"', **kws)
assert_(s == 0)
assert_(o == '')
if 'BBB' not in os.environ:
os.environ['BBB'] = 'Hi'
s, o = exec_command.exec_command('echo "$BBB"', **kws)
assert_(s == 0)
assert_(o == 'Hi')
s, o = exec_command.exec_command('echo "$BBB"', BBB='Hey', **kws)
assert_(s == 0)
assert_(o == 'Hey')
s, o = exec_command.exec_command('echo "$BBB"', **kws)
assert_(s == 0)
assert_(o == 'Hi')
del os.environ['BBB']
s, o = exec_command.exec_command('echo "$BBB"', **kws)
assert_(s == 0)
assert_(o == '')
s, o = exec_command.exec_command('this_is_not_a_command', **kws)
assert_(s != 0)
assert_(o != '')
s, o = exec_command.exec_command('echo path=$PATH', **kws)
assert_(s == 0)
assert_(o != '')
s, o = exec_command.exec_command(
'"%s" -c "import sys,os;sys.stderr.write(os.name)"' %
self.pyexe, **kws)
assert_(s == 0)
assert_(o == 'posix')
def check_basic(self, *kws):
s, o = exec_command.exec_command(
'"%s" -c "raise \'Ignore me.\'"' % self.pyexe, **kws)
assert_(s != 0)
assert_(o != '')
s, o = exec_command.exec_command(
'"%s" -c "import sys;sys.stderr.write(\'0\');'
'sys.stderr.write(\'1\');sys.stderr.write(\'2\')"' %
self.pyexe, **kws)
assert_(s == 0)
assert_(o == '012')
s, o = exec_command.exec_command(
'"%s" -c "import sys;sys.exit(15)"' % self.pyexe, **kws)
assert_(s == 15)
assert_(o == '')
s, o = exec_command.exec_command(
'"%s" -c "print(\'Heipa\'")' % self.pyexe, **kws)
assert_(s == 0)
assert_(o == 'Heipa')
def check_execute_in(self, **kws):
with tempdir() as tmpdir:
fn = "file"
tmpfile = os.path.join(tmpdir, fn)
f = open(tmpfile, 'w')
f.write('Hello')
f.close()
s, o = exec_command.exec_command(
'"%s" -c "f = open(\'%s\', \'r\'); f.close()"' %
(self.pyexe, fn), **kws)
assert_(s != 0)
assert_(o != '')
s, o = exec_command.exec_command(
'"%s" -c "f = open(\'%s\', \'r\'); print(f.read()); '
'f.close()"' % (self.pyexe, fn), execute_in=tmpdir, **kws)
assert_(s == 0)
assert_(o == 'Hello')
def test_basic(self):
with redirect_stdout(StringIO()):
with redirect_stderr(StringIO()):
with assert_warns(DeprecationWarning):
if os.name == "posix":
self.check_posix(use_tee=0)
self.check_posix(use_tee=1)
elif os.name == "nt":
self.check_nt(use_tee=0)
self.check_nt(use_tee=1)
self.check_execute_in(use_tee=0)
self.check_execute_in(use_tee=1)

View File

@@ -0,0 +1,81 @@
from __future__ import division, absolute_import, print_function
import pytest
from numpy.testing import assert_, suppress_warnings
import numpy.distutils.fcompiler
customizable_flags = [
('f77', 'F77FLAGS'),
('f90', 'F90FLAGS'),
('free', 'FREEFLAGS'),
('arch', 'FARCH'),
('debug', 'FDEBUG'),
('flags', 'FFLAGS'),
('linker_so', 'LDFLAGS'),
]
def test_fcompiler_flags(monkeypatch):
monkeypatch.setenv('NPY_DISTUTILS_APPEND_FLAGS', '0')
fc = numpy.distutils.fcompiler.new_fcompiler(compiler='none')
flag_vars = fc.flag_vars.clone(lambda *args, **kwargs: None)
for opt, envvar in customizable_flags:
new_flag = '-dummy-{}-flag'.format(opt)
prev_flags = getattr(flag_vars, opt)
monkeypatch.setenv(envvar, new_flag)
new_flags = getattr(flag_vars, opt)
monkeypatch.delenv(envvar)
assert_(new_flags == [new_flag])
monkeypatch.setenv('NPY_DISTUTILS_APPEND_FLAGS', '1')
for opt, envvar in customizable_flags:
new_flag = '-dummy-{}-flag'.format(opt)
prev_flags = getattr(flag_vars, opt)
monkeypatch.setenv(envvar, new_flag)
new_flags = getattr(flag_vars, opt)
monkeypatch.delenv(envvar)
if prev_flags is None:
assert_(new_flags == [new_flag])
else:
assert_(new_flags == prev_flags + [new_flag])
def test_fcompiler_flags_append_warning(monkeypatch):
# Test to check that the warning for append behavior changing in future
# is triggered. Need to use a real compiler instance so that we have
# non-empty flags to start with (otherwise the "if var and append" check
# will always be false).
try:
with suppress_warnings() as sup:
sup.record()
fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95')
fc.customize()
except numpy.distutils.fcompiler.CompilerNotFound:
pytest.skip("gfortran not found, so can't execute this test")
# Ensure NPY_DISTUTILS_APPEND_FLAGS not defined
monkeypatch.delenv('NPY_DISTUTILS_APPEND_FLAGS', raising=False)
for opt, envvar in customizable_flags:
new_flag = '-dummy-{}-flag'.format(opt)
with suppress_warnings() as sup:
sup.record()
prev_flags = getattr(fc.flag_vars, opt)
monkeypatch.setenv(envvar, new_flag)
with suppress_warnings() as sup:
sup.record()
new_flags = getattr(fc.flag_vars, opt)
if prev_flags:
# Check that warning was issued
assert len(sup.log) == 1
monkeypatch.delenv(envvar)
assert_(new_flags == [new_flag])

View File

@@ -0,0 +1,57 @@
from __future__ import division, absolute_import, print_function
from numpy.testing import assert_
import numpy.distutils.fcompiler
g77_version_strings = [
('GNU Fortran 0.5.25 20010319 (prerelease)', '0.5.25'),
('GNU Fortran (GCC 3.2) 3.2 20020814 (release)', '3.2'),
('GNU Fortran (GCC) 3.3.3 20040110 (prerelease) (Debian)', '3.3.3'),
('GNU Fortran (GCC) 3.3.3 (Debian 20040401)', '3.3.3'),
('GNU Fortran (GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) 3.2.2'
' 20030222 (Red Hat Linux 3.2.2-5)', '3.2.2'),
]
gfortran_version_strings = [
('GNU Fortran 95 (GCC 4.0.3 20051023 (prerelease) (Debian 4.0.2-3))',
'4.0.3'),
('GNU Fortran 95 (GCC) 4.1.0', '4.1.0'),
('GNU Fortran 95 (GCC) 4.2.0 20060218 (experimental)', '4.2.0'),
('GNU Fortran (GCC) 4.3.0 20070316 (experimental)', '4.3.0'),
('GNU Fortran (rubenvb-4.8.0) 4.8.0', '4.8.0'),
('4.8.0', '4.8.0'),
('4.0.3-7', '4.0.3'),
("gfortran: warning: couldn't understand kern.osversion '14.1.0\n4.9.1",
'4.9.1'),
("gfortran: warning: couldn't understand kern.osversion '14.1.0\n"
"gfortran: warning: yet another warning\n4.9.1",
'4.9.1'),
('GNU Fortran (crosstool-NG 8a21ab48) 7.2.0', '7.2.0')
]
class TestG77Versions(object):
def test_g77_version(self):
fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu')
for vs, version in g77_version_strings:
v = fc.version_match(vs)
assert_(v == version, (vs, v))
def test_not_g77(self):
fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu')
for vs, _ in gfortran_version_strings:
v = fc.version_match(vs)
assert_(v is None, (vs, v))
class TestGFortranVersions(object):
def test_gfortran_version(self):
fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95')
for vs, version in gfortran_version_strings:
v = fc.version_match(vs)
assert_(v == version, (vs, v))
def test_not_gfortran(self):
fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95')
for vs, _ in g77_version_strings:
v = fc.version_match(vs)
assert_(v is None, (vs, v))

View File

@@ -0,0 +1,32 @@
from __future__ import division, absolute_import, print_function
import numpy.distutils.fcompiler
from numpy.testing import assert_
intel_32bit_version_strings = [
("Intel(R) Fortran Intel(R) 32-bit Compiler Professional for applications"
"running on Intel(R) 32, Version 11.1", '11.1'),
]
intel_64bit_version_strings = [
("Intel(R) Fortran IA-64 Compiler Professional for applications"
"running on IA-64, Version 11.0", '11.0'),
("Intel(R) Fortran Intel(R) 64 Compiler Professional for applications"
"running on Intel(R) 64, Version 11.1", '11.1')
]
class TestIntelFCompilerVersions(object):
def test_32bit_version(self):
fc = numpy.distutils.fcompiler.new_fcompiler(compiler='intel')
for vs, version in intel_32bit_version_strings:
v = fc.version_match(vs)
assert_(v == version)
class TestIntelEM64TFCompilerVersions(object):
def test_64bit_version(self):
fc = numpy.distutils.fcompiler.new_fcompiler(compiler='intelem')
for vs, version in intel_64bit_version_strings:
v = fc.version_match(vs)
assert_(v == version)

View File

@@ -0,0 +1,24 @@
from __future__ import division, absolute_import, print_function
from numpy.testing import assert_
import numpy.distutils.fcompiler
nag_version_strings = [('nagfor', 'NAG Fortran Compiler Release '
'6.2(Chiyoda) Build 6200', '6.2'),
('nagfor', 'NAG Fortran Compiler Release '
'6.1(Tozai) Build 6136', '6.1'),
('nagfor', 'NAG Fortran Compiler Release '
'6.0(Hibiya) Build 1021', '6.0'),
('nagfor', 'NAG Fortran Compiler Release '
'5.3.2(971)', '5.3.2'),
('nag', 'NAGWare Fortran 95 compiler Release 5.1'
'(347,355-367,375,380-383,389,394,399,401-402,407,'
'431,435,437,446,459-460,463,472,494,496,503,508,'
'511,517,529,555,557,565)', '5.1')]
class TestNagFCompilerVersions(object):
def test_version_match(self):
for comp, vs, version in nag_version_strings:
fc = numpy.distutils.fcompiler.new_fcompiler(compiler=comp)
v = fc.version_match(vs)
assert_(v == version)

View File

@@ -0,0 +1,44 @@
from numpy.distutils.from_template import process_str
from numpy.testing import assert_equal
pyf_src = """
python module foo
<_rd=real,double precision>
interface
subroutine <s,d>foosub(tol)
<_rd>, intent(in,out) :: tol
end subroutine <s,d>foosub
end interface
end python module foo
"""
expected_pyf = """
python module foo
interface
subroutine sfoosub(tol)
real, intent(in,out) :: tol
end subroutine sfoosub
subroutine dfoosub(tol)
double precision, intent(in,out) :: tol
end subroutine dfoosub
end interface
end python module foo
"""
def normalize_whitespace(s):
"""
Remove leading and trailing whitespace, and convert internal
stretches of whitespace to a single space.
"""
return ' '.join(s.split())
def test_from_template():
"""Regression test for gh-10712."""
pyf = process_str(pyf_src)
normalized_pyf = normalize_whitespace(pyf)
normalized_expected_pyf = normalize_whitespace(expected_pyf)
assert_equal(normalized_pyf, normalized_expected_pyf)

View File

@@ -0,0 +1,84 @@
from __future__ import division, absolute_import, print_function
from os.path import join, sep, dirname
from numpy.distutils.misc_util import (
appendpath, minrelpath, gpaths, get_shared_lib_extension, get_info
)
from numpy.testing import (
assert_, assert_equal
)
ajoin = lambda *paths: join(*((sep,)+paths))
class TestAppendpath(object):
def test_1(self):
assert_equal(appendpath('prefix', 'name'), join('prefix', 'name'))
assert_equal(appendpath('/prefix', 'name'), ajoin('prefix', 'name'))
assert_equal(appendpath('/prefix', '/name'), ajoin('prefix', 'name'))
assert_equal(appendpath('prefix', '/name'), join('prefix', 'name'))
def test_2(self):
assert_equal(appendpath('prefix/sub', 'name'),
join('prefix', 'sub', 'name'))
assert_equal(appendpath('prefix/sub', 'sup/name'),
join('prefix', 'sub', 'sup', 'name'))
assert_equal(appendpath('/prefix/sub', '/prefix/name'),
ajoin('prefix', 'sub', 'name'))
def test_3(self):
assert_equal(appendpath('/prefix/sub', '/prefix/sup/name'),
ajoin('prefix', 'sub', 'sup', 'name'))
assert_equal(appendpath('/prefix/sub/sub2', '/prefix/sup/sup2/name'),
ajoin('prefix', 'sub', 'sub2', 'sup', 'sup2', 'name'))
assert_equal(appendpath('/prefix/sub/sub2', '/prefix/sub/sup/name'),
ajoin('prefix', 'sub', 'sub2', 'sup', 'name'))
class TestMinrelpath(object):
def test_1(self):
n = lambda path: path.replace('/', sep)
assert_equal(minrelpath(n('aa/bb')), n('aa/bb'))
assert_equal(minrelpath('..'), '..')
assert_equal(minrelpath(n('aa/..')), '')
assert_equal(minrelpath(n('aa/../bb')), 'bb')
assert_equal(minrelpath(n('aa/bb/..')), 'aa')
assert_equal(minrelpath(n('aa/bb/../..')), '')
assert_equal(minrelpath(n('aa/bb/../cc/../dd')), n('aa/dd'))
assert_equal(minrelpath(n('.././..')), n('../..'))
assert_equal(minrelpath(n('aa/bb/.././../dd')), n('dd'))
class TestGpaths(object):
def test_gpaths(self):
local_path = minrelpath(join(dirname(__file__), '..'))
ls = gpaths('command/*.py', local_path)
assert_(join(local_path, 'command', 'build_src.py') in ls, repr(ls))
f = gpaths('system_info.py', local_path)
assert_(join(local_path, 'system_info.py') == f[0], repr(f))
class TestSharedExtension(object):
def test_get_shared_lib_extension(self):
import sys
ext = get_shared_lib_extension(is_python_ext=False)
if sys.platform.startswith('linux'):
assert_equal(ext, '.so')
elif sys.platform.startswith('gnukfreebsd'):
assert_equal(ext, '.so')
elif sys.platform.startswith('darwin'):
assert_equal(ext, '.dylib')
elif sys.platform.startswith('win'):
assert_equal(ext, '.dll')
# just check for no crash
assert_(get_shared_lib_extension(is_python_ext=True))
def test_installed_npymath_ini():
# Regression test for gh-7707. If npymath.ini wasn't installed, then this
# will give an error.
info = get_info('npymath')
assert isinstance(info, dict)
assert "define_macros" in info

View File

@@ -0,0 +1,86 @@
from __future__ import division, absolute_import, print_function
import os
from numpy.distutils.npy_pkg_config import read_config, parse_flags
from numpy.testing import temppath, assert_
simple = """\
[meta]
Name = foo
Description = foo lib
Version = 0.1
[default]
cflags = -I/usr/include
libs = -L/usr/lib
"""
simple_d = {'cflags': '-I/usr/include', 'libflags': '-L/usr/lib',
'version': '0.1', 'name': 'foo'}
simple_variable = """\
[meta]
Name = foo
Description = foo lib
Version = 0.1
[variables]
prefix = /foo/bar
libdir = ${prefix}/lib
includedir = ${prefix}/include
[default]
cflags = -I${includedir}
libs = -L${libdir}
"""
simple_variable_d = {'cflags': '-I/foo/bar/include', 'libflags': '-L/foo/bar/lib',
'version': '0.1', 'name': 'foo'}
class TestLibraryInfo(object):
def test_simple(self):
with temppath('foo.ini') as path:
with open(path, 'w') as f:
f.write(simple)
pkg = os.path.splitext(path)[0]
out = read_config(pkg)
assert_(out.cflags() == simple_d['cflags'])
assert_(out.libs() == simple_d['libflags'])
assert_(out.name == simple_d['name'])
assert_(out.version == simple_d['version'])
def test_simple_variable(self):
with temppath('foo.ini') as path:
with open(path, 'w') as f:
f.write(simple_variable)
pkg = os.path.splitext(path)[0]
out = read_config(pkg)
assert_(out.cflags() == simple_variable_d['cflags'])
assert_(out.libs() == simple_variable_d['libflags'])
assert_(out.name == simple_variable_d['name'])
assert_(out.version == simple_variable_d['version'])
out.vars['prefix'] = '/Users/david'
assert_(out.cflags() == '-I/Users/david/include')
class TestParseFlags(object):
def test_simple_cflags(self):
d = parse_flags("-I/usr/include")
assert_(d['include_dirs'] == ['/usr/include'])
d = parse_flags("-I/usr/include -DFOO")
assert_(d['include_dirs'] == ['/usr/include'])
assert_(d['macros'] == ['FOO'])
d = parse_flags("-I /usr/include -DFOO")
assert_(d['include_dirs'] == ['/usr/include'])
assert_(d['macros'] == ['FOO'])
def test_simple_lflags(self):
d = parse_flags("-L/usr/lib -lfoo -L/usr/lib -lbar")
assert_(d['library_dirs'] == ['/usr/lib', '/usr/lib'])
assert_(d['libraries'] == ['foo', 'bar'])
d = parse_flags("-L /usr/lib -lfoo -L/usr/lib -lbar")
assert_(d['library_dirs'] == ['/usr/lib', '/usr/lib'])
assert_(d['libraries'] == ['foo', 'bar'])

View File

@@ -0,0 +1,79 @@
from __future__ import division, absolute_import, print_function
import pytest
import subprocess
import os
import json
import sys
from numpy.distutils import _shell_utils
argv_cases = [
[r'exe'],
[r'path/exe'],
[r'path\exe'],
[r'\\server\path\exe'],
[r'path to/exe'],
[r'path to\exe'],
[r'exe', '--flag'],
[r'path/exe', '--flag'],
[r'path\exe', '--flag'],
[r'path to/exe', '--flag'],
[r'path to\exe', '--flag'],
# flags containing literal quotes in their name
[r'path to/exe', '--flag-"quoted"'],
[r'path to\exe', '--flag-"quoted"'],
[r'path to/exe', '"--flag-quoted"'],
[r'path to\exe', '"--flag-quoted"'],
]
@pytest.fixture(params=[
_shell_utils.WindowsParser,
_shell_utils.PosixParser
])
def Parser(request):
return request.param
@pytest.fixture
def runner(Parser):
if Parser != _shell_utils.NativeParser:
pytest.skip('Unable to run with non-native parser')
if Parser == _shell_utils.WindowsParser:
return lambda cmd: subprocess.check_output(cmd)
elif Parser == _shell_utils.PosixParser:
# posix has no non-shell string parsing
return lambda cmd: subprocess.check_output(cmd, shell=True)
else:
raise NotImplementedError
@pytest.mark.parametrize('argv', argv_cases)
def test_join_matches_subprocess(Parser, runner, argv):
"""
Test that join produces strings understood by subprocess
"""
# invoke python to return its arguments as json
cmd = [
sys.executable, '-c',
'import json, sys; print(json.dumps(sys.argv[1:]))'
]
joined = Parser.join(cmd + argv)
json_out = runner(joined).decode()
assert json.loads(json_out) == argv
@pytest.mark.parametrize('argv', argv_cases)
def test_roundtrip(Parser, argv):
"""
Test that split is the inverse operation of join
"""
try:
joined = Parser.join(argv)
assert argv == Parser.split(joined)
except NotImplementedError:
pytest.skip("Not implemented")

View File

@@ -0,0 +1,257 @@
from __future__ import division, print_function
import os
import shutil
import pytest
from tempfile import mkstemp, mkdtemp
from subprocess import Popen, PIPE
from distutils.errors import DistutilsError
from numpy.testing import assert_, assert_equal, assert_raises
from numpy.distutils import ccompiler, customized_ccompiler
from numpy.distutils.system_info import system_info, ConfigParser
from numpy.distutils.system_info import AliasedOptionError
from numpy.distutils.system_info import default_lib_dirs, default_include_dirs
from numpy.distutils import _shell_utils
def get_class(name, notfound_action=1):
"""
notfound_action:
0 - do nothing
1 - display warning message
2 - raise error
"""
cl = {'temp1': Temp1Info,
'temp2': Temp2Info,
'duplicate_options': DuplicateOptionInfo,
}.get(name.lower(), _system_info)
return cl()
simple_site = """
[ALL]
library_dirs = {dir1:s}{pathsep:s}{dir2:s}
libraries = {lib1:s},{lib2:s}
extra_compile_args = -I/fake/directory -I"/path with/spaces" -Os
runtime_library_dirs = {dir1:s}
[temp1]
library_dirs = {dir1:s}
libraries = {lib1:s}
runtime_library_dirs = {dir1:s}
[temp2]
library_dirs = {dir2:s}
libraries = {lib2:s}
extra_link_args = -Wl,-rpath={lib2_escaped:s}
rpath = {dir2:s}
[duplicate_options]
mylib_libs = {lib1:s}
libraries = {lib2:s}
"""
site_cfg = simple_site
fakelib_c_text = """
/* This file is generated from numpy/distutils/testing/test_system_info.py */
#include<stdio.h>
void foo(void) {
printf("Hello foo");
}
void bar(void) {
printf("Hello bar");
}
"""
def have_compiler():
""" Return True if there appears to be an executable compiler
"""
compiler = customized_ccompiler()
try:
cmd = compiler.compiler # Unix compilers
except AttributeError:
try:
if not compiler.initialized:
compiler.initialize() # MSVC is different
except (DistutilsError, ValueError):
return False
cmd = [compiler.cc]
try:
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
p.stdout.close()
p.stderr.close()
p.wait()
except OSError:
return False
return True
HAVE_COMPILER = have_compiler()
class _system_info(system_info):
def __init__(self,
default_lib_dirs=default_lib_dirs,
default_include_dirs=default_include_dirs,
verbosity=1,
):
self.__class__.info = {}
self.local_prefixes = []
defaults = {'library_dirs': '',
'include_dirs': '',
'runtime_library_dirs': '',
'rpath': '',
'src_dirs': '',
'search_static_first': "0",
'extra_compile_args': '',
'extra_link_args': ''}
self.cp = ConfigParser(defaults)
# We have to parse the config files afterwards
# to have a consistent temporary filepath
def _check_libs(self, lib_dirs, libs, opt_libs, exts):
"""Override _check_libs to return with all dirs """
info = {'libraries': libs, 'library_dirs': lib_dirs}
return info
class Temp1Info(_system_info):
"""For testing purposes"""
section = 'temp1'
class Temp2Info(_system_info):
"""For testing purposes"""
section = 'temp2'
class DuplicateOptionInfo(_system_info):
"""For testing purposes"""
section = 'duplicate_options'
class TestSystemInfoReading(object):
def setup(self):
""" Create the libraries """
# Create 2 sources and 2 libraries
self._dir1 = mkdtemp()
self._src1 = os.path.join(self._dir1, 'foo.c')
self._lib1 = os.path.join(self._dir1, 'libfoo.so')
self._dir2 = mkdtemp()
self._src2 = os.path.join(self._dir2, 'bar.c')
self._lib2 = os.path.join(self._dir2, 'libbar.so')
# Update local site.cfg
global simple_site, site_cfg
site_cfg = simple_site.format(**{
'dir1': self._dir1,
'lib1': self._lib1,
'dir2': self._dir2,
'lib2': self._lib2,
'pathsep': os.pathsep,
'lib2_escaped': _shell_utils.NativeParser.join([self._lib2])
})
# Write site.cfg
fd, self._sitecfg = mkstemp()
os.close(fd)
with open(self._sitecfg, 'w') as fd:
fd.write(site_cfg)
# Write the sources
with open(self._src1, 'w') as fd:
fd.write(fakelib_c_text)
with open(self._src2, 'w') as fd:
fd.write(fakelib_c_text)
# We create all class-instances
def site_and_parse(c, site_cfg):
c.files = [site_cfg]
c.parse_config_files()
return c
self.c_default = site_and_parse(get_class('default'), self._sitecfg)
self.c_temp1 = site_and_parse(get_class('temp1'), self._sitecfg)
self.c_temp2 = site_and_parse(get_class('temp2'), self._sitecfg)
self.c_dup_options = site_and_parse(get_class('duplicate_options'),
self._sitecfg)
def teardown(self):
# Do each removal separately
try:
shutil.rmtree(self._dir1)
except Exception:
pass
try:
shutil.rmtree(self._dir2)
except Exception:
pass
try:
os.remove(self._sitecfg)
except Exception:
pass
def test_all(self):
# Read in all information in the ALL block
tsi = self.c_default
assert_equal(tsi.get_lib_dirs(), [self._dir1, self._dir2])
assert_equal(tsi.get_libraries(), [self._lib1, self._lib2])
assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1])
extra = tsi.calc_extra_info()
assert_equal(extra['extra_compile_args'], ['-I/fake/directory', '-I/path with/spaces', '-Os'])
def test_temp1(self):
# Read in all information in the temp1 block
tsi = self.c_temp1
assert_equal(tsi.get_lib_dirs(), [self._dir1])
assert_equal(tsi.get_libraries(), [self._lib1])
assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1])
def test_temp2(self):
# Read in all information in the temp2 block
tsi = self.c_temp2
assert_equal(tsi.get_lib_dirs(), [self._dir2])
assert_equal(tsi.get_libraries(), [self._lib2])
# Now from rpath and not runtime_library_dirs
assert_equal(tsi.get_runtime_lib_dirs(key='rpath'), [self._dir2])
extra = tsi.calc_extra_info()
assert_equal(extra['extra_link_args'], ['-Wl,-rpath=' + self._lib2])
def test_duplicate_options(self):
# Ensure that duplicates are raising an AliasedOptionError
tsi = self.c_dup_options
assert_raises(AliasedOptionError, tsi.get_option_single, "mylib_libs", "libraries")
assert_equal(tsi.get_libs("mylib_libs", [self._lib1]), [self._lib1])
assert_equal(tsi.get_libs("libraries", [self._lib2]), [self._lib2])
@pytest.mark.skipif(not HAVE_COMPILER, reason="Missing compiler")
def test_compile1(self):
# Compile source and link the first source
c = customized_ccompiler()
previousDir = os.getcwd()
try:
# Change directory to not screw up directories
os.chdir(self._dir1)
c.compile([os.path.basename(self._src1)], output_dir=self._dir1)
# Ensure that the object exists
assert_(os.path.isfile(self._src1.replace('.c', '.o')) or
os.path.isfile(self._src1.replace('.c', '.obj')))
finally:
os.chdir(previousDir)
@pytest.mark.skipif(not HAVE_COMPILER, reason="Missing compiler")
@pytest.mark.skipif('msvc' in repr(ccompiler.new_compiler()),
reason="Fails with MSVC compiler ")
def test_compile2(self):
# Compile source and link the second source
tsi = self.c_temp2
c = customized_ccompiler()
extra_link_args = tsi.calc_extra_info()['extra_link_args']
previousDir = os.getcwd()
try:
# Change directory to not screw up directories
os.chdir(self._dir2)
c.compile([os.path.basename(self._src2)], output_dir=self._dir2,
extra_postargs=extra_link_args)
# Ensure that the object exists
assert_(os.path.isfile(self._src2.replace('.c', '.o')))
finally:
os.chdir(previousDir)