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', '--generate-hashes',
'--upgrade', '--upgrade',
'cibuildwheel/resources/constraints.in', 'cibuildwheel/resources/constraints.in',
'--output-file', 'cibuildwheel/resources/constraints-python2.txt' '--output-file', 'cibuildwheel/resources/constraints-python27.txt'
]) ])
Image = namedtuple('Image', ['manylinux_version', 'arch']) Image = namedtuple('Image', ['manylinux_version', 'arch'])
+5 -6
View File
@@ -4,7 +4,7 @@ import argparse, os, subprocess, sys, textwrap
import cibuildwheel import cibuildwheel
import cibuildwheel.linux, cibuildwheel.windows, cibuildwheel.macos import cibuildwheel.linux, cibuildwheel.windows, cibuildwheel.macos
from cibuildwheel.environment import parse_environment, EnvironmentParseError 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): def get_option_from_environment(option_name, platform=None, default=None):
''' '''
@@ -102,15 +102,14 @@ def main():
repair_command_default = '' repair_command_default = ''
repair_command = get_option_from_environment('CIBW_REPAIR_WHEEL_COMMAND', platform=platform, default=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='') environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
dependency_versions = get_option_from_environment('CIBW_DEPENDENCY_VERSIONS', platform=platform, default='pinned') dependency_versions = get_option_from_environment('CIBW_DEPENDENCY_VERSIONS', platform=platform, default='pinned')
if dependency_versions == 'pinned': if dependency_versions == 'pinned':
dependency_constraints = os.path.join( dependency_constraints = DependencyConstraints.with_defaults()
os.path.dirname(__file__), 'resources', 'constraints.txt'
)
elif dependency_versions == 'latest': elif dependency_versions == 'latest':
dependency_constraints = '' dependency_constraints = None
else: else:
dependency_constraints = dependency_versions dependency_constraints = DependencyConstraints(dependency_versions)
if test_extras: if test_extras:
test_extras = '[{0}]'.format(test_extras) test_extras = '[{0}]'.format(test_extras)
+16 -14
View File
@@ -10,20 +10,20 @@ except ImportError:
def get_python_configurations(build_selector): def get_python_configurations(build_selector):
PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path']) PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'path'])
python_configurations = [ python_configurations = [
PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'), PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'),
PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'), PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'),
PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'), PythonConfiguration(version='3.5', identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'),
PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'), PythonConfiguration(version='3.6', identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'),
PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'), PythonConfiguration(version='3.7', identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'),
PythonConfiguration(identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'), PythonConfiguration(version='3.8', identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'),
PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'), PythonConfiguration(version='2.7', identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'),
PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'), PythonConfiguration(version='2.7', identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'),
PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'), PythonConfiguration(version='3.5', identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'),
PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'), PythonConfiguration(version='3.6', identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'),
PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'), PythonConfiguration(version='3.7', identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'),
PythonConfiguration(identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'), PythonConfiguration(version='3.8', identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'),
] ]
# skip builds as required # 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: for config in platform_configs:
if dependency_constraints: 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=''' run_docker(['start', '-i', '-a', container_name], stdin_str='''
set -o errexit set -o errexit
set -o xtrace 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(['which', 'python'], env=env)
call(['python', '--version'], 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 # install pip & wheel
call(['python', get_pip_script, '--no-setuptools', '--no-wheel'] + dependency_constraint_flags, env=env, cwd="/tmp") 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() 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')) 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', '--version'], env=env)
simple_shell(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)\"'], 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 # make sure pip is installed
if not os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe')): 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") 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 constraints](https://pip.pypa.io/en/stable/user_guide/#constraints-files) file
here and it will be used instead. 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/> Platform-specific variants also available:<br/>
`CIBW_DEPENDENCY_VERSIONS_MACOS` | `CIBW_DEPENDENCY_VERSIONS_WINDOWS` | `CIBW_DEPENDENCY_VERSIONS_LINUX` `CIBW_DEPENDENCY_VERSIONS_MACOS` | `CIBW_DEPENDENCY_VERSIONS_WINDOWS` | `CIBW_DEPENDENCY_VERSIONS_LINUX`