diff --git a/.gitignore b/.gitignore index 5721e556..e78281bc 100644 --- a/.gitignore +++ b/.gitignore @@ -85,7 +85,10 @@ celerybeat-schedule # virtualenv .venv venv/ +venv3/ ENV/ +env/ +env3/ # Spyder project settings .spyderproject diff --git a/.travis.yml b/.travis.yml index effe4142..5d1465fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,46 @@ +language: generic + matrix: include: + # Linux Python 2 - sudo: required + language: python services: - docker + env: + - "PYTHON=python2" + + # Linux Python 3 + - sudo: required + language: python + services: + - docker + env: + - "PYTHON=python3" + before_install: + - sudo apt-get -qq update + - sudo apt-get install -y python3-pip + + # macOS Python 2 - os: osx + env: + - "PYTHON=python2" + + # macOS Python 3 + - os: osx + env: + - "PYTHON=python3" + before_install: + - brew update + - brew install python3 script: - | if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - pip install -r requirements-dev.txt - python ./bin/run_tests.py + $PYTHON -m pip install -r requirements-dev.txt + $PYTHON ./bin/run_tests.py else # linux test requires root to clean up the wheelhouse (docker runs as root) - sudo pip install -r requirements-dev.txt - sudo python ./bin/run_tests.py + sudo $PYTHON -m pip install -r requirements-dev.txt + sudo $PYTHON ./bin/run_tests.py fi diff --git a/appveyor.yml b/appveyor.yml index c96d6e2e..a8463c2f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,10 @@ +environment: + matrix: + - PYTHON: "C:\\Python27\\python.exe" + - PYTHON: "C:\\Python35\\python.exe" + build_script: - - pip install -r requirements-dev.txt + - "%PYTHON% -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. - - python -u ./bin/run_tests.py + - "%PYTHON% -u ./bin/run_tests.py" diff --git a/bin/run_test.py b/bin/run_test.py index 90f0e35b..efcf3de5 100755 --- a/bin/run_test.py +++ b/bin/run_test.py @@ -17,7 +17,7 @@ def single_run(test_project): project_env = {str(k): str(v) for k, v in project_env.items()} # unicode not allowed in env env.update(project_env) print('Building %s with environment %s' % (test_project, project_env)) - subprocess.check_call(['cibuildwheel', test_project], env=env) + subprocess.check_call([sys.executable, '-m', 'cibuildwheel', test_project], env=env) wheels = glob('wheelhouse/*.whl') print('%s built successfully. %i wheels built.' % (test_project, len(wheels))) diff --git a/bin/run_tests.py b/bin/run_tests.py index 9264e2be..bcae61c5 100755 --- a/bin/run_tests.py +++ b/bin/run_tests.py @@ -10,7 +10,7 @@ if __name__ == '__main__': ### run the unit tests - subprocess.check_call(['python', '-m', 'pytest', 'unit_test']) + subprocess.check_call([sys.executable, '-m', 'pytest', 'unit_test']) ### run the integration tests diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 46b87cf8..1a157495 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -59,6 +59,8 @@ def main(): platform = 'macos' elif 'APPVEYOR' in os.environ: platform = 'windows' + elif 'BITRISE_BUILD_NUMBER' in os.environ: + platform = 'macos' else: print('cibuildwheel: Unable to detect platform. cibuildwheel should run on your CI server, ' 'Travis CI and Appveyor are supported. You can run on your development ' diff --git a/cibuildwheel/bashlex_eval.py b/cibuildwheel/bashlex_eval.py index 90a399fe..af1ef5ba 100644 --- a/cibuildwheel/bashlex_eval.py +++ b/cibuildwheel/bashlex_eval.py @@ -1,4 +1,4 @@ -import subprocess, shlex +import subprocess, shlex, sys from collections import namedtuple import bashlex @@ -60,8 +60,12 @@ 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) - return subprocess.check_output(shlex.split(command), env=context.environment) + output = subprocess.check_output(shlex.split(command), env=context.environment) + 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, '') diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index d20f986a..d860beeb 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -22,3 +22,20 @@ class BuildSkipper(object): def __repr__(self): return 'BuildSkipper(%r)' % ' '.join(self.patterns) + + +# Taken from https://stackoverflow.com/a/107717 +class Unbuffered(object): + def __init__(self, stream): + self.stream = stream + + def write(self, data): + self.stream.write(data) + self.stream.flush() + + def writelines(self, datas): + self.stream.writelines(datas) + self.stream.flush() + + def __getattr__(self, attr): + return getattr(self.stream, attr) diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index d44125f1..b431c4f5 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -7,13 +7,13 @@ except ImportError: from collections import namedtuple from glob import glob -from .util import prepare_command +from .util import prepare_command, Unbuffered def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, skip, environment): # Python under AppVeyor/Windows seems to be buffering by default, giving problems interleaving subprocess call output with unflushed calls to 'print' sys.stdout.flush() - sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) + sys.stdout = Unbuffered(sys.stdout) # run_with_env is a cmd file that sets the right environment variables to run_with_env = os.path.join(tempfile.gettempdir(), 'appveyor_run_with_env.cmd')