import re import pytest import textwrap import cibuildwheel.util from . import utils from . import test_projects project_with_expected_version_checks = test_projects.new_c_project( setup_py_add=textwrap.dedent(r''' import subprocess import os versions_output_text = subprocess.check_output( ['pip', 'freeze', '--all', '-qq'], universal_newlines=True, ) versions = versions_output_text.strip().splitlines() # `versions` now looks like: # ['pip==x.x.x', 'setuptools==x.x.x', 'wheel==x.x.x'] print('Gathered versions', versions) for package_name in ['pip', 'setuptools', 'wheel']: env_name = 'EXPECTED_{}_VERSION'.format(package_name.upper()) expected_version = os.environ[env_name] assert '{}=={}'.format(package_name, expected_version) in versions, ( 'error: {} version should equal {}'.format(package_name, expected_version) ) ''') ) VERSION_REGEX = r'([\w-]+)==([^\s]+)' def get_versions_from_constraint_file(constraint_file): constraint_file_text = constraint_file.read_text(encoding='utf8') versions = {} for package, version in re.findall(VERSION_REGEX, constraint_file_text): versions[package] = version return versions @pytest.mark.parametrize('python_version', ['2.7', '3.5', '3.6', '3.8']) def test_pinned_versions(tmp_path, python_version): if utils.platform == 'linux': pytest.skip('linux doesn\'t pin individual tool versions, it pins manylinux images instead') project_dir = tmp_path / 'project' project_with_expected_version_checks.generate(project_dir) build_environment = {} if python_version == '2.7': constraint_filename = 'constraints-python27.txt' build_pattern = '[cp]p27-*' elif python_version == '3.5': constraint_filename = 'constraints-python35.txt' build_pattern = '[cp]p35-*' elif python_version == '3.6': constraint_filename = 'constraints-python36.txt' build_pattern = '[cp]p36-*' else: constraint_filename = 'constraints.txt' build_pattern = '[cp]p38-*' constraint_file = cibuildwheel.util.resources_dir / constraint_filename constraint_versions = get_versions_from_constraint_file(constraint_file) for package in ['pip', 'setuptools', 'wheel', 'virtualenv']: env_name = f'EXPECTED_{package.upper()}_VERSION' build_environment[env_name] = constraint_versions[package] cibw_environment_option = ' '.join( [f'{k}={v}' for k, v in build_environment.items()] ) # build and test the wheels actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_BUILD': build_pattern, 'CIBW_ENVIRONMENT': cibw_environment_option, }) # also check that we got the right wheels if python_version == '2.7': expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') if '-cp27' in w or '-pp27' in w] elif python_version == '3.5': expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') if '-cp35' in w or '-pp35' in w] elif python_version == '3.6': expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') if '-cp36' in w or '-pp36' in w] elif python_version == '3.8': expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') if '-cp38' in w or '-pp38' in w] else: raise ValueError('unhandled python version') assert set(actual_wheels) == set(expected_wheels) @pytest.mark.parametrize('python_version', ['2.7', '3.x']) def test_dependency_constraints_file(tmp_path, python_version): if utils.platform == 'linux': pytest.skip('linux doesn\'t pin individual tool versions, it pins manylinux images instead') project_dir = tmp_path / 'project' project_with_expected_version_checks.generate(project_dir) tool_versions = { 'pip': '20.0.2', 'setuptools': '44.0.0' if python_version == '2.7' else '46.0.0', 'wheel': '0.34.2', 'virtualenv': '20.0.10', } constraints_file = tmp_path / 'constraints.txt' constraints_file.write_text(textwrap.dedent( ''' pip=={pip} setuptools=={setuptools} wheel=={wheel} virtualenv=={virtualenv} '''.format(**tool_versions) )) build_environment = {} for package_name, version in tool_versions.items(): env_name = f'EXPECTED_{package_name.upper()}_VERSION' build_environment[env_name] = version cibw_environment_option = ' '.join( [f'{k}={v}' for k, v in build_environment.items()] ) # build and test the wheels actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_BUILD': '[cp]p27-*' if python_version == '2.7' else '[cp]p3?-*', 'CIBW_ENVIRONMENT': cibw_environment_option, 'CIBW_DEPENDENCY_VERSIONS': str(constraints_file), }) # also check that we got the right wheels if python_version == '2.7': expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') if '-cp27' in w or '-pp27' in w] else: expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') if '-cp27' not in w and '-pp27' not in w] assert set(actual_wheels) == set(expected_wheels)