From e67b3bc6117300b62ab50dd09a31c21c0d3ea20d Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Sat, 7 Sep 2019 17:17:21 +0100 Subject: [PATCH 1/3] Added support for CIBW_TEST_EXTRAS to allow extras_require to be used to install test dependencies --- README.md | 20 ++++++++++++++++++++ cibuildwheel/__main__.py | 5 +++++ cibuildwheel/linux.py | 4 ++-- cibuildwheel/macos.py | 4 ++-- cibuildwheel/windows.py | 4 ++-- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 171b397b..714692f7 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,7 @@ All being well, you should get wheels delivered to you in a few minutes. | | `CIBW_MANYLINUX1_I686_IMAGE` | Specify an alternative manylinux1 i686 docker image | | **Tests** | `CIBW_TEST_COMMAND` | Execute a shell command to test all built wheels | | | `CIBW_TEST_REQUIRES` | Install Python dependencies before running the tests | +| | `CIBW_TEST_EXTRAS` | Install Python dependencies before running the tests using ``extras_require``| A more detailed description of the options, the allowed values, and some examples can be found in the [Options](#options) section. @@ -412,6 +413,25 @@ Example: `nose==1.3.7 moto==0.4.31` Platform-specific variants also available: `CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX` +*** + +| Environment variable: `CIBW_TEST_EXTRAS` +| --- + +Optional. + +Comma-separated list of +[extras_require](https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies) +options that should be included when installing the wheel prior to running the +tests. This can be used to avoid having to redefine test dependencies in +``CIBW_TEST_REQUIRES`` if they are already defined in ``setup.py`` or +``setup.cfg``. + +Example: `test,qt` (will cause the wheel to be installed with ``pip install [test,qt]) + + +Platform-specific variants also available: +`CIBW_TEST_EXTRAS_MACOS` | `CIBW_TEST_EXTRAS_WINDOWS` | `CIBW_TEST_EXTRAS_LINUX` ### Example YML syntax diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 0b4342c6..516f0d69 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -91,12 +91,16 @@ def main(): output_dir = args.output_dir test_command = get_option_from_environment('CIBW_TEST_COMMAND', platform=platform) test_requires = get_option_from_environment('CIBW_TEST_REQUIRES', platform=platform, default='').split() + test_extras = get_option_from_environment('CIBW_TEST_EXTRAS', platform=platform, default='') project_dir = args.project_dir before_build = get_option_from_environment('CIBW_BEFORE_BUILD', platform=platform) build_verbosity = get_option_from_environment('CIBW_BUILD_VERBOSITY', platform=platform, default='') build_config, skip_config = os.environ.get('CIBW_BUILD', '*'), os.environ.get('CIBW_SKIP', '') environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='') + if test_extras: + test_extras = '[{0}]'.format(test_extras) + try: build_verbosity = min(3, max(-3, int(build_verbosity))) except ValueError: @@ -129,6 +133,7 @@ def main(): output_dir=output_dir, test_command=test_command, test_requires=test_requires, + test_extras=test_extras, before_build=before_build, build_verbosity=build_verbosity, build_selector=build_selector, diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index a43d47dc..b5954330 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -30,7 +30,7 @@ def get_python_configurations(build_selector): return [c for c in python_configurations if build_selector(c.identifier)] -def build(project_dir, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment, manylinux1_images): +def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment, manylinux1_images): try: subprocess.check_call(['docker', '--version']) except: @@ -86,7 +86,7 @@ def build(project_dir, output_dir, test_command, test_requires, before_build, bu delocated_wheel=(/tmp/delocated_wheel/*.whl) # Install the wheel we just built - "$PYBIN/pip" install "$delocated_wheel" + "$PYBIN/pip" install "$delocated_wheel"{test_extras} # Install any requirements to run the tests if [ ! -z "{test_requires}" ]; then diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index b27f9699..0c687eeb 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -24,7 +24,7 @@ def get_python_configurations(build_selector): return [c for c in python_configurations if build_selector(c.identifier)] -def build(project_dir, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment): +def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment): python_configurations = get_python_configurations(build_selector) get_pip_url = 'https://bootstrap.pypa.io/get-pip.py' get_pip_script = '/tmp/get-pip.py' @@ -121,7 +121,7 @@ def build(project_dir, output_dir, test_command, test_requires, before_build, bu delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0] # install the wheel - call(['pip', 'install', delocated_wheel], env=env) + call(['pip', 'install', delocated_wheel + test_extras], env=env) # test the wheel if test_requires: diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index e48a11c5..13fd4f54 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -56,7 +56,7 @@ def get_python_configurations(build_selector): return [c for c in python_configurations if build_selector(c.identifier)] -def build(project_dir, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment): +def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment): if IS_RUNNING_ON_AZURE: def shell(args, env=None, cwd=None): print('+ ' + ' '.join(args)) @@ -122,7 +122,7 @@ def build(project_dir, output_dir, test_command, test_requires, before_build, bu built_wheel = glob(built_wheel_dir+'/*.whl')[0] # install the wheel - shell(['pip', 'install', built_wheel], env=env) + shell(['pip', 'install', built_wheel + test_extras], env=env) # test the wheel if test_requires: From 45fcebf9d8f1ba7762830f80947cc01d9d0a4369 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Sat, 7 Sep 2019 17:24:03 +0100 Subject: [PATCH 2/3] Fix issue on linux --- cibuildwheel/linux.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index b5954330..473838b0 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -107,6 +107,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef '''.format( pybin_paths=' '.join(c.path+'/bin' for c in platform_configs), test_requires=' '.join(test_requires), + test_extras=test_extras, test_command=shlex_quote( prepare_command(test_command, project='/project') if test_command else '' ), From 4f4fed06e0228819960ab4915af151764861d3f0 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Sat, 7 Sep 2019 17:38:31 +0100 Subject: [PATCH 3/3] Added unit test for CIBW_TEST_EXTRAS --- test/02_test/cibuildwheel_test.py | 20 +++++++++++++++++++- test/02_test/setup.py | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index aa1de0fd..54973573 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -12,7 +12,25 @@ def test(): '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') + actual_wheels = os.listdir('wheelhouse') + assert set(actual_wheels) == set(expected_wheels) + + +def test_extras_require(): + project_dir = os.path.dirname(__file__) + + # build and test the wheels + utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_TEST_EXTRAS': 'test', + # 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') actual_wheels = os.listdir('wheelhouse') diff --git a/test/02_test/setup.py b/test/02_test/setup.py index 866fa22c..1609aad6 100644 --- a/test/02_test/setup.py +++ b/test/02_test/setup.py @@ -3,5 +3,6 @@ from setuptools import setup, Extension setup( name="spam", ext_modules=[Extension('spam', sources=['spam.c'])], + extras_require={'test': ['nose']}, version="0.1.0", )