Add ability to pin different dependencies for each python version

This commit is contained in:
Joe Rickerby
2020-02-02 17:30:27 +00:00
parent 076987cb7e
commit b9607ffae7
8 changed files with 94 additions and 24 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ subprocess.check_call([
'--generate-hashes',
'--upgrade',
'cibuildwheel/resources/constraints.in',
'--output-file', 'cibuildwheel/resources/constraints-python2.txt'
'--output-file', 'cibuildwheel/resources/constraints-python27.txt'
])
Image = namedtuple('Image', ['manylinux_version', 'arch'])
+5 -6
View File
@@ -4,7 +4,7 @@ import argparse, os, subprocess, sys, textwrap
import cibuildwheel
import cibuildwheel.linux, cibuildwheel.windows, cibuildwheel.macos
from cibuildwheel.environment import parse_environment, EnvironmentParseError
from cibuildwheel.util import BuildSelector, Unbuffered
from cibuildwheel.util import BuildSelector, DependencyConstraints, Unbuffered
def get_option_from_environment(option_name, platform=None, default=None):
'''
@@ -102,15 +102,14 @@ 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='')
dependency_versions = get_option_from_environment('CIBW_DEPENDENCY_VERSIONS', platform=platform, default='pinned')
if dependency_versions == 'pinned':
dependency_constraints = os.path.join(
os.path.dirname(__file__), 'resources', 'constraints.txt'
)
dependency_constraints = DependencyConstraints.with_defaults()
elif dependency_versions == 'latest':
dependency_constraints = ''
dependency_constraints = None
else:
dependency_constraints = dependency_versions
dependency_constraints = DependencyConstraints(dependency_versions)
if test_extras:
test_extras = '[{0}]'.format(test_extras)
+16 -14
View File
@@ -10,20 +10,20 @@ except ImportError:
def get_python_configurations(build_selector):
PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path'])
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'path'])
python_configurations = [
PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'),
PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'),
PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'),
PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'),
PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'),
PythonConfiguration(identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'),
PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'),
PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'),
PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'),
PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'),
PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'),
PythonConfiguration(identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'),
PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'),
PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'),
PythonConfiguration(version='3.5', identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'),
PythonConfiguration(version='3.6', identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'),
PythonConfiguration(version='3.7', identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'),
PythonConfiguration(version='3.8', identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'),
PythonConfiguration(version='2.7', identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'),
PythonConfiguration(version='2.7', identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'),
PythonConfiguration(version='3.5', identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'),
PythonConfiguration(version='3.6', identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'),
PythonConfiguration(version='3.7', identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'),
PythonConfiguration(version='3.8', identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'),
]
# skip builds as required
@@ -79,7 +79,9 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
for config in platform_configs:
if dependency_constraints:
run_docker(['cp', os.path.abspath(dependency_constraints), container_name + ':/constraints.txt'])
constraints_file = dependency_constraints.get_for_python_version(config.version)
run_docker(['cp', os.path.abspath(constraints_file), container_name + ':/constraints.txt'])
run_docker(['start', '-i', '-a', container_name], stdin_str='''
set -o errexit
set -o xtrace
+5 -1
View File
@@ -87,7 +87,11 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
call(['which', 'python'], env=env)
call(['python', '--version'], env=env)
dependency_constraint_flags = ['-c', dependency_constraints] if dependency_constraints else []
dependency_constraint_flags = []
if dependency_constraints:
dependency_constraint_flags = [
'-c', dependency_constraints.get_for_python_version(config.version)
]
# install pip & wheel
call(['python', get_pip_script, '--no-setuptools', '--no-wheel'] + dependency_constraint_flags, env=env, cwd="/tmp")
@@ -0,0 +1,29 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# bin/update_constraints
#
auditwheel==2.1.1 \
--hash=sha256:d9f0f47c0ecdf4f72316eabfb19223b81aec95f0deba97729e9c09ea4f2c166e \
--hash=sha256:f60e265dc168ae7c9d65a814410881c5ca170d88644c178f8e3aa20eecd0fae1
delocate==0.8.0 \
--hash=sha256:ac9f4d8d28b2582d94f764db0d72a1fe3c42ab8212e9b780168455de385d5b95
pyelftools==0.26 \
--hash=sha256:86ac6cee19f6c945e8dedf78c6ee74f1112bd14da5a658d8c9d4103aed5756a2 \
--hash=sha256:cc0ea0de82b240a73ef4056fce44acbb4727dca7d66759371aff2bad457ed711 \
# via auditwheel
virtualenv==16.7.9 \
--hash=sha256:0d62c70883c0342d59c11d0ddac0d954d0431321a41ab20851facf2b222598f3 \
--hash=sha256:55059a7a676e4e19498f1aad09b8313a38fcc0cdbe4fdddc0e9b06946d21b4bb
wheel==0.31.1 \
--hash=sha256:0a2e54558a0628f2145d2fc822137e322412115173e8a2ddbe1c9024338ae83c \
--hash=sha256:80044e51ec5bbf6c894ba0bc48d26a8c20a9ba629f4ca19ea26ecfcf87685f5f
# The following packages are considered to be unsafe in a requirements file:
pip==20.0.2 \
--hash=sha256:4ae14a42d8adba3205ebeb38aa68cfc0b6c346e1ae2e699a0b3bad4da19cef5c \
--hash=sha256:7db0c8ea4c7ea51c8049640e8e6e7fde949de672bfa4949920675563a5a6967f
setuptools==44.0.0 \
--hash=sha256:180081a244d0888b0065e18206950d603f6550721bd6f8c0a10221ed467dd78e \
--hash=sha256:e5baf7723e5bb8382fc146e33032b241efc63314211a3a120aaa55d62d2bb008
+25
View File
@@ -83,4 +83,29 @@ def download(url, dest):
response.close()
class DependencyConstraints(object):
def __init__(self, base_file_path):
assert os.path.exists(base_file_path)
self.base_file_path = base_file_path
@classmethod
def with_defaults(cls):
return cls(
base_file_path=os.path.join(os.path.dirname(__file__), 'resources', 'constraints.txt')
)
def get_for_python_version(self, version):
version_parts = version.split('.')
# try to find a version-specific dependency file e.g. if
# ./constraints.txt is the base, look for ./constraints-python27.txt
base, ext = os.path.splitext(self.base_file_path)
specific = base + '-{}{}'.format(version_parts[0], version_parts[1])
specific_file_path = specific + ext
if os.path.exists(specific_file_path):
return specific_file_path
else:
return self.base_file_path
get_pip_script = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'get-pip.py'))
+6 -2
View File
@@ -104,8 +104,12 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
simple_shell(['python', '--version'], env=env)
simple_shell(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)\"'], env=env)
dependency_constraint_flags = ['-c', dependency_constraints] if dependency_constraints else []
dependency_constraint_flags = []
if dependency_constraints:
dependency_constraint_flags = [
'-c', dependency_constraints.get_for_python_version(config.version)
]
# make sure pip is installed
if not os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe')):
simple_shell(['python', get_pip_script] + dependency_constraint_flags, env=env, cwd="C:\\cibw")
+7
View File
@@ -285,6 +285,13 @@ To control the versions of dependencies yourself, you can supply a [pip
constraints](https://pip.pypa.io/en/stable/user_guide/#constraints-files) file
here and it will be used instead.
!!! note
If you need different dependencies for each python version, provide them
in the same folder with a `-pythonXY` suffix. e.g. if your
`CIBW_DEPENDENCY_VERSIONS=./constraints.txt`, cibuildwheel will use
`./constraints-python27.txt` on Python 2.7, or fallback to
`./constraints.txt` if that's not found.
Platform-specific variants also available:<br/>
`CIBW_DEPENDENCY_VERSIONS_MACOS` | `CIBW_DEPENDENCY_VERSIONS_WINDOWS` | `CIBW_DEPENDENCY_VERSIONS_LINUX`