Merge remote-tracking branch 'origin/master' into deterministic-builds

This commit is contained in:
Joe Rickerby
2020-02-15 11:45:54 +00:00
46 changed files with 314 additions and 184 deletions
+22 -25
View File
@@ -1,11 +1,24 @@
version: 2
jobs:
osx-python2:
flake8:
docker:
- image: circleci/python:3.6
steps:
- checkout
- run:
name: Install flake8
command: sudo python -m pip install flake8
- run:
name: Test.
command: flake8 --exclude=.git,.venv,site .
osx-python3.6:
macos:
xcode: "10.0.0"
xcode: "9.4.1"
environment:
PYTHON: python2
PYTHON: python3
steps:
- checkout
@@ -16,7 +29,7 @@ jobs:
name: Test.
command: venv/bin/python ./bin/run_tests.py
osx-python3:
osx-python3.7:
macos:
xcode: "10.0.0"
environment:
@@ -31,23 +44,7 @@ jobs:
name: Test.
command: venv/bin/python ./bin/run_tests.py
linux-python2:
docker:
- image: circleci/python:2.7
environment:
PYTHON: python2
steps:
- checkout
- setup_remote_docker
- run:
name: Prepare the environment.
command: bash .circleci/prepare.sh
- run:
name: Test.
command: venv/bin/python ./bin/run_tests.py
linux-python3:
linux-python3.6:
docker:
- image: circleci/python:3.6
environment:
@@ -67,7 +64,7 @@ workflows:
version: 2
all-tests:
jobs:
- osx-python2
- osx-python3
- linux-python2
- linux-python3
- flake8
- osx-python3.6
- osx-python3.7
- linux-python3.6
+1 -1
View File
@@ -1,6 +1,6 @@
$PYTHON --version
$PYTHON -m pip --version
$PYTHON -m pip install -q --user --ignore-installed --upgrade virtualenv
$PYTHON -m pip install -q --user --ignore-installed --upgrade "virtualenv<20"
$PYTHON -m virtualenv -p $PYTHON venv
venv/bin/python -m pip install -r requirements-dev.txt
venv/bin/python -m pip freeze
-7
View File
@@ -2,13 +2,6 @@ language: generic
matrix:
include:
# Linux Python 2
- sudo: required
language: python
python: 2.7
services: docker
env: PYTHON=python
# Linux Python 3
- sudo: required
language: python
+9
View File
@@ -0,0 +1,9 @@
This is a summary of the Python versions and platforms covered by the different CI platforms:
| | 3.5 | 3.6 | 3.7 | 3.8 |
|----------|------------------|------------------|-----------------------|------------------|
| Linux | Travis CI | CircleCI | AppVeyor | Azure Pipelines |
| macOS | Azure Pipelines | CircleCI | Travis CI¹ / CircleCI | Azure Pipelines |
| Windows | TravisCI | Azure Pipelines | AppVeyor | Azure Pipelines |
> ¹ Python version not really pinned, but dependent on the (default) version of image used.
+2 -2
View File
@@ -3,9 +3,9 @@ image:
- Visual Studio 2015
build_script:
- cmd: "C:\\Python27\\python.exe -m pip install -r requirements-dev.txt"
- cmd: "C:\\Python37\\python.exe -m pip install -r requirements-dev.txt"
- sh: "${HOME}/.localpython3.7.4/bin/python3 -m pip install -r requirements-dev.txt"
# the '-u' flag is required so the output is in the correct order.
# See https://github.com/joerick/cibuildwheel/pull/24 for more info.
- cmd: "C:\\Python27\\python.exe -u ./bin/run_tests.py"
- cmd: "C:\\Python37\\python.exe -u ./bin/run_tests.py"
- sh: "${HOME}/.localpython3.7.4/bin/python3 ./bin/run_tests.py"
+25 -3
View File
@@ -1,5 +1,5 @@
jobs:
- job: linux
- job: linux_38
pool: {vmImage: 'Ubuntu-18.04'}
steps:
- task: UsePythonVersion@0
@@ -9,7 +9,17 @@ jobs:
python -m pip install -r requirements-dev.txt
python ./bin/run_tests.py
- job: macos
- job: macos_35
pool: {vmImage: 'macOS-10.13'}
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.5'
- bash: |
python -m pip install -r requirements-dev.txt
python ./bin/run_tests.py
- job: macos_38
pool: {vmImage: 'macOS-10.13'}
steps:
- task: UsePythonVersion@0
@@ -19,7 +29,19 @@ jobs:
python -m pip install -r requirements-dev.txt
python ./bin/run_tests.py
- job: windows
- job: windows_36
pool: {vmImage: 'vs2017-win2016'}
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.6'
- script: choco install vcpython27 -f -y
displayName: Install Visual C++ for Python 2.7
- bash: |
python -m pip install -r requirements-dev.txt
python ./bin/run_tests.py
- job: windows_38
pool: {vmImage: 'vs2017-win2016'}
steps:
- task: UsePythonVersion@0
+5 -5
View File
@@ -1,7 +1,9 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os, sys, subprocess, shutil
import argparse
import os
import subprocess
import sys
def single_run(test_project):
@@ -12,8 +14,6 @@ def single_run(test_project):
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("test_project_dir")
args = parser.parse_args()
+6 -5
View File
@@ -1,18 +1,19 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os, sys, subprocess, shutil, json
import os
import subprocess
import sys
from glob import glob
if __name__ == '__main__':
# move cwd to the project root
os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
### run the unit tests
# run the unit tests
subprocess.check_call([sys.executable, '-m', 'pytest', 'unit_test'])
### run the integration tests
# run the integration tests
test_projects = sorted(glob('test/??_*'))
+21 -13
View File
@@ -1,14 +1,24 @@
from __future__ import print_function
import argparse, os, subprocess, sys, textwrap
try:
from configparser import ConfigParser
except ImportError:
from ConfigParser import ConfigParser
import argparse
import os
import sys
import textwrap
import traceback
from configparser import ConfigParser
import cibuildwheel
import cibuildwheel.linux, cibuildwheel.windows, cibuildwheel.macos
from cibuildwheel.environment import parse_environment, EnvironmentParseError
from cibuildwheel.util import BuildSelector, DependencyConstraints, Unbuffered
import cibuildwheel.linux
import cibuildwheel.macos
import cibuildwheel.windows
from cibuildwheel.environment import (
EnvironmentParseError,
parse_environment,
)
from cibuildwheel.util import (
BuildSelector,
DependencyConstraints,
Unbuffered
)
def get_option_from_environment(option_name, platform=None, default=None):
'''
@@ -89,7 +99,6 @@ def main():
file=sys.stderr)
exit(2)
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()
@@ -125,9 +134,8 @@ def main():
try:
environment = parse_environment(environment_config)
except (EnvironmentParseError, ValueError) as e:
except (EnvironmentParseError, ValueError):
print('cibuildwheel: Malformed environment option "%s"' % environment_config, file=sys.stderr)
import traceback
traceback.print_exc(None, sys.stderr)
exit(2)
@@ -239,6 +247,7 @@ def detect_obsolete_options():
))
os.environ[option] = os.environ[option].replace(deprecated, alternative)
def print_preamble(platform, build_options):
print(textwrap.dedent('''
_ _ _ _ _ _ _
@@ -249,7 +258,6 @@ def print_preamble(platform, build_options):
print('cibuildwheel version %s\n' % cibuildwheel.__version__)
print('Build options:')
print(' platform: %r' % platform)
for option, value in sorted(build_options.items()):
+7 -8
View File
@@ -1,9 +1,12 @@
import subprocess, shlex, sys
import shlex
import subprocess
from collections import namedtuple
import bashlex
NodeExecutionContext = namedtuple('NodeExecutionContext', ['environment', 'input'])
def evaluate(value, environment):
if not value:
# empty string evaluates to empty string
@@ -16,9 +19,9 @@ def evaluate(value, environment):
raise ValueError('"%s" has too many parts' % value)
value_word_node = command_node.parts[0]
return evaluate_node(
value_word_node,
value_word_node,
context=NodeExecutionContext(environment=environment, input=value)
)
@@ -60,12 +63,8 @@ def evaluate_word_node(node, context):
def evaluate_command_node(node, context):
words = [evaluate_node(part, context=context) for part in node.parts]
command = ' '.join(words)
output = subprocess.check_output(shlex.split(command), env=context.environment)
return subprocess.check_output(shlex.split(command), env=context.environment, universal_newlines=True)
if sys.version_info[0] >= 3:
return output.decode('utf8', 'replace')
else:
return output
def evaluate_parameter_node(node, context):
return context.environment.get(node.value, '')
+3 -2
View File
@@ -1,4 +1,5 @@
import bashlex
from . import bashlex_eval
@@ -41,7 +42,7 @@ def split_env_items(env_string):
return result
class EnvironmentAssignment(object):
class EnvironmentAssignment:
def __init__(self, assignment):
name, equals, value = assignment.partition('=')
if not equals:
@@ -60,7 +61,7 @@ class EnvironmentAssignment(object):
return '%s=%s' % (self.name, self.value)
class ParsedEnvironment(object):
class ParsedEnvironment:
def __init__(self, assignments):
self.assignments = assignments
+46 -18
View File
@@ -1,12 +1,15 @@
from __future__ import print_function
import os, subprocess, sys, uuid
import os
import shlex
import subprocess
import sys
import textwrap
import uuid
from collections import namedtuple
from .util import prepare_command, get_build_verbosity_extra_flags
try:
from shlex import quote as shlex_quote
except ImportError:
from pipes import quote as shlex_quote
from .util import (
get_build_verbosity_extra_flags,
prepare_command,
)
def get_python_configurations(build_selector):
@@ -49,7 +52,7 @@ def run_docker(command, stdin_str=None):
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images, dependency_constraints):
try:
subprocess.check_call(['docker', '--version'])
except:
except Exception:
print('cibuildwheel: Docker not found. Docker is required to run Linux builds. '
'If you\'re building on Travis CI, add `services: [docker]` to your .travis.yml.'
'If you\'re building on Circle CI in Linux, add a `setup_remote_docker` step to your .circleci/config.yml',
@@ -69,20 +72,20 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
container_name = 'cibuildwheel-{}'.format(uuid.uuid4())
try:
run_docker(['create',
'--env', 'CIBUILDWHEEL',
'--name', container_name,
'-i',
'-v', '/:/host', # ignored on CircleCI
docker_image, '/bin/bash'])
run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project'])
subprocess.run(['docker', 'create',
'--env', 'CIBUILDWHEEL',
'--name', container_name,
'-i',
'-v', '/:/host', # ignored on CircleCI
docker_image, '/bin/bash'])
subprocess.run(['docker', 'cp', os.path.abspath(project_dir) + '/.', container_name + ':/project'])
for config in platform_configs:
if dependency_constraints:
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='''
subprocess.run(['docker', 'start', '-i', '-a', container_name], stdin_str='''
set -o errexit
set -o xtrace
mkdir -p /output
@@ -188,11 +191,36 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
))
# copy the output back into the host
run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)])
subprocess.run(['docker', 'cp', container_name + ':/output/.', os.path.abspath(output_dir)])
except subprocess.CalledProcessError:
exit(1)
finally:
# Still gets executed, even when 'exit(1)' gets called
run_docker(['rm', '--force', '-v', container_name])
subprocess.run(['docker', 'rm', '--force', '-v', container_name], check=True)
def troubleshoot(project_dir, error):
if (isinstance(error, subprocess.CalledProcessError) and 'start' in error.cmd):
# the bash script failed
print('Checking for common errors...')
so_files = []
for root, dirs, files in os.walk(project_dir):
for name in files:
_, ext = os.path.splitext(name)
if ext == '.so':
so_files.append(os.path.join(root, name))
if so_files:
print(textwrap.dedent('''
NOTE: Shared object (.so) files found in this project.
These files might be built against the wrong OS, causing problems with
auditwheel.
If you're using Cython and have previously done an in-place build,
remove those build files (*.so and *.c) before starting cibuildwheel.
'''))
print(' Files detected:')
print('\n'.join([' ' + f for f in so_files]))
print('')
+12 -11
View File
@@ -1,14 +1,17 @@
from __future__ import print_function
import os
import shlex
import shutil
import subprocess
import tempfile
import os, subprocess, shlex, sys, shutil
from collections import namedtuple
from glob import glob
try:
from shlex import quote as shlex_quote
except ImportError:
from pipes import quote as shlex_quote
from .util import prepare_command, get_build_verbosity_extra_flags, download, get_pip_script
from .util import (
download,
get_build_verbosity_extra_flags,
prepare_command,
get_pip_script
)
def get_python_configurations(build_selector):
@@ -33,9 +36,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
python_configurations = get_python_configurations(build_selector)
pkgs_output = subprocess.check_output(['pkgutil', '--pkgs'])
if sys.version_info[0] >= 3:
pkgs_output = pkgs_output.decode('utf8')
pkgs_output = subprocess.check_output(['pkgutil', '--pkgs'], universal_newlines=True)
installed_system_packages = pkgs_output.splitlines()
def call(args, env=None, cwd=None, shell=False):
@@ -43,7 +44,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
if shell:
print('+ %s' % args)
else:
print('+ ' + ' '.join(shlex_quote(a) for a in args))
print('+ ' + ' '.join(shlex.quote(a) for a in args))
return subprocess.check_call(args, env=env, cwd=cwd, shell=shell)
+6 -11
View File
@@ -1,13 +1,8 @@
from fnmatch import fnmatch
import warnings
import os
import urllib.request
from fnmatch import fnmatch
from time import sleep
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
def prepare_command(command, **kwargs):
'''
@@ -28,7 +23,7 @@ def get_build_verbosity_extra_flags(level):
return []
class BuildSelector(object):
class BuildSelector:
def __init__(self, build_config, skip_config):
self.build_patterns = build_config.split()
self.skip_patterns = skip_config.split()
@@ -43,7 +38,7 @@ class BuildSelector(object):
# Taken from https://stackoverflow.com/a/107717
class Unbuffered(object):
class Unbuffered:
def __init__(self, stream):
self.stream = stream
@@ -68,8 +63,8 @@ def download(url, dest):
repeat_num = 3
for i in range(repeat_num):
try:
response = urlopen(url)
except:
response = urllib.request.urlopen(url)
except Exception:
if i == repeat_num - 1:
raise
sleep(3)
+12 -9
View File
@@ -1,14 +1,16 @@
from __future__ import print_function
import os, tempfile, subprocess, shutil, sys
import os
import shutil
import subprocess
import tempfile
from collections import namedtuple
from glob import glob
try:
from shlex import quote as shlex_quote
except ImportError:
from pipes import quote as shlex_quote
from .util import prepare_command, get_build_verbosity_extra_flags, download, get_pip_script
from .util import (
download,
get_build_verbosity_extra_flags,
prepare_command,
get_pip_script,
)
IS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache')
@@ -26,6 +28,7 @@ def get_nuget_args(configuration):
python_name = python_name + "x86"
return [python_name, "-Version", configuration.version, "-OutputDirectory", "C:/cibw/python"]
def get_python_configurations(build_selector):
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier'])
python_configurations = [
@@ -46,7 +49,7 @@ def get_python_configurations(build_selector):
# try with (and similar): msiexec /i VCForPython27.msi ALLUSERS=1 ACCEPT=YES /passive
python_configurations = [c for c in python_configurations if not c.version.startswith('2.7.')]
# skip builds as required
# skip builds as required
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
return python_configurations
+1 -1
View File
@@ -20,7 +20,7 @@ OS X/macOS allows you to specify a so-called "deployment target" version that wi
However, to enable modern C++ standards, the deploment target needs to be set high enough (since older OS X/macOS versions did not have the necessary modern C++ standard library).
To get C++11 and C++14 support, set `MACOSX_DEPLOYMENT_TARGET` to (at least) `"10.9"`.
To get C++11 and C++14 support, `MACOSX_DEPLOYMENT_TARGET` needs to be set to (at least) `"10.9"`. By default, `cibuildwheel` already does this, building 64-bit-only wheels for macOS 10.9 and later.
To get C++17 support, set `MACOSX_DEPLOYMENT_TARGET` to (at least) `"10.13"` or `"10.14"` (macOS 10.13 offers partial C++17 support; e.g., the filesystem header is in experimental, offering `#include <experimental/filesystem>` instead of `#include <filesystem>`; macOS 10.14 has full C++17 support).
@@ -1,4 +1,9 @@
import mkdocs, re, os, io, cgi
import cgi
import io
import os
import re
import mkdocs
INCLUDE_TAG_REGEX = re.compile(
r'''
@@ -28,6 +33,7 @@ INCLUDEMARKDOWN_TAG_REGEX = re.compile(
flags=re.VERBOSE,
)
class ImportMarkdownPlugin(mkdocs.plugins.BasePlugin):
def on_page_markdown(self, markdown, page, **kwargs):
page_src_path = page.file.abs_src_path
@@ -49,7 +55,6 @@ class ImportMarkdownPlugin(mkdocs.plugins.BasePlugin):
return text_to_include
def found_includemarkdown_tag(match):
filename = match.group('filename')
start = match.group('start')
@@ -62,13 +67,13 @@ class ImportMarkdownPlugin(mkdocs.plugins.BasePlugin):
with io.open(file_path_abs, encoding='utf8') as f:
text_to_include = f.read()
if start:
_, _, text_to_include = text_to_include.partition(start)
if end:
text_to_include, _, _ = text_to_include.partition(end)
return (
'<!-- BEGIN INCLUDE %s %s %s -->\n' % (
filename, cgi.escape(start or ''), cgi.escape(end or '')
@@ -80,4 +85,3 @@ class ImportMarkdownPlugin(mkdocs.plugins.BasePlugin):
markdown = re.sub(INCLUDE_TAG_REGEX, found_include_tag, markdown)
markdown = re.sub(INCLUDEMARKDOWN_TAG_REGEX, found_includemarkdown_tag, markdown)
return markdown
+3
View File
@@ -19,3 +19,6 @@ replace = cibuildwheel=={new_version}
[bdist_wheel]
universal = 1
[flake8]
ignore = E501,W503
application-import-names = cibuildwheel
+4 -5
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, io
import io
import os
try:
from setuptools import setup
@@ -21,19 +21,18 @@ setup(
author="Joe Rickerby",
author_email='joerick@mac.com',
url='https://github.com/joerick/cibuildwheel',
packages=['cibuildwheel',],
packages=['cibuildwheel', ],
license="BSD",
zip_safe=False,
package_data={
'cibuildwheel': ['resources/*'],
},
# Supported python versions
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
python_requires='>=3.5',
keywords='ci wheel packaging pypi travis appveyor macos linux windows',
classifiers=[
'Intended Audience :: Developers',
'Natural Language :: English',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: BSD License',
+3 -2
View File
@@ -1,9 +1,10 @@
import os
import utils
project_dir = os.path.dirname(__file__)
def test():
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir)
@@ -20,6 +21,6 @@ def test_build_identifiers():
# can be multiple wheels for each wheel, though, so we need to limit
# the expected wheels
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
if not '-manylinux' in w or '-manylinux1' in w]
if '-manylinux' not in w or '-manylinux1' in w]
build_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir)
assert len(expected_wheels) == len(build_identifiers)
+4 -1
View File
@@ -1,6 +1,9 @@
import os
from setuptools import setup, Extension
from setuptools import (
Extension,
setup,
)
if os.environ.get('CIBUILDWHEEL', '0') != '1':
raise Exception('CIBUILDWHEEL environment variable is not set to 1')
+5 -1
View File
@@ -1,7 +1,11 @@
import os, subprocess
import os
import subprocess
import pytest
import utils
def test():
project_dir = os.path.dirname(__file__)
+4 -1
View File
@@ -1,4 +1,7 @@
from setuptools import setup, Extension
from setuptools import (
Extension,
setup,
)
setup(
name="spam",
+1
View File
@@ -1,4 +1,5 @@
from unittest import TestCase
import spam
@@ -1,6 +1,8 @@
import os
import utils
def test():
project_dir = os.path.dirname(__file__)
+7 -2
View File
@@ -1,5 +1,10 @@
from setuptools import setup, Extension
import sys, os
import os
import sys
from setuptools import (
Extension,
setup,
)
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step
# is the same one as is currently running.
+2
View File
@@ -1,6 +1,8 @@
import os
import utils
def test():
project_dir = os.path.dirname(__file__)
+5 -1
View File
@@ -1,6 +1,10 @@
from setuptools import setup, Extension
import sys
from setuptools import (
Extension,
setup,
)
# explode if run on Python 2.7 or Python 3.4 (these should be skipped)
if sys.version_info[0:2] == (2, 7):
raise Exception('Python 2.7 should not be built')
+2
View File
@@ -1,6 +1,8 @@
import os
import utils
def test():
project_dir = os.path.dirname(__file__)
+6 -3
View File
@@ -1,5 +1,9 @@
from setuptools import setup, Extension
import sys, os
import os
from setuptools import (
Extension,
setup,
)
# explode if environment isn't correct, as set in CIBW_ENVIRONMENT
CIBW_TEST_VAR = os.environ.get('CIBW_TEST_VAR')
@@ -15,7 +19,6 @@ if '/opt/cibw_test_path' not in PATH:
if '$PATH' in PATH:
raise Exception('$PATH should be expanded in PATH. It was "%s"' % PATH)
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
+5 -1
View File
@@ -1,6 +1,10 @@
import os, pytest
import os
import pytest
import utils
def test():
project_dir = os.path.dirname(__file__)
+6 -2
View File
@@ -1,6 +1,10 @@
import os, sys
import os
import sys
from setuptools import setup, Extension
from setuptools import (
Extension,
setup,
)
# check that we're running in the correct docker image as specified in the
# environment options CIBW_MANYLINUX1_*_IMAGE
+2
View File
@@ -1,6 +1,8 @@
import os
import utils
def test():
project_dir = os.path.dirname(__file__)
# this test checks that SSL is working in the build environment using
+5 -1
View File
@@ -1,6 +1,10 @@
import ssl
import sys
from setuptools import setup, Extension
from setuptools import (
Extension,
setup,
)
if sys.version_info[0] == 2:
from urllib2 import urlopen
@@ -1,4 +1,7 @@
import os, pytest
import os
import pytest
import utils
+4 -1
View File
@@ -1,4 +1,7 @@
from setuptools import setup, Extension
from setuptools import (
Extension,
setup,
)
setup(
name="spam",
+2 -1
View File
@@ -1,9 +1,10 @@
import os
import utils
project_dir = os.path.dirname(__file__)
def test():
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir)
+4 -4
View File
@@ -1,7 +1,7 @@
import os
from setuptools import setup, Extension
from setuptools import (
Extension,
setup,
)
setup(
ext_modules=[Extension('spam.spam', sources=['spam/spam.c'])],
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.1.0"
__version__ = "0.1.0"
+8 -9
View File
@@ -1,13 +1,12 @@
import os
import sys
import pytest
import utils
project_dir = os.path.dirname(__file__)
def test_cpp11(tmp_path):
# This test checks that the C++11 standard is supported
@@ -18,8 +17,8 @@ def test_cpp11(tmp_path):
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [x for x in utils.expected_wheels(
'spam', '0.1.0', macosx_deployment_target='10.9')
if 'cp27-cp27m-win' not in x]
'spam', '0.1.0', macosx_deployment_target='10.9')
if 'cp27-cp27m-win' not in x]
assert set(actual_wheels) == set(expected_wheels)
@@ -35,15 +34,15 @@ def test_cpp14():
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [x for x in utils.expected_wheels(
'spam', '0.1.0', macosx_deployment_target='10.9')
if 'cp27-cp27m-win' not in x and 'cp35-cp35m-win' not in x]
'spam', '0.1.0', macosx_deployment_target='10.9')
if 'cp27-cp27m-win' not in x and 'cp35-cp35m-win' not in x]
assert set(actual_wheels) == set(expected_wheels)
def test_cpp17():
# This test checks that the C++17 standard is supported
# Python 2.7 uses the `register` keyword which is forbidden in the C++17 standard
# Python 2.7 uses the `register` keyword which is forbidden in the C++17 standard
# The manylinux1 docker image does not have a compiler which supports C++11
# Python 3.4 and 3.5 are compiled with MSVC 10, which does not support C++17
if os.environ.get('APPVEYOR_BUILD_WORKER_IMAGE', '') == 'Visual Studio 2015':
@@ -55,6 +54,6 @@ def test_cpp17():
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [x for x in utils.expected_wheels(
'spam', '0.1.0', macosx_deployment_target='10.13')
if 'cp27-cp27m-win' not in x and 'cp35-cp35m-win' not in x]
'spam', '0.1.0', macosx_deployment_target='10.13')
if 'cp27-cp27m-win' not in x and 'cp35-cp35m-win' not in x]
assert set(actual_wheels) == set(expected_wheels)
+6 -2
View File
@@ -1,7 +1,11 @@
import os, sys
from setuptools import setup, Extension
import os
import platform
from setuptools import (
Extension,
setup,
)
standard = os.environ["STANDARD"]
language_standard = "/std:c++" + standard if platform.system() == "Windows" else "-std=c++" + standard
+5 -3
View File
@@ -4,10 +4,12 @@ Utility functions used by the cibuildwheel tests.
This file is added to the PYTHONPATH in the test runner at bin/run_test.py.
'''
import subprocess, sys, os, shutil
from tempfile import mkdtemp
import os
import shutil
import subprocess
import sys
from contextlib import contextmanager
from tempfile import mkdtemp
IS_WINDOWS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache')
IS_WINDOWS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows'
+8
View File
@@ -1,4 +1,5 @@
import os
from cibuildwheel.environment import parse_environment
@@ -13,6 +14,7 @@ def test_basic_parsing():
assert environment_dict == {'VAR': '1', 'VBR': '2'}
assert environment_cmds == ['export VAR=1', 'export VBR=2']
def test_quotes():
environment_recipe = parse_environment('A=1 VAR="1 NOT_A_VAR=2" VBR=\'vbr\'')
@@ -24,6 +26,7 @@ def test_quotes():
assert environment_dict == {'A': '1', 'VAR': '1 NOT_A_VAR=2', 'VBR': 'vbr'}
assert environment_cmds == ['export A=1', 'export VAR="1 NOT_A_VAR=2"', 'export VBR=\'vbr\'']
def test_inheritance():
environment_recipe = parse_environment('PATH=$PATH:/usr/local/bin')
@@ -35,6 +38,7 @@ def test_inheritance():
assert environment_dict == {'PATH': '/usr/bin:/usr/local/bin'}
assert environment_cmds == ['export PATH=$PATH:/usr/local/bin']
def test_shell_eval():
environment_recipe = parse_environment('VAR="$(echo "a test" string)"')
@@ -49,6 +53,7 @@ def test_shell_eval():
assert environment_dict['VAR'] == 'a test string'
assert environment_cmds == ['export VAR="$(echo "a test" string)"']
def test_shell_eval_and_env():
environment_recipe = parse_environment('VAR="$(echo "$PREV_VAR" string)"')
@@ -60,6 +65,7 @@ def test_shell_eval_and_env():
assert environment_dict == {'PREV_VAR': '1 2 3', 'VAR': '1 2 3 string'}
assert environment_cmds == ['export VAR="$(echo "$PREV_VAR" string)"']
def test_empty_var():
environment_recipe = parse_environment('CFLAGS=')
@@ -71,6 +77,7 @@ def test_empty_var():
assert environment_dict == {'CFLAGS': ''}
assert environment_cmds == ['export CFLAGS=']
def test_no_vars():
environment_recipe = parse_environment('')
@@ -80,6 +87,7 @@ def test_no_vars():
assert environment_dict == {}
assert environment_cmds == []
def test_no_vars_pass_through():
environment_recipe = parse_environment('')
@@ -1,13 +1,18 @@
import pytest
import sys
import os
import subprocess
import sys
from cibuildwheel import linux, macos, windows, util
import pytest
from cibuildwheel import (
linux,
macos,
util,
windows,
)
class ArgsInterceptor(object):
class ArgsInterceptor:
def __call__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
@@ -15,6 +20,7 @@ class ArgsInterceptor(object):
MOCK_PROJECT_DIR = 'some_project_dir'
@pytest.fixture(autouse=True)
def mock_protection(monkeypatch):
'''
@@ -31,13 +37,14 @@ def mock_protection(monkeypatch):
monkeypatch.setattr(linux, 'build', fail_on_call)
monkeypatch.setattr(macos, 'build', fail_on_call)
@pytest.fixture(autouse=True)
def fake_project_dir(monkeypatch):
'''
Monkey-patch enough for the main() function to run
'''
real_os_path_exists = os.path.exists
def mock_os_path_exists(path):
if path == os.path.join(MOCK_PROJECT_DIR, 'setup.py'):
return True
@@ -1,15 +1,12 @@
import pytest
import sys
from fnmatch import fnmatch
import pytest
from cibuildwheel.__main__ import main
from cibuildwheel.environment import ParsedEnvironment
from cibuildwheel.util import BuildSelector
from main_util_fixtures import mock_protection, fake_project_dir, platform, intercepted_build_args
# CIBW_PLATFORM is tested in main_platform_test.py
@@ -97,6 +94,7 @@ def get_default_repair_command(platform):
else:
raise ValueError('Unknown platform', platform)
@pytest.mark.parametrize('repair_command', [None, 'repair', 'repair -w {dest_dir} {wheel}'])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_repair_command(repair_command, platform_specific, platform, intercepted_build_args, monkeypatch):
@@ -229,5 +227,3 @@ def test_build_selector_migrations(intercepted_build_args, monkeypatch, option_n
assert intercepted_build_selector.build_patterns == build_selector_patterns
else:
assert intercepted_build_selector.skip_patterns == build_selector_patterns
@@ -1,10 +1,10 @@
import pytest
import sys
import pytest
from cibuildwheel.__main__ import main
from main_util_fixtures import MOCK_PROJECT_DIR, mock_protection, fake_project_dir, platform, intercepted_build_args
from conftest import MOCK_PROJECT_DIR # noqa: I100
def test_unknown_platform_non_ci(monkeypatch, capsys):