diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 473838b0..ddcec627 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -85,19 +85,36 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef fi delocated_wheel=(/tmp/delocated_wheel/*.whl) - # Install the wheel we just built - "$PYBIN/pip" install "$delocated_wheel"{test_extras} - - # Install any requirements to run the tests - if [ ! -z "{test_requires}" ]; then - "$PYBIN/pip" install {test_requires} - fi - - # Run the tests from a different directory if [ ! -z {test_command} ]; then - pushd $HOME - PATH="$PYBIN:$PATH" sh -c {test_command} - popd + # Set up a virtual environment to install and test from, to make sure + # there are no dependencies that were pulled in at build time. + "$PYBIN/pip" install virtualenv + venv_dir=`mktemp -d`/venv + "$PYBIN/python" -m virtualenv "$venv_dir" + + # run the tests in a subshell to keep that `activate` + # script from polluting the env + ( + source "$venv_dir/bin/activate" + + echo "Running tests using `which python`" + + # Install the wheel we just built + pip install "$delocated_wheel"{test_extras} + + # Install any requirements to run the tests + if [ ! -z "{test_requires}" ]; then + pip install {test_requires} + fi + + # Run the tests from a different directory + pushd $HOME + sh -c {test_command} + popd + ) + + # clean up + rm -rf "$venv_dir" fi # we're all done here; move it to output diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 61a432e0..2709cc1a 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -1,4 +1,5 @@ from __future__ import print_function +import tempfile import os, subprocess, shlex, sys, shutil from collections import namedtuple from glob import glob @@ -120,18 +121,40 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef call(['delocate-wheel', '-w', '/tmp/delocated_wheel', built_wheel], env=env) delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0] - # install the wheel - call(['pip', 'install', delocated_wheel + test_extras], env=env) - - # test the wheel - if test_requires: - call(['pip', 'install'] + test_requires, env=env) if test_command: + # set up a virtual environment to install and test from, to make sure + # there are no dependencies that were pulled in at build time. + call(['pip', 'install', 'virtualenv'], env=env) + venv_dir = tempfile.mkdtemp() + call(['python', '-m', 'virtualenv', venv_dir], env=env) + + virtualenv_env = env.copy() + virtualenv_env['PATH'] = os.pathsep.join([ + os.path.join(venv_dir, 'bin'), + virtualenv_env['PATH'], + ]) + # Fix some weird issue with the shebang of installed scripts + # See https://github.com/theacodes/nox/issues/44 and https://github.com/pypa/virtualenv/issues/620 + virtualenv_env.pop('__PYVENV_LAUNCHER__', None) + + # check that we are using the Python from the virtual environment + call(['which', 'python'], env=virtualenv_env) + + # install the wheel + call(['pip', 'install', delocated_wheel + test_extras], env=virtualenv_env) + + # test the wheel + if test_requires: + call(['pip', 'install'] + test_requires, env=virtualenv_env) + # run the tests from $HOME, with an absolute path in the command # (this ensures that Python runs the tests against the installed wheel # and not the repo code) test_command_prepared = prepare_command(test_command, project=abs_project_dir) - call(test_command_prepared, cwd=os.environ['HOME'], env=env, shell=True) + call(test_command_prepared, cwd=os.environ['HOME'], env=virtualenv_env, shell=True) + + # clean up + shutil.rmtree(venv_dir) # we're all done here; move it to output (overwrite existing) dst = os.path.join(output_dir, os.path.basename(delocated_wheel)) diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index 13fd4f54..a25dab69 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -121,18 +121,37 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef shell(['pip', 'wheel', abs_project_dir, '-w', built_wheel_dir, '--no-deps'] + get_build_verbosity_extra_flags(build_verbosity), env=env) built_wheel = glob(built_wheel_dir+'/*.whl')[0] - # install the wheel - shell(['pip', 'install', built_wheel + test_extras], env=env) - - # test the wheel - if test_requires: - shell(['pip', 'install'] + test_requires, env=env) if test_command: + # set up a virtual environment to install and test from, to make sure + # there are no dependencies that were pulled in at build time. + shell(['pip', 'install', 'virtualenv'], env=env) + venv_dir = tempfile.mkdtemp() + shell(['python', '-m', 'virtualenv', venv_dir], env=env) + + virtualenv_env = env.copy() + virtualenv_env['PATH'] = os.pathsep.join([ + os.path.join(venv_dir, 'Scripts'), + virtualenv_env['PATH'], + ]) + + # check that we are using the Python from the virtual environment + shell(['which', 'python'], env=virtualenv_env) + + # install the wheel + shell(['pip', 'install', built_wheel + test_extras], env=virtualenv_env) + + # test the wheel + if test_requires: + shell(['pip', 'install'] + test_requires, env=virtualenv_env) + # run the tests from c:\, with an absolute path in the command # (this ensures that Python runs the tests against the installed wheel # and not the repo code) test_command_prepared = prepare_command(test_command, project=abs_project_dir) - shell([test_command_prepared], cwd='c:\\', env=env) + shell([test_command_prepared], cwd='c:\\', env=virtualenv_env) + + # clean up + shutil.rmtree(venv_dir) # we're all done here; move it to output (remove if already exists) dst = os.path.join(output_dir, os.path.basename(built_wheel))