From 4e9316036c43b15c1264ca0bedbb1a7bb37591ba Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Tue, 7 Jan 2020 00:17:03 +0100 Subject: [PATCH 1/8] add before test variable --- cibuildwheel/__main__.py | 2 + cibuildwheel/linux.py | 9 +- cibuildwheel/macos.py | 6 +- cibuildwheel/windows.py | 6 +- test/10_before_test/cibuildwheel_test.py | 22 +++ test/10_before_test/setup.py | 19 ++ test/10_before_test/spam.c | 48 +++++ test/10_before_test/test/spam_test.py | 24 +++ unit_test/main_options_test.py | 221 +++++++++++++++++++++++ 9 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 test/10_before_test/cibuildwheel_test.py create mode 100644 test/10_before_test/setup.py create mode 100644 test/10_before_test/spam.c create mode 100644 test/10_before_test/test/spam_test.py create mode 100644 unit_test/main_options_test.py diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index aa7f6587..e20028d8 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -113,6 +113,7 @@ def main(): repair_command_default = '' repair_command = get_option_from_environment('CIBW_REPAIR_WHEEL_COMMAND', platform=platform, default=repair_command_default) environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='') + before_test = get_option_from_environment('CIBW_BEFORE_TEST', platform=platform, default='') if test_extras: test_extras = '[{0}]'.format(test_extras) @@ -154,6 +155,7 @@ def main(): build_selector=build_selector, repair_command=repair_command, environment=environment, + before_test=before_test ) if platform == 'linux': diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 20dae7e6..753da624 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -68,7 +68,7 @@ def get_python_configurations(build_selector): return [c for c in python_configurations if matches_platform(c.identifier) and build_selector(c.identifier)] -def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images): +def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test, manylinux_images): try: subprocess.check_call(['docker', '--version']) except Exception: @@ -154,6 +154,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef echo "Running tests using `which python`" + if [ ! -z {before_test} ]; then + sh -c {before_test} + fi + # Install the wheel we just built # Note: If auditwheel produced two wheels, it's because the earlier produced wheel # conforms to multiple manylinux standards. These multiple versions of the wheel are @@ -202,6 +206,9 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef environment_exports='\n'.join(environment.as_shell_commands()), uid=os.getuid(), gid=os.getgid(), + before_test=shlex_quote( + prepare_command(before_test, project='/project') if before_test else '' + ), ) container_name = 'cibuildwheel-{}'.format(uuid.uuid4()) diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 3b3edcba..50b6392a 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -105,7 +105,7 @@ def install_pypy(version, url): return installation_bin_path -def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment): +def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test): abs_project_dir = os.path.abspath(project_dir) temp_dir = tempfile.mkdtemp(prefix='cibuildwheel') built_wheel_dir = os.path.join(temp_dir, 'built_wheel') @@ -214,6 +214,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef # check that we are using the Python from the virtual environment call(['which', 'python'], env=virtualenv_env) + if before_test: + before_test_prepared = prepare_command(before_test, project=abs_project_dir) + call(before_test_prepared, env=virtualenv_env, shell=True) + # install the wheel call(['pip', 'install', repaired_wheel + test_extras], env=virtualenv_env) diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index 24e19c38..15a53209 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -87,7 +87,7 @@ def install_pypy(version, arch, url): return installation_path -def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment): +def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test): abs_project_dir = os.path.abspath(project_dir) temp_dir = tempfile.mkdtemp(prefix='cibuildwheel') built_wheel_dir = os.path.join(temp_dir, 'built_wheel') @@ -193,6 +193,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef # check that we are using the Python from the virtual environment shell(['which', 'python'], env=virtualenv_env) + if before_test: + before_test_prepared = prepare_command(before_test, project=abs_project_dir) + shell([before_test_prepared], env=virtualenv_env) + # install the wheel shell(['pip', 'install', repaired_wheel + test_extras], env=virtualenv_env) diff --git a/test/10_before_test/cibuildwheel_test.py b/test/10_before_test/cibuildwheel_test.py new file mode 100644 index 00000000..f6a56af4 --- /dev/null +++ b/test/10_before_test/cibuildwheel_test.py @@ -0,0 +1,22 @@ +import os +import utils + +def test(): + project_dir = os.path.dirname(__file__) + + # build the wheels + actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ + # write python version information to a temporary file, this is + # checked in setup.py + 'CIBW_BEFORE_TEST': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)"''', + 'CIBW_BEFORE_TEST_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)"''', + 'CIBW_TEST_REQUIRES': 'nose', + # the 'false ||' bit is to ensure this command runs in a shell on + # mac/linux. + 'CIBW_TEST_COMMAND': 'false || nosetests {project}/test', + 'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test', + }) + + # also check that we got the right wheels + expected_wheels = utils.expected_wheels('spam', '0.1.0') + assert set(actual_wheels) == set(expected_wheels) diff --git a/test/10_before_test/setup.py b/test/10_before_test/setup.py new file mode 100644 index 00000000..8abc7921 --- /dev/null +++ b/test/10_before_test/setup.py @@ -0,0 +1,19 @@ +from setuptools import setup, Extension +import sys, os + +# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step +# is the same one as is currently running. +version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt' +if os.path.exists(version_file): + os.remove(version_file) + +# check that the executable also was written +executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' +if os.path.exists(executable_file): + os.remove(executable_file) + +setup( + name="spam", + ext_modules=[Extension('spam', sources=['spam.c'])], + version="0.1.0", +) diff --git a/test/10_before_test/spam.c b/test/10_before_test/spam.c new file mode 100644 index 00000000..d1ab0f22 --- /dev/null +++ b/test/10_before_test/spam.c @@ -0,0 +1,48 @@ +#include + +static PyObject * +spam_system(PyObject *self, PyObject *args) +{ + const char *command; + int sts; + + if (!PyArg_ParseTuple(args, "s", &command)) + return NULL; + sts = system(command); + return PyLong_FromLong(sts); +} + +/* Module initialization */ + +#if PY_MAJOR_VERSION >= 3 + #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) + #define MOD_DEF(m, name, doc, methods, module_state_size) \ + static struct PyModuleDef moduledef = { \ + PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \ + m = PyModule_Create(&moduledef); + #define MOD_RETURN(m) return m; +#else + #define MOD_INIT(name) PyMODINIT_FUNC init##name(void) + #define MOD_DEF(m, name, doc, methods, module_state_size) \ + m = Py_InitModule3(name, methods, doc); + #define MOD_RETURN(m) return; +#endif + +static PyMethodDef module_methods[] = { + {"system", (PyCFunction)spam_system, METH_VARARGS, + "Execute a shell command."}, + {NULL} /* Sentinel */ +}; + +MOD_INIT(spam) +{ + PyObject* m; + + MOD_DEF(m, + "spam", + "Example module", + module_methods, + -1) + + MOD_RETURN(m) +} diff --git a/test/10_before_test/test/spam_test.py b/test/10_before_test/test/spam_test.py new file mode 100644 index 00000000..7560b438 --- /dev/null +++ b/test/10_before_test/test/spam_test.py @@ -0,0 +1,24 @@ +import sys, os +from unittest import TestCase + + +class TestBeforeTest(TestCase): + def test_version(self): + # assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step + # is the same one as is currently running. + version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt' + with open(version_file) as f: + stored_version = f.read() + print('stored_version', stored_version) + print('sys.version', sys.version) + assert stored_version == sys.version + + def test_executable(self): + # check that the executable also was written + executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' + with open(executable_file) as f: + stored_executable = f.read() + print('stored_executable', stored_executable) + print('sys.executable', sys.executable) + # windows/mac are case insensitive + assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower() diff --git a/unit_test/main_options_test.py b/unit_test/main_options_test.py new file mode 100644 index 00000000..99387bf5 --- /dev/null +++ b/unit_test/main_options_test.py @@ -0,0 +1,221 @@ +import pytest + +import sys + +from cibuildwheel.__main__ import main +from cibuildwheel.environment import ParsedEnvironment +from cibuildwheel.util import BuildSelector + +from main_util_fixtures import mock_protection, fake_project_dir, platform, intercepted_build_args + + + +# CIBW_PLATFORM is tested in main_platform_test.py + + +def test_output_dir(platform, intercepted_build_args, monkeypatch): + OUTPUT_DIR = 'some_output_dir' + + monkeypatch.setenv('CIBW_OUTPUT_DIR', OUTPUT_DIR) + + main() + + assert intercepted_build_args.kwargs['output_dir'] == OUTPUT_DIR + + +def test_output_dir_default(platform, intercepted_build_args, monkeypatch): + main() + + assert intercepted_build_args.kwargs['output_dir'] == 'wheelhouse' + + +@pytest.mark.parametrize('also_set_environment', [False, True]) +def test_output_dir_argument(also_set_environment, platform, intercepted_build_args, monkeypatch): + OUTPUT_DIR = 'some_output_dir' + + monkeypatch.setattr(sys, 'argv', sys.argv + ['--output-dir', OUTPUT_DIR]) + if also_set_environment: + monkeypatch.setenv('CIBW_OUTPUT_DIR', 'not_this_output_dir') + + main() + + assert intercepted_build_args.kwargs['output_dir'] == OUTPUT_DIR + + +def test_build_selector(platform, intercepted_build_args, monkeypatch): + BUILD = 'some build* *-selector' + SKIP = 'some skip* *-selector' + + monkeypatch.setenv('CIBW_BUILD', BUILD) + monkeypatch.setenv('CIBW_SKIP', SKIP) + + main() + + intercepted_build_selector = intercepted_build_args.kwargs['build_selector'] + assert isinstance(intercepted_build_selector, BuildSelector) + assert intercepted_build_selector('build-this') + assert not intercepted_build_selector('skip-that') + # This unit test is just testing the options of 'main' + # Unit tests for BuildSelector are in build_selector_test.py + + +@pytest.mark.parametrize('architecture, image, full_image', [ + ('x86_64', None, 'quay.io/pypa/manylinux2010_x86_64'), + ('x86_64', 'manylinux1', 'quay.io/pypa/manylinux1_x86_64'), + ('x86_64', 'manylinux2010', 'quay.io/pypa/manylinux2010_x86_64'), + ('x86_64', 'manylinux2014', 'quay.io/pypa/manylinux2014_x86_64'), + ('x86_64', 'custom_image', 'custom_image'), + ('i686', None, 'quay.io/pypa/manylinux2010_i686'), + ('i686', 'manylinux1', 'quay.io/pypa/manylinux1_i686'), + ('i686', 'manylinux2010', 'quay.io/pypa/manylinux2010_i686'), + ('i686', 'manylinux2014', 'quay.io/pypa/manylinux2014_i686'), + ('i686', 'custom_image', 'custom_image'), +]) +def test_manylinux_images(architecture, image, full_image, platform, intercepted_build_args, monkeypatch): + if image is not None: + monkeypatch.setenv('CIBW_MANYLINUX_' + architecture.upper() + '_IMAGE', image) + + main() + + if platform == 'linux': + assert intercepted_build_args.kwargs['manylinux_images'][architecture] == full_image + else: + assert 'manylinux_images' not in intercepted_build_args.kwargs + + +def get_default_repair_command(platform): + if platform == 'linux': + return 'auditwheel repair -w {dest_dir} {wheel}' + elif platform == 'macos': + return 'delocate-listdeps {wheel} && delocate-wheel -w {dest_dir} {wheel}' + elif platform == 'windows': + return '' + else: + raise ValueError('Unknown platform', platform) + +@pytest.mark.parametrize('repair_command', [None, 'repair', 'repair -w {dest_dir} {wheel}']) +@pytest.mark.parametrize('platform_specific', [False, True]) +def test_repair_command(repair_command, platform_specific, platform, intercepted_build_args, monkeypatch): + if repair_command is not None: + if platform_specific: + monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND_' + platform.upper(), repair_command) + monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND', 'overwritten') + else: + monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND', repair_command) + + main() + + expected_repair = repair_command or get_default_repair_command(platform) + assert intercepted_build_args.kwargs['repair_command'] == expected_repair + + +@pytest.mark.parametrize('environment', [ + {}, + {'something': 'value'}, + {'something': 'value', 'something_else': 'other_value'} +]) +@pytest.mark.parametrize('platform_specific', [False, True]) +def test_environment(environment, platform_specific, platform, intercepted_build_args, monkeypatch): + env_string = ' '.join(['{}={}'.format(k, v) for k, v in environment.items()]) + if platform_specific: + monkeypatch.setenv('CIBW_ENVIRONMENT_' + platform.upper(), env_string) + monkeypatch.setenv('CIBW_ENVIRONMENT', 'overwritten') + else: + monkeypatch.setenv('CIBW_ENVIRONMENT', env_string) + + main() + + intercepted_environment = intercepted_build_args.kwargs['environment'] + assert isinstance(intercepted_environment, ParsedEnvironment) + assert intercepted_environment.as_dictionary(prev_environment={}) == environment + + +@pytest.mark.parametrize('test_requires', [None, 'requirement other_requirement']) +@pytest.mark.parametrize('platform_specific', [False, True]) +def test_test_requires(test_requires, platform_specific, platform, intercepted_build_args, monkeypatch): + if test_requires is not None: + if platform_specific: + monkeypatch.setenv('CIBW_TEST_REQUIRES_' + platform.upper(), test_requires) + monkeypatch.setenv('CIBW_TEST_REQUIRES', 'overwritten') + else: + monkeypatch.setenv('CIBW_TEST_REQUIRES', test_requires) + + main() + + assert intercepted_build_args.kwargs['test_requires'] == (test_requires or '').split() + + +@pytest.mark.parametrize('test_extras', [None, 'extras']) +@pytest.mark.parametrize('platform_specific', [False, True]) +def test_test_extras(test_extras, platform_specific, platform, intercepted_build_args, monkeypatch): + if test_extras is not None: + if platform_specific: + monkeypatch.setenv('CIBW_TEST_EXTRAS_' + platform.upper(), test_extras) + monkeypatch.setenv('CIBW_TEST_EXTRAS', 'overwritten') + else: + monkeypatch.setenv('CIBW_TEST_EXTRAS', test_extras) + + main() + + assert intercepted_build_args.kwargs['test_extras'] == ('[' + test_extras + ']' if test_extras else '') + + +@pytest.mark.parametrize('test_command', [None, 'test --command']) +@pytest.mark.parametrize('platform_specific', [False, True]) +def test_test_command(test_command, platform_specific, platform, intercepted_build_args, monkeypatch): + if test_command is not None: + if platform_specific: + monkeypatch.setenv('CIBW_TEST_COMMAND_' + platform.upper(), test_command) + monkeypatch.setenv('CIBW_TEST_COMMAND', 'overwritten') + else: + monkeypatch.setenv('CIBW_TEST_COMMAND', test_command) + + main() + + assert intercepted_build_args.kwargs['test_command'] == test_command + + +@pytest.mark.parametrize('before_build', [None, 'before --build']) +@pytest.mark.parametrize('platform_specific', [False, True]) +def test_before_build(before_build, platform_specific, platform, intercepted_build_args, monkeypatch): + if before_build is not None: + if platform_specific: + monkeypatch.setenv('CIBW_BEFORE_BUILD_' + platform.upper(), before_build) + monkeypatch.setenv('CIBW_BEFORE_BUILD', 'overwritten') + else: + monkeypatch.setenv('CIBW_BEFORE_BUILD', before_build) + + main() + + assert intercepted_build_args.kwargs['before_build'] == before_build + + +@pytest.mark.parametrize('build_verbosity', [None, 0, 2, -2, 4, -4]) +@pytest.mark.parametrize('platform_specific', [False, True]) +def test_build_verbosity(build_verbosity, platform_specific, platform, intercepted_build_args, monkeypatch): + if build_verbosity is not None: + if platform_specific: + monkeypatch.setenv('CIBW_BUILD_VERBOSITY_' + platform.upper(), str(build_verbosity)) + monkeypatch.setenv('CIBW_BUILD_VERBOSITY', 'overwritten') + else: + monkeypatch.setenv('CIBW_BUILD_VERBOSITY', str(build_verbosity)) + + main() + + expected_verbosity = max(-3, min(3, int(build_verbosity or 0))) + assert intercepted_build_args.kwargs['build_verbosity'] == expected_verbosity + + +@pytest.mark.parametrize('before_test', ["", 'before --test']) +@pytest.mark.parametrize('platform_specific', [False, True]) +def test_before_test(before_test, platform_specific, platform, intercepted_build_args, monkeypatch): + if before_test is not None: + if platform_specific: + monkeypatch.setenv('CIBW_BEFORE_TEST_' + platform.upper(), before_test) + monkeypatch.setenv('CIBW_BEFORE_TEST', 'overwritten') + else: + monkeypatch.setenv('CIBW_BEFORE_TEST', before_test) + + main() + + assert intercepted_build_args.kwargs['before_test'] == before_test \ No newline at end of file From d9e6bbfa4f018b0c2d61dd80c1c2259396cdfac9 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Tue, 7 Jan 2020 09:03:14 +0100 Subject: [PATCH 2/8] add documentation --- README.md | 3 ++- docs/options.md | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d918c808..9c7ecb59 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,8 @@ Options | **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel | | | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests | | | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require | -| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel | +| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute shell command to prepare test environment | +| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Increase/decrease the output of pip wheel | Working examples ---------------- diff --git a/docs/options.md b/docs/options.md index 4b4069ac..95c7a728 100644 --- a/docs/options.md +++ b/docs/options.md @@ -340,6 +340,32 @@ Platform-specific variants also available:
CIBW_TEST_EXTRAS: test,qt ``` +### `CIBW_BEFORE_TEST` {: #before-test} +> Execute a shell command preparing test environment + +A shell command to run after setup test environment. This option allows you to run a command in **each** Python environment before the `pip wheel` command. This is useful if you need to install non pip package, change values of environment variables +or perform multi step pip installation (like install `scikit-build` or `cython` before install test package) + +If dependencies are required to build your wheel (for example if you include a header from a Python module), set this to `pip install .`, and the dependencies will be installed automatically by pip. However, this means your package will be built twice - if your package takes a long time to build, you might wish to manually list the dependencies here instead. + +The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`. + +On Linux and macOS, the command is run in a shell, so you can write things like `cmd1 && cmd2`. + +Platform-specific variants also available:
+ `CIBW_BEFORE_TEST_MACOS` | `CIBW_BEFORE_TEST_WINDOWS` | `CIBW_BEFORE_TEST_LINUX` + +#### Examples +```yaml +# install packages needed to build test dependencies +CIBW_BEFORE_TEST: pip install cmake scikit-build + +# install test dependencies with overwritten environment variables. +CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt + +# chain commands using && +CIBW_BEFORE_TEST: yum install -y libffi-dev && pip install . +``` ## Other From 6461074ec96a5918a0693d8bb79d6f932f6865e6 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Fri, 10 Jan 2020 23:08:27 +0100 Subject: [PATCH 3/8] Apply spell suggestions from joerick code review Co-Authored-By: Joe Rickerby --- docs/options.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/options.md b/docs/options.md index 95c7a728..dff21fe4 100644 --- a/docs/options.md +++ b/docs/options.md @@ -341,12 +341,11 @@ CIBW_TEST_EXTRAS: test,qt ``` ### `CIBW_BEFORE_TEST` {: #before-test} -> Execute a shell command preparing test environment +> Execute a shell command before testing each wheel -A shell command to run after setup test environment. This option allows you to run a command in **each** Python environment before the `pip wheel` command. This is useful if you need to install non pip package, change values of environment variables +A shell command to run in **each** test virtual environment, before your wheel is installed and tested. This is useful if you need to install non pip package, change values of environment variables or perform multi step pip installation (like install `scikit-build` or `cython` before install test package) -If dependencies are required to build your wheel (for example if you include a header from a Python module), set this to `pip install .`, and the dependencies will be installed automatically by pip. However, this means your package will be built twice - if your package takes a long time to build, you might wish to manually list the dependencies here instead. The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`. From 01a7c2d6df9158471a5ef3c35940b23fe654f864 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Thu, 16 Jan 2020 17:30:14 +0100 Subject: [PATCH 4/8] reorder before_test --- README.md | 2 +- cibuildwheel/linux.py | 2 +- cibuildwheel/macos.py | 2 +- cibuildwheel/windows.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9c7ecb59..08159b81 100644 --- a/README.md +++ b/README.md @@ -104,9 +104,9 @@ Options | | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each (non-pure Python) built wheel | | | [`CIBW_MANYLINUX_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) [`CIBW_MANYLINUX_I686_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) [`CIBW_MANYLINUX_PYPY_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) | Specify alternative manylinux docker images | | **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel | +| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute shell command to prepare test environment | | | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests | | | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require | -| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute shell command to prepare test environment | | **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Increase/decrease the output of pip wheel | Working examples diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 753da624..39494ef9 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -68,7 +68,7 @@ def get_python_configurations(build_selector): return [c for c in python_configurations if matches_platform(c.identifier) and build_selector(c.identifier)] -def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test, manylinux_images): +def build(project_dir, output_dir, test_command, before_test, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images): try: subprocess.check_call(['docker', '--version']) except Exception: diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 50b6392a..7b2ba8a9 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -105,7 +105,7 @@ def install_pypy(version, url): return installation_bin_path -def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test): +def build(project_dir, output_dir, test_command, before_test, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment): abs_project_dir = os.path.abspath(project_dir) temp_dir = tempfile.mkdtemp(prefix='cibuildwheel') built_wheel_dir = os.path.join(temp_dir, 'built_wheel') diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index 15a53209..7a4edbe1 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -87,7 +87,7 @@ def install_pypy(version, arch, url): return installation_path -def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test): +def build(project_dir, output_dir, test_command, before_test, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment): abs_project_dir = os.path.abspath(project_dir) temp_dir = tempfile.mkdtemp(prefix='cibuildwheel') built_wheel_dir = os.path.join(temp_dir, 'built_wheel') From d613a8c1a63525a5e58ec2c3b190995359d067f7 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Mon, 20 Jan 2020 00:03:28 +0100 Subject: [PATCH 5/8] remove clean files from setup.py, fixes in doc --- docs/options.md | 12 ++++++------ test/10_before_test/setup.py | 10 ---------- test/10_before_test/test/spam_test.py | 3 ++- unit_test/main_options_test.py | 2 +- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/docs/options.md b/docs/options.md index dff21fe4..b1d64042 100644 --- a/docs/options.md +++ b/docs/options.md @@ -343,8 +343,8 @@ CIBW_TEST_EXTRAS: test,qt ### `CIBW_BEFORE_TEST` {: #before-test} > Execute a shell command before testing each wheel -A shell command to run in **each** test virtual environment, before your wheel is installed and tested. This is useful if you need to install non pip package, change values of environment variables -or perform multi step pip installation (like install `scikit-build` or `cython` before install test package) +A shell command to run in **each** test virtual environment, before your wheel is installed and tested. This is useful if you need to install a non pip package, change values of environment variables +or perform multi step pip installation (e.g. installing `scikit-build` or `cython` before install test package) The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`. @@ -356,14 +356,14 @@ Platform-specific variants also available:
#### Examples ```yaml -# install packages needed to build test dependencies -CIBW_BEFORE_TEST: pip install cmake scikit-build - # install test dependencies with overwritten environment variables. CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt # chain commands using && -CIBW_BEFORE_TEST: yum install -y libffi-dev && pip install . +CIBW_BEFORE_TEST : rm -rf ./data/cache && mkdir -p ./data/cache + +# install python packages that are required to install test dependencies +CIBW_BEFORE_TEST: pip install cmake scikit-build ``` ## Other diff --git a/test/10_before_test/setup.py b/test/10_before_test/setup.py index 8abc7921..7bdeac0b 100644 --- a/test/10_before_test/setup.py +++ b/test/10_before_test/setup.py @@ -1,16 +1,6 @@ from setuptools import setup, Extension import sys, os -# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step -# is the same one as is currently running. -version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt' -if os.path.exists(version_file): - os.remove(version_file) - -# check that the executable also was written -executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' -if os.path.exists(executable_file): - os.remove(executable_file) setup( name="spam", diff --git a/test/10_before_test/test/spam_test.py b/test/10_before_test/test/spam_test.py index 7560b438..f5d9d605 100644 --- a/test/10_before_test/test/spam_test.py +++ b/test/10_before_test/test/spam_test.py @@ -4,8 +4,9 @@ from unittest import TestCase class TestBeforeTest(TestCase): def test_version(self): - # assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step + # assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_TEST step # is the same one as is currently running. + # because of use symlinks in MacOS run this test is also need version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt' with open(version_file) as f: stored_version = f.read() diff --git a/unit_test/main_options_test.py b/unit_test/main_options_test.py index 99387bf5..73545d61 100644 --- a/unit_test/main_options_test.py +++ b/unit_test/main_options_test.py @@ -218,4 +218,4 @@ def test_before_test(before_test, platform_specific, platform, intercepted_build main() - assert intercepted_build_args.kwargs['before_test'] == before_test \ No newline at end of file + assert intercepted_build_args.kwargs['before_test'] == before_test From baba7706e0b824a5ecab84274f51b09f24eb2ce3 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Mon, 20 Jan 2020 00:25:30 +0100 Subject: [PATCH 6/8] add example with non pip python package --- docs/options.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/options.md b/docs/options.md index b1d64042..0aabadc0 100644 --- a/docs/options.md +++ b/docs/options.md @@ -362,6 +362,9 @@ CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt # chain commands using && CIBW_BEFORE_TEST : rm -rf ./data/cache && mkdir -p ./data/cache +# install non pip python package +CIBW_BEFORE_TEST: cd some_dir; ./configure; make; make install + # install python packages that are required to install test dependencies CIBW_BEFORE_TEST: pip install cmake scikit-build ``` From 79cf7e47aed8721a0b6d9f327b81bac0649fe1c9 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Fri, 28 Feb 2020 19:05:02 +0100 Subject: [PATCH 7/8] fix test after rebase, fix typos in readme --- README.md | 2 +- cibuildwheel/linux.py | 2 +- .../cibuildwheel_test.py | 1 + .../setup.py | 1 - .../{10_before_test => 11_before_test}/spam.c | 0 .../test/spam_test.py | 9 +- unit_test/main_options_test.py | 221 ------------------ 7 files changed, 9 insertions(+), 227 deletions(-) rename test/{10_before_test => 11_before_test}/cibuildwheel_test.py (99%) rename test/{10_before_test => 11_before_test}/setup.py (90%) rename test/{10_before_test => 11_before_test}/spam.c (100%) rename test/{10_before_test => 11_before_test}/test/spam_test.py (82%) delete mode 100644 unit_test/main_options_test.py diff --git a/README.md b/README.md index 08159b81..aa843107 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ Options | | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute shell command to prepare test environment | | | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests | | | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require | -| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Increase/decrease the output of pip wheel | +| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel | Working examples ---------------- diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 39494ef9..3113f309 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -206,7 +206,7 @@ def build(project_dir, output_dir, test_command, before_test, test_requires, tes environment_exports='\n'.join(environment.as_shell_commands()), uid=os.getuid(), gid=os.getgid(), - before_test=shlex_quote( + before_test=shlex.quote( prepare_command(before_test, project='/project') if before_test else '' ), ) diff --git a/test/10_before_test/cibuildwheel_test.py b/test/11_before_test/cibuildwheel_test.py similarity index 99% rename from test/10_before_test/cibuildwheel_test.py rename to test/11_before_test/cibuildwheel_test.py index f6a56af4..7db1b127 100644 --- a/test/10_before_test/cibuildwheel_test.py +++ b/test/11_before_test/cibuildwheel_test.py @@ -1,6 +1,7 @@ import os import utils + def test(): project_dir = os.path.dirname(__file__) diff --git a/test/10_before_test/setup.py b/test/11_before_test/setup.py similarity index 90% rename from test/10_before_test/setup.py rename to test/11_before_test/setup.py index 7bdeac0b..e3ea2938 100644 --- a/test/10_before_test/setup.py +++ b/test/11_before_test/setup.py @@ -1,5 +1,4 @@ from setuptools import setup, Extension -import sys, os setup( diff --git a/test/10_before_test/spam.c b/test/11_before_test/spam.c similarity index 100% rename from test/10_before_test/spam.c rename to test/11_before_test/spam.c diff --git a/test/10_before_test/test/spam_test.py b/test/11_before_test/test/spam_test.py similarity index 82% rename from test/10_before_test/test/spam_test.py rename to test/11_before_test/test/spam_test.py index f5d9d605..e25cc0c7 100644 --- a/test/10_before_test/test/spam_test.py +++ b/test/11_before_test/test/spam_test.py @@ -1,4 +1,5 @@ -import sys, os +import sys +import os from unittest import TestCase @@ -21,5 +22,7 @@ class TestBeforeTest(TestCase): stored_executable = f.read() print('stored_executable', stored_executable) print('sys.executable', sys.executable) - # windows/mac are case insensitive - assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower() + # Works around path-comparison bugs caused by short-paths on Windows e.g. + # vssadm~1 instead of vssadministrator + + assert os.stat(stored_executable) == os.stat(sys.executable) diff --git a/unit_test/main_options_test.py b/unit_test/main_options_test.py deleted file mode 100644 index 73545d61..00000000 --- a/unit_test/main_options_test.py +++ /dev/null @@ -1,221 +0,0 @@ -import pytest - -import sys - -from cibuildwheel.__main__ import main -from cibuildwheel.environment import ParsedEnvironment -from cibuildwheel.util import BuildSelector - -from main_util_fixtures import mock_protection, fake_project_dir, platform, intercepted_build_args - - - -# CIBW_PLATFORM is tested in main_platform_test.py - - -def test_output_dir(platform, intercepted_build_args, monkeypatch): - OUTPUT_DIR = 'some_output_dir' - - monkeypatch.setenv('CIBW_OUTPUT_DIR', OUTPUT_DIR) - - main() - - assert intercepted_build_args.kwargs['output_dir'] == OUTPUT_DIR - - -def test_output_dir_default(platform, intercepted_build_args, monkeypatch): - main() - - assert intercepted_build_args.kwargs['output_dir'] == 'wheelhouse' - - -@pytest.mark.parametrize('also_set_environment', [False, True]) -def test_output_dir_argument(also_set_environment, platform, intercepted_build_args, monkeypatch): - OUTPUT_DIR = 'some_output_dir' - - monkeypatch.setattr(sys, 'argv', sys.argv + ['--output-dir', OUTPUT_DIR]) - if also_set_environment: - monkeypatch.setenv('CIBW_OUTPUT_DIR', 'not_this_output_dir') - - main() - - assert intercepted_build_args.kwargs['output_dir'] == OUTPUT_DIR - - -def test_build_selector(platform, intercepted_build_args, monkeypatch): - BUILD = 'some build* *-selector' - SKIP = 'some skip* *-selector' - - monkeypatch.setenv('CIBW_BUILD', BUILD) - monkeypatch.setenv('CIBW_SKIP', SKIP) - - main() - - intercepted_build_selector = intercepted_build_args.kwargs['build_selector'] - assert isinstance(intercepted_build_selector, BuildSelector) - assert intercepted_build_selector('build-this') - assert not intercepted_build_selector('skip-that') - # This unit test is just testing the options of 'main' - # Unit tests for BuildSelector are in build_selector_test.py - - -@pytest.mark.parametrize('architecture, image, full_image', [ - ('x86_64', None, 'quay.io/pypa/manylinux2010_x86_64'), - ('x86_64', 'manylinux1', 'quay.io/pypa/manylinux1_x86_64'), - ('x86_64', 'manylinux2010', 'quay.io/pypa/manylinux2010_x86_64'), - ('x86_64', 'manylinux2014', 'quay.io/pypa/manylinux2014_x86_64'), - ('x86_64', 'custom_image', 'custom_image'), - ('i686', None, 'quay.io/pypa/manylinux2010_i686'), - ('i686', 'manylinux1', 'quay.io/pypa/manylinux1_i686'), - ('i686', 'manylinux2010', 'quay.io/pypa/manylinux2010_i686'), - ('i686', 'manylinux2014', 'quay.io/pypa/manylinux2014_i686'), - ('i686', 'custom_image', 'custom_image'), -]) -def test_manylinux_images(architecture, image, full_image, platform, intercepted_build_args, monkeypatch): - if image is not None: - monkeypatch.setenv('CIBW_MANYLINUX_' + architecture.upper() + '_IMAGE', image) - - main() - - if platform == 'linux': - assert intercepted_build_args.kwargs['manylinux_images'][architecture] == full_image - else: - assert 'manylinux_images' not in intercepted_build_args.kwargs - - -def get_default_repair_command(platform): - if platform == 'linux': - return 'auditwheel repair -w {dest_dir} {wheel}' - elif platform == 'macos': - return 'delocate-listdeps {wheel} && delocate-wheel -w {dest_dir} {wheel}' - elif platform == 'windows': - return '' - else: - raise ValueError('Unknown platform', platform) - -@pytest.mark.parametrize('repair_command', [None, 'repair', 'repair -w {dest_dir} {wheel}']) -@pytest.mark.parametrize('platform_specific', [False, True]) -def test_repair_command(repair_command, platform_specific, platform, intercepted_build_args, monkeypatch): - if repair_command is not None: - if platform_specific: - monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND_' + platform.upper(), repair_command) - monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND', 'overwritten') - else: - monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND', repair_command) - - main() - - expected_repair = repair_command or get_default_repair_command(platform) - assert intercepted_build_args.kwargs['repair_command'] == expected_repair - - -@pytest.mark.parametrize('environment', [ - {}, - {'something': 'value'}, - {'something': 'value', 'something_else': 'other_value'} -]) -@pytest.mark.parametrize('platform_specific', [False, True]) -def test_environment(environment, platform_specific, platform, intercepted_build_args, monkeypatch): - env_string = ' '.join(['{}={}'.format(k, v) for k, v in environment.items()]) - if platform_specific: - monkeypatch.setenv('CIBW_ENVIRONMENT_' + platform.upper(), env_string) - monkeypatch.setenv('CIBW_ENVIRONMENT', 'overwritten') - else: - monkeypatch.setenv('CIBW_ENVIRONMENT', env_string) - - main() - - intercepted_environment = intercepted_build_args.kwargs['environment'] - assert isinstance(intercepted_environment, ParsedEnvironment) - assert intercepted_environment.as_dictionary(prev_environment={}) == environment - - -@pytest.mark.parametrize('test_requires', [None, 'requirement other_requirement']) -@pytest.mark.parametrize('platform_specific', [False, True]) -def test_test_requires(test_requires, platform_specific, platform, intercepted_build_args, monkeypatch): - if test_requires is not None: - if platform_specific: - monkeypatch.setenv('CIBW_TEST_REQUIRES_' + platform.upper(), test_requires) - monkeypatch.setenv('CIBW_TEST_REQUIRES', 'overwritten') - else: - monkeypatch.setenv('CIBW_TEST_REQUIRES', test_requires) - - main() - - assert intercepted_build_args.kwargs['test_requires'] == (test_requires or '').split() - - -@pytest.mark.parametrize('test_extras', [None, 'extras']) -@pytest.mark.parametrize('platform_specific', [False, True]) -def test_test_extras(test_extras, platform_specific, platform, intercepted_build_args, monkeypatch): - if test_extras is not None: - if platform_specific: - monkeypatch.setenv('CIBW_TEST_EXTRAS_' + platform.upper(), test_extras) - monkeypatch.setenv('CIBW_TEST_EXTRAS', 'overwritten') - else: - monkeypatch.setenv('CIBW_TEST_EXTRAS', test_extras) - - main() - - assert intercepted_build_args.kwargs['test_extras'] == ('[' + test_extras + ']' if test_extras else '') - - -@pytest.mark.parametrize('test_command', [None, 'test --command']) -@pytest.mark.parametrize('platform_specific', [False, True]) -def test_test_command(test_command, platform_specific, platform, intercepted_build_args, monkeypatch): - if test_command is not None: - if platform_specific: - monkeypatch.setenv('CIBW_TEST_COMMAND_' + platform.upper(), test_command) - monkeypatch.setenv('CIBW_TEST_COMMAND', 'overwritten') - else: - monkeypatch.setenv('CIBW_TEST_COMMAND', test_command) - - main() - - assert intercepted_build_args.kwargs['test_command'] == test_command - - -@pytest.mark.parametrize('before_build', [None, 'before --build']) -@pytest.mark.parametrize('platform_specific', [False, True]) -def test_before_build(before_build, platform_specific, platform, intercepted_build_args, monkeypatch): - if before_build is not None: - if platform_specific: - monkeypatch.setenv('CIBW_BEFORE_BUILD_' + platform.upper(), before_build) - monkeypatch.setenv('CIBW_BEFORE_BUILD', 'overwritten') - else: - monkeypatch.setenv('CIBW_BEFORE_BUILD', before_build) - - main() - - assert intercepted_build_args.kwargs['before_build'] == before_build - - -@pytest.mark.parametrize('build_verbosity', [None, 0, 2, -2, 4, -4]) -@pytest.mark.parametrize('platform_specific', [False, True]) -def test_build_verbosity(build_verbosity, platform_specific, platform, intercepted_build_args, monkeypatch): - if build_verbosity is not None: - if platform_specific: - monkeypatch.setenv('CIBW_BUILD_VERBOSITY_' + platform.upper(), str(build_verbosity)) - monkeypatch.setenv('CIBW_BUILD_VERBOSITY', 'overwritten') - else: - monkeypatch.setenv('CIBW_BUILD_VERBOSITY', str(build_verbosity)) - - main() - - expected_verbosity = max(-3, min(3, int(build_verbosity or 0))) - assert intercepted_build_args.kwargs['build_verbosity'] == expected_verbosity - - -@pytest.mark.parametrize('before_test', ["", 'before --test']) -@pytest.mark.parametrize('platform_specific', [False, True]) -def test_before_test(before_test, platform_specific, platform, intercepted_build_args, monkeypatch): - if before_test is not None: - if platform_specific: - monkeypatch.setenv('CIBW_BEFORE_TEST_' + platform.upper(), before_test) - monkeypatch.setenv('CIBW_BEFORE_TEST', 'overwritten') - else: - monkeypatch.setenv('CIBW_BEFORE_TEST', before_test) - - main() - - assert intercepted_build_args.kwargs['before_test'] == before_test From 7e566e46eee4b37c54bfa7881b50c3676091cad5 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Sun, 8 Mar 2020 14:25:36 +0100 Subject: [PATCH 8/8] uses sys.prefix instead of sys.executable in before_test --- test/11_before_test/cibuildwheel_test.py | 4 ++-- test/11_before_test/test/spam_test.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/11_before_test/cibuildwheel_test.py b/test/11_before_test/cibuildwheel_test.py index 7db1b127..5aa1c4ca 100644 --- a/test/11_before_test/cibuildwheel_test.py +++ b/test/11_before_test/cibuildwheel_test.py @@ -9,8 +9,8 @@ def test(): actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ # write python version information to a temporary file, this is # checked in setup.py - 'CIBW_BEFORE_TEST': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)"''', - 'CIBW_BEFORE_TEST_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)"''', + 'CIBW_BEFORE_TEST': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonprefix.txt', 'w').write(sys.prefix)"''', + 'CIBW_BEFORE_TEST_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonprefix.txt', 'w').write(sys.prefix)"''', 'CIBW_TEST_REQUIRES': 'nose', # the 'false ||' bit is to ensure this command runs in a shell on # mac/linux. diff --git a/test/11_before_test/test/spam_test.py b/test/11_before_test/test/spam_test.py index e25cc0c7..21bad8c2 100644 --- a/test/11_before_test/test/spam_test.py +++ b/test/11_before_test/test/spam_test.py @@ -15,14 +15,14 @@ class TestBeforeTest(TestCase): print('sys.version', sys.version) assert stored_version == sys.version - def test_executable(self): - # check that the executable also was written - executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' - with open(executable_file) as f: - stored_executable = f.read() - print('stored_executable', stored_executable) - print('sys.executable', sys.executable) + def test_prefix(self): + # check that the prefix also was written + prefix_file = 'c:\\pythonprefix.txt' if sys.platform == 'win32' else '/tmp/pythonprefix.txt' + with open(prefix_file) as f: + stored_prefix = f.read() + print('stored_prefix', stored_prefix) + print('sys.prefix', sys.prefix) # Works around path-comparison bugs caused by short-paths on Windows e.g. # vssadm~1 instead of vssadministrator - assert os.stat(stored_executable) == os.stat(sys.executable) + assert os.stat(stored_prefix) == os.stat(sys.prefix)