Compare commits

...
904 Commits
Author SHA1 Message Date
Joe Rickerby c884530a1d Bump version: v1.5.3 2020-07-19 11:59:56 +01:00
Joe Rickerby acf0320f68 Merge pull request #405 from mayeut/update-cp38
Update CPython 3.8 from 3.8.3 to 3.8.4
2020-07-18 11:52:57 +01:00
mayeut 5368b3bc64 Update CPython 3.8 from 3.8.3 to 3.8.4
Changelog: https://docs.python.org/release/3.8.4/whatsnew/changelog.html#changelog
2020-07-18 11:05:23 +02:00
Joe Rickerby acf60364c0 Merge pull request #403 from joerick/appveyor-debug-env
Debug Appveyor errors
2020-07-17 15:00:04 +01:00
Joe Rickerby 7d983cdf8c Reenable all tests 2020-07-17 09:39:22 +01:00
Joe Rickerby 6847454850 Remove debug code 2020-07-17 09:31:53 +01:00
Joe Rickerby af2a171994 Fix quotes 2020-07-17 09:09:02 +01:00
Joe Rickerby b90c4035b3 Update test_environment.py 2020-07-16 07:56:15 +01:00
Joe Rickerby 56cd6c965d Avoid backslash-in-env-var entirely 2020-07-15 22:02:20 +01:00
Joe Rickerby 5df97a4121 Correct quoting of semicolon 2020-07-15 21:34:30 +01:00
Joe Rickerby 69fe085ba3 more back-slash hilarity 2020-07-15 21:25:29 +01:00
Joe Rickerby 08eddeff8b Fix test and add another more awkward example 2020-07-15 21:07:33 +01:00
Joe Rickerby 9fb748bfb0 Add unit test for this failure mode 2020-07-12 21:45:46 +01:00
Joe Rickerby dc446d3cac moar debug 2020-07-12 12:45:59 +01:00
Joe Rickerby 9f71900637 add debugging code 2020-07-12 12:39:33 +01:00
Joe Rickerby e098e1450d Fix test project generation script 2020-07-12 12:35:30 +01:00
Joe Rickerby ed0077a995 Merge pull request #386 from joerick/docker-exec
From Linux bash script to Python control flow
2020-07-11 19:28:40 +01:00
Joe Rickerby 5842a75927 Flake8 fixes 2020-07-10 13:04:50 +01:00
Joe Rickerby 44e3198880 Convert glob to take a Path and a str pattern 2020-07-10 12:57:05 +01:00
Joe Rickerby 4c0af9f152 Finish file/dir tests 2020-07-10 12:46:32 +01:00
Joe Rickerby 8ddc6d57a2 Bump version: v1.5.2 2020-07-08 22:59:40 +01:00
Joe Rickerby 9e35d65de4 Add file-based unit tests 2020-07-08 22:56:33 +01:00
Joe Rickerby 58fa77b73b Merge pull request #401 from joerick/windows_call
Windows - distinguishing between call and shell for better arg quoting
2020-07-08 22:01:57 +01:00
Joe RickerbyandHenry Schreiner 048ddc4af3 Update test/test_pep518.py
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2020-07-08 20:12:50 +01:00
Joe Rickerby c521dca40b My own unique attempt on the shell/call debacle 2020-07-08 18:17:55 +01:00
Henry Schreiner ac2b391790 Typo 2020-07-07 23:33:03 -04:00
Henry Schreiner 47fe71efb4 Try just converting to list 2020-07-07 23:09:40 -04:00
Henry Schreiner 53ba9bd0d0 Try adding PATH to env 2020-07-06 18:11:29 -04:00
Henry Schreiner 317397b39a fix: Try resolving 2020-07-06 14:25:02 -04:00
Henry Schreiner 8466194576 fix: Try removing shell 2020-07-06 10:49:24 -04:00
Henry Schreiner c68be58e78 fix: Try simple quoting 2020-07-06 08:55:36 -04:00
Henry Schreiner fc24230cb4 Try original 2020-07-06 01:31:47 -04:00
Henry Schreiner c36be04ee8 fix: Use repr 2020-07-05 23:51:28 -04:00
Henry Schreiner 7a27ae941c fix: Support environment markers in PEP 518 workaround 2020-07-05 23:16:00 -04:00
Joe Rickerby 833a069207 Pass PATH during command substitution test 2020-07-05 17:39:40 +01:00
Joe Rickerby cc913ee7cf Use a different method for the Windows test 2020-07-05 17:27:29 +01:00
Joe Rickerby d0b6401129 Merge pull request #394 from mayeut/update-cpython-3.7
Update CPython 3.7 from 3.7.7 to 3.7.8
2020-07-05 14:50:00 +01:00
mayeut 141b3e031e Update CPython 3.7 from 3.7.7 to 3.7.8
Changelog: https://docs.python.org/release/3.7.8/whatsnew/changelog.html#changelog
2020-07-04 18:11:06 +02:00
Yannick Jadoul 0beb9518c9 Merge pull request #393 from Czaki/fix-doc1
Update links in documentation
2020-07-04 16:37:53 +02:00
Grzegorz Bokota ad51e796c0 Update links in documentation
fix #391
2020-07-04 12:02:16 +02:00
Joe Rickerby b12a560e87 Add docker test images for other architectures 2020-07-01 13:22:24 +01:00
Joe Rickerby e31c24d3bb Fix overridden PATH test, by ensuring bash command substitution rules 2020-06-28 21:51:06 +01:00
Joe Rickerby 27d97daf13 Don't use redirection syntax in Windows environment. Fix absolute path use for Mac 2020-06-28 11:33:22 +01:00
Joe Rickerby faf6a76375 Change 'slow' tests to 'docker' tests, only run them on Linux 2020-06-28 10:53:03 +01:00
Joe Rickerby 91c3e90017 Fix Python 3.6 compatibility 2020-06-26 21:47:42 +01:00
Joe Rickerby ad871f886a Fix style 2020-06-26 21:41:00 +01:00
Joe Rickerby c956f118f6 Add unit tests for DockerContainer 2020-06-26 21:37:02 +01:00
Joe Rickerby 762dc807cd Convert DockerContainer to use binary PIPEs, to handle arbitrary data 2020-06-26 21:36:52 +01:00
Joe Rickerby 2edb33662b Import organisation 2020-06-26 20:22:49 +01:00
Joe Rickerby df69dda44a Fix broken PATH test - it was erroring for a different reason 2020-06-26 12:59:26 +01:00
Joe Rickerby 1d9333689f Explicit buffer size isn't necessary 2020-06-26 12:55:38 +01:00
Joe Rickerby 68d8f89fb3 Style tweaks 2020-06-26 11:02:23 +01:00
Joe Rickerby db9d658b51 Merge pull request #387 from joerick/call-types
Remove str() calls in call/shell functions using destructuring syntax
2020-06-26 00:20:22 +01:00
Joe Rickerby 1d88c27530 Neaten function call whitespace 2020-06-25 12:41:21 +01:00
Joe Rickerby fefe128a15 Fix issues with spaces in environment variables 2020-06-25 11:21:10 +01:00
Joe Rickerby a92959f191 Update README.md 2020-06-25 10:57:58 +01:00
Joe Rickerby 321335e756 Bump version: v1.5.1 2020-06-25 10:53:30 +01:00
Joe Rickerby c88a73b40b Merge pull request #389 from Czaki/fix_shutil
Switch back to shutil.move from Path.rename
2020-06-25 10:44:53 +01:00
Joe Rickerby dd4fc69e7c Revert "Remove hard-coded shell info to use the docker ENTRYPOINT instead"
This reverts commit a052c71aec.
2020-06-25 10:39:26 +01:00
Grzegorz Bokota 4dd5c0e11c use only dir name as target of shutil.move 2020-06-24 23:04:15 +00:00
Grzegorz Bokota a2f4d2aa47 Switch back to shutil.move from Path.rename 2020-06-24 22:36:18 +00:00
Joe Rickerby 850d109582 Don't use docker exec -w because CircleCI doesn't support it 2020-06-24 17:12:06 +01:00
Joe Rickerby a052c71aec Remove hard-coded shell info to use the docker ENTRYPOINT instead
This lets us use the 'linux32 bash' that's specified by the i686 docker
images, without specifying it explicitly.
2020-06-24 16:50:08 +01:00
Joe Rickerby 31339ba30e Extract DockerContainer into its own file 2020-06-24 16:43:33 +01:00
Joe Rickerby 53c00a0af6 Use a long-running remote bash shell, rather than docker exec 2020-06-24 16:39:20 +01:00
Joe Rickerby 41891277d3 Bump version: v1.5.0 2020-06-24 09:54:55 +01:00
Joe Rickerby 78ac83ff7e Merge pull request #358 from henryiii/henryiii/pep517
Adding PEP 518 test, fix 3.5 Python on Windows
2020-06-24 09:34:25 +01:00
Joe Rickerby 50a263df21 Remove str() calls in call/shell functions using destructuring syntax 2020-06-23 20:28:54 +01:00
Joe Rickerby e417791ae4 Remove the linux bash script, replaced with a docker exec approach 2020-06-23 19:46:23 +01:00
Joe Rickerby 3ff84c52f9 Merge branch 'master' into henryiii/pep517 2020-06-23 19:39:59 +01:00
probot-auto-merge[bot] e72e4683db Merge pull request #383 from joerick/circleci-debug
Debug CircleCI failures
2020-06-23 11:26:55 +00:00
Joe Rickerby dfd8f4809a Merge remote-tracking branch 'origin/master' into circleci-debug 2020-06-23 11:17:36 +01:00
Joe Rickerby 666699a51e Configure probot-auto-merge 2020-06-23 11:16:23 +01:00
Joe Rickerby 947059bbf4 Don't try to install virtualenv 2020-06-23 10:27:23 +01:00
Joe Rickerby 4302090f08 Uninstall poetry 2020-06-23 10:25:35 +01:00
Joe Rickerby c68d50a073 Lock virtualenv version 2020-06-23 10:19:09 +01:00
Joe Rickerby a03a26c90e Update README options table 2020-06-23 09:59:22 +01:00
Joe Rickerby e3b272201e Merge pull request #342 from Czaki/setup_data
Add BEFORE_ALL options
2020-06-23 09:51:35 +01:00
Grzegorz Bokota 43fcb31231 fix tests 2020-06-22 13:55:04 +02:00
Grzegorz Bokota b4b46a1f06 fix mypy 2020-06-22 13:55:04 +02:00
Joe Rickerby 2057bba07f Update docs to reflect linux available python change 2020-06-22 13:55:04 +02:00
Joe Rickerby 46352c8e30 Add a modern python to linux build before_all environment 2020-06-22 13:55:04 +02:00
Grzegorz Bokota 2e15fdddfd change to new test engine 2020-06-22 13:55:04 +02:00
Grzegorz Bokota fc52c5e7b6 add unit_test 2020-06-22 13:55:04 +02:00
Grzegorz Bokota 7b7e24d36d add missed quote of before_all command 2020-06-22 13:55:04 +02:00
Grzegorz Bokota 9f6c91404d fix flake8 2020-06-22 13:55:04 +02:00
Grzegorz BokotaandJoe Rickerby 219a65d5e3 Apply suggestions from code review
Co-authored-by: Joe Rickerby <joerick@mac.com>
2020-06-22 13:55:04 +02:00
Grzegorz Bokota 36b8f7fff2 changes in code from code review 2020-06-22 13:55:04 +02:00
Grzegorz Bokota 4d5cf4629e fix mypy type warning 2020-06-22 13:55:04 +02:00
Grzegorz Bokota c1f155c0f2 add environment evaluation 2020-06-22 13:55:04 +02:00
Grzegorz Bokota 3fe560cf14 fix mypy 2020-06-22 13:55:04 +02:00
Grzegorz Bokota 75a0384d02 fix flake8 errors 2020-06-22 13:55:04 +02:00
Grzegorz Bokota 6501470357 Add BEFORE_ALL options 2020-06-22 13:55:04 +02:00
Joe Rickerby 8bfc313d02 Merge pull request #347 from Czaki/pre_commit
Pre commit
2020-06-22 12:19:11 +01:00
Joe Rickerby e6ac527416 Convert the workaround to use Path objects 2020-06-22 12:08:40 +01:00
Joe Rickerby c27c5feadb Merge branch 'master' into henryiii/pep517 2020-06-22 12:06:32 +01:00
Joe Rickerby 2b22ffda9b Add python3.9 note to version matrix 2020-06-22 11:42:41 +01:00
Yannick Jadoul 9a1f8a99e0 Merge pull request #376 from YannickJadoul/pathlib
Use pathlib.Path
2020-06-22 12:27:20 +02:00
Yannick Jadoul d552d29eae Revert use of Path.joinpath instead of Path.__div__ 2020-06-21 13:14:53 +02:00
Grzegorz Bokota aa99405a9c unpin flake, exclude pinned_docker_images.cfg 2020-06-19 21:15:33 +02:00
Grzegorz Bokota 39101ae8ea update mypy config 2020-06-19 21:12:12 +02:00
Grzegorz Bokota 1a83967261 remove json check 2020-06-19 21:12:12 +02:00
Grzegorz Bokota d43817b49a fixed files 2020-06-19 21:12:12 +02:00
Grzegorz Bokota 3b1f0dd453 add pre-commit configuration 2020-06-19 21:12:12 +02:00
Joe Rickerby a1db0f7ebb Merge pull request #378 from YannickJadoul/ignore-TestProject
Suppress warnings about pytest trying to collect TestProject
2020-06-19 11:02:52 +01:00
Yannick Jadoul acf5c24881 Use patlib.Path in tests and tools 2020-06-18 15:29:48 +02:00
Yannick Jadoul f012fa1af0 Mock Path.mkdir calls in unit tests 2020-06-18 00:23:25 +02:00
Yannick Jadoul b62b17a223 Replace shutil.move with Path.rename or Path.replace 2020-06-18 00:23:25 +02:00
Yannick Jadoul 265708854a Attend to review remarks 2020-06-18 00:23:25 +02:00
Yannick Jadoul e58aed1731 Fix overlooked os.path.abspath 2020-06-18 00:23:25 +02:00
Yannick Jadoul b3ffb04a2c Fix order of pathlib.Path.symlink_to arguments in windows.py 2020-06-18 00:23:25 +02:00
Yannick Jadoul c53e7824a7 Remove unused imports 2020-06-18 00:23:25 +02:00
Yannick Jadoul 46a39b06cb Fix paths in unit tests 2020-06-18 00:23:25 +02:00
Yannick Jadoul a7f73f1593 Use pathlib.Path in main cibuildwheel files 2020-06-18 00:23:25 +02:00
Yannick Jadoul 47323761dd Suppress warnings about pytest trying to collect TestProject 2020-06-18 00:23:09 +02:00
Yannick Jadoul 43fbcfe008 Merge pull request #379 from YannickJadoul/fix-travis-ci-windows-root-ca
Fix SSL error on Windows on Travis CI
2020-06-18 00:21:33 +02:00
Yannick Jadoul 5c19ff3f95 Fix 'ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)' error on Windows on Travis CI 2020-06-17 23:26:39 +02:00
Joe Rickerby 02e9ee3e96 Merge pull request #369 from Czaki/ensure_dir_name
Ensure dir name
2020-06-16 15:07:58 +01:00
Joe Rickerby df07aafae1 Merge pull request #374 from YannickJadoul/detect-virtualenv-real_prefix
Simplify virtualenv test in test_testing
2020-06-16 15:06:00 +01:00
Joe Rickerby 78edb0a06a Merge pull request #375 from joerick/appveyor-macos-allow-failures
Allow failures on Appveyor macos
2020-06-16 15:03:14 +01:00
Henry Schreiner 901ac79dbc review: Address review suggestion 2020-06-14 11:25:14 -04:00
Henry Schreiner 0597088f64 Adding PEP 518 test 2020-06-14 09:57:58 -04:00
Joe Rickerby f1c4ebbed0 Allow failures on Appveyor macos
Temporarily allow this build to fail to get the tests green again
2020-06-14 11:03:38 +01:00
Joe Rickerby fd9e3202a0 Merge pull request #348 from YannickJadoul/before-test-docs-order
Making order of options more consistent in docs and BuildOptions fields
2020-06-14 10:55:11 +01:00
Joe Rickerby 7afdd40714 Merge pull request #354 from henryiii/patch-2
Better help for GitHub Actions + Py27 workaround
2020-06-14 09:56:22 +01:00
Yannick Jadoul ed491d0e22 Simplify virtualenv test in test_testing 2020-06-14 00:37:34 +02:00
Joe Rickerby e12ca14006 Merge pull request #362 from breznak/gh-action-pypi-publish
example: for GH Actions use action to publish
2020-06-10 13:20:16 +01:00
Joe Rickerby 58fc418563 Update to add clarity to on: section 2020-06-10 13:18:22 +01:00
Yannick Jadoul 57e6f0f56d Replace "startsWith(matrix.os, 'windows')" by "runner.os == 'Windows'" in GitHub Actions configurations 2020-06-10 01:53:41 +02:00
Yannick Jadoul cc8dbbe8b3 Make deploy on published GitHub release optional in examples/github-deploy.yml 2020-06-08 15:50:38 +02:00
Yannick Jadoul bb5aac3d69 Move if-clause of PyPI upload to job level rather than action level, and specify to use only published releases 2020-06-08 13:23:28 +02:00
Grzegorz Bokota 374e88382b move abspath to system specific files 2020-06-08 10:19:02 +02:00
Grzegorz Bokota c74acd6363 change to abspath 2020-06-08 08:05:25 +02:00
Grzegorz Bokota 90023a3a70 fix logic for test 2020-06-06 20:26:50 +02:00
Grzegorz Bokota 0b82ab6674 ensure that package_dir is provided as package 2020-06-06 20:05:09 +02:00
Henry Schreiner fb0e192681 Add example snippit 2020-06-05 16:58:57 -04:00
Yannick Jadoul eedc5c6b79 Remove twine check from examples/github-deploy.yml as it's now integrated into the pypa/gh-action-pypi-publish action 2020-06-03 19:01:01 +02:00
Joe Rickerby 31c9247921 Merge pull request #360 from heitorlessa/improv/support-pyproject-poetry
Support projects without setup.py (pyproject.toml and setup.cfg are also valid)
2020-06-02 21:30:48 +01:00
Yannick JadoulandJoe Rickerby 4c3cbf702c Update examples/github-deploy.yml to upload on tags, as alternative to GitHub releases
Co-authored-by: Joe Rickerby <joerick@mac.com>
2020-06-02 22:09:33 +02:00
Yannick Jadoul a06998e2f6 Merge pull request #366 from YannickJadoul/ignore-docker-rm
Ignore errors when cleaning up docker container in linux.py
2020-06-02 21:45:50 +02:00
Joe Rickerby 4e15e202c8 style- inline function 2020-06-02 20:03:04 +01:00
Joe Rickerby 35ea7b6307 Remove debugging flags 2020-06-02 20:02:54 +01:00
Yannick Jadoul 46688ae3f9 Revert previous solution and just don't try removing the container if 'docker create' errors 2020-06-02 17:15:27 +02:00
Yannick Jadoul 9c3f44d086 Rename examples/*-deploy-only.yml to examples/*-deploy.yml, and keep sdist in dist/ in examples/github-deploy.yml 2020-06-02 17:07:18 +02:00
Yannick Jadoul 896337cbb1 Updating all GitHub actions version to actions/checkout@v2, actions/setup-python@v2, and actions/upload-artifact@v2 2020-06-02 15:23:15 +02:00
Yannick Jadoul a0dab888a7 Ignore errors when cleaning up docker container in linux.py 2020-06-02 15:09:41 +02:00
Yannick Jadoul d7cffde00f Add 'release' to 'on' section in examples/github-deploy-only.yml 2020-06-02 15:07:06 +02:00
Yannick Jadoul 562d81c6ea Add links to the PyPI deployment examples to the docs 2020-06-02 12:03:06 +02:00
Yannick Jadoul 66b392f4ee Implement @henriii's suggestion, adding a separate job on Linux to upload all artifacts at once 2020-06-02 11:48:15 +02:00
Marek Otahal dd3c87ece2 example: small doc 2020-06-01 16:04:44 +02:00
Marek Otahal 63f7a2ddc4 examples: revert to minima GH example, add deploymet
example showing pypi and GH release
2020-06-01 16:01:29 +02:00
Marek Otahal ca49d86ed8 example: publish to PyPI only on release tag 2020-06-01 15:32:51 +02:00
heitorlessa d9a317c370 fix: address Yannick's PR feedback 2020-06-01 14:30:14 +01:00
Marek Otahal add792de30 example: for GH Actions use action to publish
to PyPI, instead of calling twine directly.
2020-06-01 15:02:26 +02:00
heitorlessa 004fc03899 fix: remove integ test 2020-06-01 13:21:52 +01:00
heitorlessa 15f1678439 fix: install poetry before build for windows
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-06-01 10:44:58 +01:00
heitorlessa 3de38fc679 fix: assert single wheel workaround
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-06-01 10:03:53 +01:00
heitorlessa 63eda18cf9 chore: increase test verbosity to capture errors
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-06-01 09:31:54 +01:00
heitorlessa a15a5f1c0f fix: exclude pypy build that's failing
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-06-01 08:58:24 +01:00
heitorlessa d41cf65173 improv: address Henrii's feedback
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-06-01 08:37:08 +01:00
Yannick Jadoul e97b103148 Group environment variables querying in __main__.py 2020-06-01 00:04:32 +02:00
heitorlessa 4e6246d2a7 chore: flake8
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-05-31 22:43:30 +01:00
heitorlessa ab4f5209b5 improv: document test given when then
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-05-31 22:39:19 +01:00
heitorlessa 8a25718c71 fix: ignores images with outdated pip version
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-05-31 22:37:52 +01:00
heitorlessa a8bdac07e6 fix: python version requirement range
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-05-31 22:02:27 +01:00
Yannick Jadoul 2790fd1dd7 Put CIBW_TEST_COMMAND as first test option everywhere 2020-05-31 21:42:21 +02:00
heitorlessa f9401d94c2 fix: support py2.7 to accommodate current setup
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-05-31 20:14:24 +01:00
heitorlessa 4fb7874ca3 chore: address PR feedback
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-05-31 20:13:52 +01:00
heitorlessa bb1b050ab5 improv: add integ test dummy poetry package 2020-05-31 19:55:27 +01:00
heitorlessa e8d857db21 chore: flake8 mypy linting
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-05-31 17:56:43 +01:00
heitorlessa f3a136be78 improv: support pyproject.toml existence
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
2020-05-31 17:36:30 +01:00
Henry Schreiner 2c564dfb9c Mention action, drop example code. 2020-05-27 19:45:34 -04:00
Henry Schreiner 901f708d4c Better help for GitHub Actions + Py27 workaround 2020-05-27 15:56:12 -04:00
Joe Rickerby ecbdc2e3d3 Bump version: v1.4.2 2020-05-25 16:16:13 +01:00
Joe Rickerby 60a3d51a50 Merge pull request #352 from mayeut/isolation-test
Add test case for proper build isolation
2020-05-25 16:07:26 +01:00
mayeut bdc86ba539 Update dependencies 2020-05-25 15:20:56 +02:00
mayeut 04c1a2aee5 Add test case for proper build isolation
If there's not a proper build isolation then,
the wheel for `cp27mu` will pick up the `spam.so` built
for `cp27m` resulting in an import error.
2020-05-25 14:57:58 +02:00
Joe Rickerby e76ebbcdec Merge pull request #334 from joerick/template-tests
Refactor tests to generate projects from template
2020-05-18 09:06:39 +01:00
Yannick Jadoul edd461ad42 Making order of options more consistent in docs and BuildOptions fields 2020-05-17 22:30:18 +02:00
Joe Rickerby 0c323cfb5b Add non-strict typechecking to test module
'strict' is a global flag, so I've had to break out the type-
checking options to be more specific
2020-05-17 20:17:34 +01:00
Joe Rickerby 2e41a4f94a Merge commit 'cf60df549183e88cf84bca9d45550caf62c8be9e' into template-tests 2020-05-17 16:59:06 +01:00
Joe Rickerby 81f960b17e Rename TemplateProject -> TestProject & tidy some comments 2020-05-17 16:57:11 +01:00
Joe Rickerby cf60df5491 Merge pull request #346 from mayeut/update-constraints
Update the versions of our dependencies.
2020-05-17 15:04:52 +01:00
mayeut fd8507212c Update the versions of our dependencies. 2020-05-16 11:19:09 +02:00
Joe Rickerby 420995f567 check_call does require paths as strings on CPython 3.6 Windows 2020-05-15 15:18:17 +01:00
Joe Rickerby 29084bd5bf Merge pull request #345 from mayeut/update-python
Update CPython 3.8 from 3.8.2 to 3.8.3
2020-05-15 15:09:22 +01:00
Joe Rickerby 13907188a1 Fix flake8 errors 2020-05-15 12:35:14 +01:00
mayeut d606aaa85e Update CPython 3.8 from 3.8.2 to 3.8.3
Changelog:
https://github.com/python/cpython/blob/v3.8.3/Misc/NEWS.d/3.8.3.rst
2020-05-15 13:35:05 +02:00
Joe Rickerby 2e8fe841ec Remove TemplateProject subclassing 2020-05-15 12:28:34 +01:00
Joe Rickerby 0411fcc2ae As discussed in code review 2020-05-15 12:19:38 +01:00
Joe Rickerby 6a9ab683a6 Merge pull request #344 from jbarlow83/patch-2
README: add pikepdf
2020-05-15 10:31:57 +01:00
jbarlow83 e9592b2d53 README: add pikepdf 2020-05-14 02:18:42 -07:00
Joe Rickerby db6b1f3541 Merge pull request #341 from mayeut/f-strings
Use f-strings
2020-05-10 08:31:40 +01:00
mayeut 5e767fcc9a Use f-strings
Now that minimum python supported is 3.6, we can use f-strings !
2020-05-09 11:53:20 +02:00
Yannick Jadoul ac0012e3da Merge pull request #315 from YannickJadoul/type-annotations
Add type annotations and drop Python 3.5 host support
2020-05-09 02:37:58 +02:00
Joe Rickerby 71150a1cb5 Remove pypy from the c++17 test 2020-05-08 13:36:53 +01:00
Yannick Jadoul 0368d58065 Run mypy in CircleCI job 2020-05-07 00:41:16 +02:00
Yannick Jadoul 9daad5c60c Ignore .mypy_cache and add mypy configuration to setup.cfg 2020-05-07 00:28:57 +02:00
Yannick Jadoul 4683ac3d6c Remove macOS Python 3.7 job on CircleCI 2020-05-07 00:28:53 +02:00
Yannick Jadoul 7cc85c2e4f Replace Callable[[str], bool] by BuildSelector 2020-05-07 00:07:14 +02:00
Yannick Jadoul 891e2dd6aa Fixing some review remarks 2020-05-06 23:57:33 +02:00
Yannick Jadoul 575e229514 Drop 3.5 host support and adapt CI configurations 2020-05-06 23:57:00 +02:00
Yannick Jadoul 1a765ac431 Use variable annotations instead of workarounds 2020-05-06 23:55:54 +02:00
Yannick Jadoul 5bdb21b705 More type annotations after rebasing 2020-05-06 23:55:54 +02:00
Yannick Jadoul 40967a6572 collections.namedtuple to typing.NameTuple and flake8 fixes 2020-05-06 23:55:54 +02:00
Yannick Jadoul c128018590 Clean up bashlex_eval.py's types 2020-05-06 23:55:54 +02:00
Yannick Jadoul 618f1cefae Added majority of type annotations (to a by now outdated version) 2020-05-06 23:55:54 +02:00
Joe Rickerby a679a09212 Add missing 3.6 pin test 2020-05-06 20:24:13 +01:00
Joe Rickerby cc1ae4a963 Add utility function to checkout a generated project 2020-05-06 20:14:03 +01:00
Joe Rickerby dbd7006704 Remove dead code from merge 2020-05-06 19:51:58 +01:00
Joe Rickerby da4bc0225c Fix new cpp17 test 2020-05-05 21:56:34 +01:00
Joe Rickerby f145c7c148 Merge commit '79278364898eccc08d6bbe6e956b6774bb332c24' into template-tests
# Conflicts:
#	CI.md
#	test/02_test/test/spam_test.py
#	test/10_cpp_standards/cibuildwheel_test.py
2020-05-05 21:52:37 +01:00
Joe Rickerby 73425d4bb8 Fix indent 2020-05-05 21:32:57 +01:00
Joe Rickerby 7927836489 Merge pull request #339 from jlaine/mention-projects
Add PyAV, aiortc and aioquic to example projects
2020-05-04 22:54:29 +01:00
Yannick Jadoul 185a1c09ad Update docs on workaround for modern MSVC/C++ in Python 2.7 2020-05-04 23:39:59 +02:00
Yannick Jadoul 3d4a6b0765 Only build Python 2.7 wheel in test_cpp17_py27_modern_msvc_workaround 2020-05-04 23:39:59 +02:00
Yannick Jadoul 7eb82bf90c Add note in CI.md about reduced tests on AppVeyor 2020-05-04 23:39:59 +02:00
Yannick Jadoul 5986c91937 Also try to build C++14/C++17 wheels for PyPy 3.6 with default MSVC 2020-05-04 23:39:59 +02:00
Yannick Jadoul 63421d40f0 Testing if cp35 works for modern C++ 2020-05-04 23:39:59 +02:00
Yannick Jadoul e11c0c2dd1 Simplify and clarify test_cpp17_modern_msvc_workaround 2020-05-04 23:39:59 +02:00
Yannick Jadoul 362b4314cb Make distinction between 32- and 64-bit Python wheels 2020-05-04 23:39:59 +02:00
Yannick Jadoul ba60f1865f Use setuptools backported versions of distutils._msvccompiler in setuptools.msvc to get environment variables from vcvarsall 2020-05-04 23:39:59 +02:00
Yannick Jadoul f0e65d9f5a Correct VC++ version in test_cpp17_modern_msvc_workaround 2020-05-04 23:39:59 +02:00
Yannick Jadoul e1881976e8 Add test to build wheels on Windows for C++17, setting DISTUTILS_USE_SDK and MSSdk to not use vcpython27 or MSVC 10 2020-05-04 23:39:59 +02:00
Jeremy Lainé 953839be59 Add PyAV, aiortc and aioquic to example projects 2020-05-04 20:20:50 +02:00
Joe Rickerby aaf1bba1cf Merge pull request #337 from Czaki/remove_pypy_patch
clean after bump to pypy 7.3.1
2020-05-04 18:43:30 +01:00
Joe Rickerby 9ea7fa7628 Bump version: v1.4.1 2020-05-04 17:11:32 +01:00
Grzegorz BokotaandJoe Rickerby 3f3effe25d add linux32 to i686 builds (#338)
* add linux32 to i686 builds

* Add test. Fix bug with space.

* Apply suggestions from code review

apply suggestions

Co-authored-by: Joe Rickerby <joerick@mac.com>

* change uname to platform.machine

Co-authored-by: Joe Rickerby <joerick@mac.com>
2020-05-04 17:06:47 +01:00
Grzegorz Bokota 196a0323a4 clean after bump to pypy 7.3.1 2020-05-04 10:52:41 +02:00
Yannick Jadoul 328a6714e9 Enable pymdownx.magiclink to get automatic links for URLs in the Markdown docs 2020-05-04 00:32:18 +02:00
Joe Rickerby 729bab42c8 Pytest config header 2020-05-03 17:03:35 +01:00
Joe Rickerby a9c475a910 Fix pathlib error on Windows 2020-05-03 16:53:15 +01:00
Joe Rickerby 566a880099 Fix warning 2020-05-03 16:52:35 +01:00
Joe Rickerby bf882b065d Output test timings 2020-05-03 14:18:57 +01:00
Joe Rickerby 1b38974c60 Fix subdir test 2020-05-03 14:09:47 +01:00
Joe Rickerby c568f7ba89 Add pytest-azurepipelines plugin 2020-05-03 14:09:35 +01:00
Joe Rickerby e9803e8fb3 Fix missing dir 2020-05-03 14:09:10 +01:00
Joe Rickerby dafe5cd1f7 Refactor to use tmp_path and pathlib paths 2020-05-03 14:08:57 +01:00
Joe Rickerby 33f210b85c Remove 'setuptools' template project 2020-05-03 10:37:41 +01:00
Yannick Jadoul e2cafa487b Cherry pick: Drop 3.5 host support and adapt CI configurations 2020-05-03 10:37:09 +01:00
Joe Rickerby ffd5d44cdc Fix C++ tests 2020-05-03 10:30:44 +01:00
Joe Rickerby 5d665aac39 Fix up test runner scripts 2020-05-02 22:57:03 +01:00
Joe Rickerby 662612685c Rename tests to remove the number, but keep 'basic' as the first 2020-05-02 22:53:58 +01:00
Joe Rickerby a204df819b Add .mypy_cache to gitignore 2020-05-02 22:51:40 +01:00
Joe Rickerby 9bb075aa0b Fix flake8 errors 2020-05-02 22:50:52 +01:00
Joe Rickerby 007be7aea7 Ensure tests are up-to-date with master 2020-05-02 22:42:35 +01:00
Joe Rickerby 3b35882f87 Complete migration to new style. remove old reference tests 2020-05-02 21:00:58 +01:00
Joe Rickerby 783dedad22 Bump version: v1.4.0 2020-05-02 17:55:50 +01:00
Joe Rickerby dd3bec5ba9 Fix #323 2020-05-02 16:57:28 +01:00
Joe Rickerby 616e9dd6eb Converting tests to the new-style 2020-05-02 16:54:19 +01:00
Joe Rickerby c9c1ea6fec Update dependencies (#332) 2020-05-02 16:37:38 +01:00
Joe Rickerby c38bc9064a Reintroduce jinja2 2020-05-02 09:59:55 +01:00
Yannick Jadoul 2e4a29bf1f Updating the description of C++17 support on macOS (#330)
* Updating the description of C++17 support on macOS, adding nuances about runtime library support vs. C++17 compiler/STL features

* Improve phrasing of macOS C++17 docs with suggested edits
2020-05-02 09:58:48 +01:00
Yannick JadoulandJoe Rickerby dadf6a7ac9 PyPy 7.3.1 (#304)
* Testing PyPy 7.3.1rc1/7.3.1rc2

* Try PyPy's fix for macOS

* 7.3.1rc3

* Update PyPy to 7.3.1

* Using latest pypywheels/manylinux2010-pypy_x86_64:2020-04-15-4ce2a6f with PyPy 7.3.1

* Rehost pypy-7.3.1 on Github to guard against bitbucket links going away

The pypy team plan to have a CDN in front of their buildbot downloads
page, but the timeline is unknown. In the meantime, this should be more
reliable than the bitbucket links!

* Updating macOS and Windows download links for PyPy to https://downloads.python.org/pypy/

Co-authored-by: Joe Rickerby <joerick@mac.com>
2020-04-28 19:05:28 +01:00
Joe Rickerby 4f75eaabcd Inprogress refactor trying f-strings as template language 2020-04-25 16:09:11 +01:00
Matthieu Darbois 9880c4fbb7 Update openssl patch from 1.0.2t to 1.0.2u on macOS (#328) 2020-04-25 16:14:31 +02:00
Matthieu Darbois 2970faf732 Update CPython 3.7 from 3.7.6 to 3.7.7 (#327)
https://docs.python.org/3.7/whatsnew/changelog.html#python-3-7-7-final
2020-04-25 13:07:57 +02:00
Matthieu Darbois a57ef07f72 Update CPython 2.7 from 2.7.17 to 2.7.18 (#326)
change log: https://github.com/python/cpython/blob/v2.7.18/Misc/NEWS.d/2.7.18rc1.rst
2020-04-25 11:16:36 +02:00
Joe Rickerby 0224d72931 Merge pull request #322 from ax3l/doc-fixTravisArm64
Travis-CI Example: Fix aarch64
2020-04-16 07:41:28 +01:00
Axel Huebl 98c4a395e9 Travis-CI Example: Fix aarch64
The `arch:` `aarch64` is called `arm64` on Travis-CI.
https://docs.travis-ci.com/user/multi-cpu-architectures/

Otherwise this falls back to a generic Linux amd64 host.
2020-04-15 18:15:31 -07:00
Joe Rickerby 95678f3d5d Merge pull request #319 from joerick/support-subdirectory-joerick
Provide `package_dir` for setting subdirectory of project [alternative]
2020-04-14 19:12:50 +01:00
Joe Rickerby f7cda33d96 Merge pull request #321 from MaxHalford/master
Update README.md
2020-04-14 19:00:59 +01:00
Joe Rickerby 603f77a0c1 Assert the files were run using capfd 2020-04-12 23:15:49 +01:00
Max Halford a290e00282 Update README.md
Add creme to working examples
2020-04-12 13:13:02 +02:00
Joe Rickerby 7ebe8fef55 Fix tests on windows - shebang don't work so great there! 2020-04-11 09:39:25 +01:00
Joe Rickerby 21e6b99884 Style fixes 2020-04-10 17:44:18 +01:00
Joe Rickerby f4e911028c Add test for building a package at a subpath within a project 2020-04-10 17:42:39 +01:00
Joe Rickerby 3e335044c6 Merge pull request #318 from joerick/appveyor-pty-fix
Try Appveyor config workaround
2020-04-10 17:23:42 +01:00
Joe Rickerby 407a1c0a6e Merge pull request #320 from joerick/reenable-linux-troubleshoot
Add back missing 'troubleshoot' function call
2020-04-10 17:23:21 +01:00
Joe Rickerby fa605d080b Add back missing 'troubleshoot' function call 2020-04-10 14:18:09 +01:00
Joe Rickerby 7b3bcfae34 Remove allow_failures block and add comment 2020-04-10 14:13:42 +01:00
Joe Rickerby 4b5c743a64 And again..? 2020-04-10 13:00:09 +01:00
Joe Rickerby 83b39bcda2 Update docs on the package/project split 2020-04-10 12:59:22 +01:00
Joe Rickerby a1983b94d8 Merge commit '882ea3426a837acfe205cc5de98793c98b6a1bf7' into support-subdirectory-joerick 2020-04-10 12:33:05 +01:00
Joe Rickerby 397393ba91 Use cwd to run test projects, not package_dir 2020-04-10 12:28:05 +01:00
Joe Rickerby e07d8038c6 Remove lingering project_dir references 2020-04-10 12:27:26 +01:00
Joe Rickerby f84388fe26 Changes that let me run the entire the entire linux test suite locally 2020-04-10 12:18:21 +01:00
Joe Rickerby 7e59d8c61c Change how paths are handled, using 'project is working dir' mentality 2020-04-09 16:19:36 +01:00
Joe Rickerby 95bef46832 Update docs for package_dir 2020-04-09 15:51:00 +01:00
Yannick Jadoul 882ea3426a Merge remote-tracking branch 'upstream/master' 2020-04-09 15:20:05 +02:00
Joe Rickerby a0cc4f6347 Fix comma/dot typo 2020-04-09 14:15:56 +01:00
Joe Rickerby d5010b8242 Merge remote-tracking branch 'origin/master' into support-subdirectory 2020-04-09 14:05:09 +01:00
Yannick Jadoul 25f2e8cb46 Fix flake8 2020-04-09 14:37:12 +02:00
Joe Rickerby 7eb0de0dd2 Try another one 2020-04-09 11:39:46 +01:00
Joe Rickerby eff997d12e Merge pull request #311 from Czaki/pack_arguments
Pack build arguments
2020-04-09 10:46:42 +01:00
Joe Rickerby b5175e6159 Try Appveyor config workaround
APPVEYOR_CONSOLE_DISABLE_PTY, as suggested in https://github.com/appveyor/ci/issues/3376#issuecomment-611314299
2020-04-09 10:43:21 +01:00
Yannick Jadoul b8dbedcdbe Remove explicit object base class of DependencyConstraints 2020-04-08 16:43:01 +02:00
Yannick Jadoul 8be6d47eec Merge pull request #313 from YannickJadoul/less-appveyor
Only run unit tests and 01_basic on AppVeyor
2020-04-08 16:24:44 +02:00
Yannick Jadoul b0d99df007 Allow failure for macOS job on AppVeyor 2020-04-08 15:10:48 +02:00
Yannick Jadoul f38eb2644f Run all tests on AppVeyor on master and appveyor-* branches 2020-04-08 13:18:27 +02:00
Grzegorz BokotaandJoe Rickerby ef935187d0 Update BuildOptions description
Co-Authored-By: Joe Rickerby <joerick@mac.com>
2020-04-08 12:54:58 +02:00
Grzegorz Bokota 6113136a1d fix types annotation with optional 2020-04-08 12:54:58 +02:00
Grzegorz Bokota 13a8c549bf rename opt to options 2020-04-08 12:54:58 +02:00
Grzegorz Bokota 8d7d41cd83 python 3.5 fix 2020-04-08 12:54:58 +02:00
Grzegorz Bokota 6554c3cf86 pack build argument in named tuple, introduce typing arguments 2020-04-08 12:54:58 +02:00
Joe Rickerby 3836bb2919 Merge pull request #306 from joerick/min-macosx-deployment-target
Set MACOSX_DEPLOYMENT_TARGET to 10.9, if not set by the user
2020-04-08 11:53:29 +01:00
Joe Rickerby 2345cf20da Merge pull request #314 from joerick/conserve-ci-on-origin-branches
Build PR branches only once (for origin branches) and skip docs changes
2020-04-08 11:40:57 +01:00
Yannick Jadoul 3a3d1a4d2b Only run unit tests and 01_basic on AppVeyor 2020-04-08 10:45:12 +02:00
Yannick Jadoul 49bbbec7f0 Fix flake8 whitespace warnings 2020-04-08 10:24:16 +02:00
Joe Rickerby 2b4bd815ed Fix some whitespace problems with the merge 2020-04-07 18:52:49 +01:00
Joe Rickerby e90e94a18e Merge branch 'master' of github.com:joerick/cibuildwheel into min-macosx-deployment-target 2020-04-07 18:47:22 +01:00
Joe Rickerby bff3e8e37a Merge pull request #307 from Czaki/setup_python_separate
Setup python extracted from build function
2020-04-07 18:24:55 +01:00
Joe Rickerby 1701bc6bde Limit the master-only rule to joerick/cibuildwheel 2020-04-07 18:11:12 +01:00
Joe Rickerby a2eff759e8 Fix github config 2020-04-07 11:54:37 +01:00
Joe Rickerby 1c88697e7c Merge pull request #312 from joerick/refactor-expected-wheels
Refactor expected_wheels test function
2020-04-07 11:50:30 +01:00
Joe Rickerby 97628673d2 Build PR branches only once (for origin branches) and skip docs changes 2020-04-07 11:49:10 +01:00
Grzegorz Bokota 3aa97f09e2 appveyor retries 2020-04-07 12:30:53 +02:00
Joe Rickerby 5a7dc042b6 Add Windows x86 machine values 2020-04-07 10:01:05 +01:00
Grzegorz Bokota a4602c32dd move calculate constraints outside python setup 2020-04-07 00:56:00 +02:00
Joe Rickerby 3018e7a1f8 Refactor expected_wheels function 2020-04-06 23:10:19 +01:00
Joe Rickerby ea6ada0728 Fix update deps script bugs 2020-04-06 14:30:43 +01:00
Joe Rickerby 90634ed872 Fix flake8 exclude list 2020-04-06 11:50:30 +01:00
Joe Rickerby e78a731e2d Fix bug in Docker pin script causing the latest tag to be pinned 2020-04-06 11:47:23 +01:00
Joe Rickerby 8986b2d468 Add dependency update script 2020-04-06 11:45:18 +01:00
Joe Rickerby 626a045770 Merge origin/master into min-macosx-deployment-target 2020-04-05 17:13:53 +01:00
Grzegorz Bokota 8b465bc94a move python setup to separated function 2020-04-05 16:03:35 +02:00
Joe Rickerby 317c0f4baf Merge pull request #256 from joerick/deterministic-builds
Deterministic builds
2020-04-05 12:58:36 +01:00
Joe Rickerby b52edf89ef Tidy up cpp_standards tests, removing 10.9 references as this is default 2020-04-05 12:40:35 +01:00
Joe Rickerby 27b79f8616 Fix tests to always default to 10.9 2020-04-05 12:34:52 +01:00
Joe Rickerby 93df99e43b Remove potentially confusing line in docs 2020-04-05 12:20:07 +01:00
Joe Rickerby 0bdafc5649 Set MACOSX_DEPLOYMENT_TARGET to 10.9, if not set by the user 2020-04-05 12:15:34 +01:00
Joe Rickerby 1eb5fa2311 Merge pull request #302 from henryiii/patch-1
Add GHA example
2020-04-02 22:51:11 +01:00
Henry Schreiner 5367e687f9 Replace most occurrences of nose with pytest 2020-03-31 15:14:27 -04:00
Henry Schreiner abdd1f71d1 Add GHA example 2020-03-31 14:51:32 -04:00
Filip Š ed50cfd20a Fix tests 2020-03-28 16:25:57 +01:00
Joe Rickerby 3fa9935d5b Ensure the correct versions of constraint files are used for each version 2020-03-28 09:52:28 +00:00
Joe Rickerby 13554d0490 Call get-pip.py on Windows with dependency constraint flags 2020-03-24 21:09:07 +00:00
Joe Rickerby 4b6df458fd Docs wording edit 2020-03-23 22:16:47 +00:00
Joe Rickerby de4bf6dafe Add missing version-specific constraint tests 2020-03-23 22:16:47 +00:00
Joe Rickerby ffaad9134b Remove PyPy version from PythonConfiguration 2020-03-18 10:11:09 +00:00
Joe Rickerby 33da3d65c7 Fix CUSTOM_COMPILE_COMMAND and add comment 2020-03-17 20:28:53 +00:00
Joe Rickerby 36a2f00e68 Revert "See stdout during tests to debug circleCI"
This reverts commit dc5dbea4c9.
2020-03-14 18:09:16 +00:00
Joe Rickerby 98dbbaecf4 Fix docker build on CircleCI 2020-03-14 17:27:51 +00:00
Joe Rickerby 7316d69139 Improve logging of docker calls 2020-03-14 17:21:47 +00:00
Joe Rickerby dc5dbea4c9 See stdout during tests to debug circleCI 2020-03-14 17:21:22 +00:00
Joe Rickerby 580b065bb0 Add no_output_timeout to CircleCI tests to prevent them timing out 2020-03-13 17:12:23 +00:00
Joe Rickerby 7090bfa4f1 Stop isn't necessary, docker rm will stop the container 2020-03-13 15:08:37 +00:00
Joe Rickerby 2db9d9a089 The docker container needs a main process 2020-03-13 15:08:10 +00:00
Joe Rickerby 94824f95af Merge remote-tracking branch 'origin/master' into deterministic-builds 2020-03-13 14:20:10 +00:00
Joe Rickerby 4e31c65d09 Workaround docker cp bug
https://github.com/moby/moby/issues/38995
2020-03-13 12:58:23 +00:00
Filip Š bbb77aa488 Update docs 2020-03-13 13:46:51 +01:00
Filip Š 1e08d29cfc Use package_dir to specify path to Python package 2020-03-13 13:45:14 +01:00
Joe Rickerby 40ff745321 Bump version: v1.3.0 2020-03-12 19:53:34 +00:00
Joe Rickerby 8f9a68fe94 Improve setup docs for Github actions 2020-03-12 19:46:58 +00:00
Joe Rickerby 840da16d39 Merge pull request #194 from mayeut/github-workflows
Add support for GitHub Actions
2020-03-12 09:25:31 +00:00
Joe Rickerby e49644edf2 Some docker fixes 2020-03-12 09:00:40 +00:00
Joe Rickerby c4f54c6aa3 Run each build using docker exec, for faster builds 2020-03-11 21:55:53 +00:00
Joe Rickerby 7efec9a0fc Try updating more things 2020-03-11 21:50:26 +00:00
Joe Rickerby b4ed192e88 Run dependency tests on pypy too, and update constraint for 3.6 2020-03-11 20:56:11 +00:00
Joe Rickerby b55e98fb2c Update test-pinned version of pip 2020-03-11 11:51:46 +00:00
Joe Rickerby cc956ea6cd Update version of setuptools used to test constraint file 2020-03-11 08:46:01 +00:00
Joe Rickerby 4fb4e44c23 Fix some errors introduced after the merge 2020-03-10 22:33:50 +00:00
Joe Rickerby 8603deac93 Update constraints 2020-03-10 21:50:20 +00:00
Matthieu Darbois b797430d21 Add support for GitHub Actions
Closes #159
2020-03-10 22:45:29 +01:00
Joe Rickerby 7ab2d599b9 Merge branch 'master' of github.com:joerick/cibuildwheel into deterministic-builds
# Conflicts:
#	cibuildwheel/__main__.py
#	cibuildwheel/linux.py
#	cibuildwheel/macos.py
#	cibuildwheel/windows.py
2020-03-10 21:16:45 +00:00
Yannick Jadoul c22d50427c Merge pull request #297 from YannickJadoul/travis-yml-reference-allow_failures
Use yaml anchors and references to not repeat full job in allow_failures
2020-03-10 01:05:29 +01:00
Yannick Jadoul ce85c8730d Use yaml anchors and references to not repeat full job in allow_failures 2020-03-09 21:03:15 +01:00
Joe Rickerby 34f8427aab Merge pull request #296 from myselfhimself/patch-1
Referencing gmic-py as Working example (for the macosx Github Actions…
2020-03-09 19:21:31 +00:00
Jonathan-David Schröder bb12d3dc31 Referencing gmic-py as Working example (for the macosx Github Actions builds) 2020-03-09 19:10:18 +01:00
Joe Rickerby 77fb97caf3 Fix typo 2020-03-08 18:08:48 +00:00
Joe Rickerby 23870b6780 Update options.md
Docs edit- now Windows does run in a shell too
2020-03-08 18:06:14 +00:00
Joe Rickerby 4caee57c21 Merge pull request #242 from Czaki/before_test
Add CIBW_BEFORE_TEST to customize test environment
2020-03-08 17:55:59 +00:00
Grzegorz Bokota 7e566e46ee uses sys.prefix instead of sys.executable in before_test 2020-03-08 14:25:42 +01:00
Joe Rickerby 02a52791c9 Fix incorrect constraints file on pypy2.7 2020-03-08 13:12:27 +00:00
Joe Rickerby 9ae2ae4ac6 Produce a python-3-only wheel 2020-03-08 13:10:06 +00:00
Joe Rickerby 42489436a2 Remove obsolete bumpversion config 2020-03-08 12:52:22 +00:00
Joe Rickerby 4628c1334e Bump version: v1.2.0 2020-03-08 12:50:23 +00:00
Joe Rickerby 18b4d42f83 Add bump_version.py script 2020-03-08 12:49:35 +00:00
Joe Rickerby dd2c27ab01 Some test fixes related to PyPy 2020-03-07 19:35:17 +00:00
Joe Rickerby ff99cb37f8 Update changelog 2020-03-07 19:09:28 +00:00
Joe Rickerby d0e5781832 Merge pull request #293 from joerick/windows-chain-commands
Allow chaining of commands on Windows
2020-03-07 18:39:04 +00:00
Joe Rickerby fd1cd2442c Merge remote-tracking branch 'origin/master' into deterministic-builds 2020-03-07 18:37:57 +00:00
Joe Rickerby ad1b59febf Remove hashes from constraint files 2020-03-07 18:31:39 +00:00
Joe Rickerby 7dfc173bca Update docs 2020-03-07 18:05:30 +00:00
Joe Rickerby 2f1ec582e9 Add constraints for python3.6 too 2020-03-07 17:53:12 +00:00
Grzegorz Bokota 79cf7e47ae fix test after rebase, fix typos in readme 2020-03-07 18:18:01 +01:00
Joe Rickerby 7c6e69ea28 Add separate constraints for Python3.5
The new virtualenv requires some packages whose latest versions are 3.6+
2020-03-07 17:05:14 +00:00
Joe Rickerby dbc2f06b9a Fix constraint resolution on pypy-2.7 2020-03-07 17:04:28 +00:00
Joe Rickerby 99dc079380 Merge pull request #292 from joerick/s390x-allow-failures
Allow failures on s390x on Travis
2020-03-07 14:55:53 +00:00
Joe Rickerby 04531d9058 Fix unit tests 2020-03-07 14:53:22 +00:00
Joe Rickerby 696067f19e Merge pull request #230 from mayeut/macos-appveyor
Add macOS support on AppVeyor
2020-03-07 14:17:07 +00:00
Joe Rickerby e934c8219e Merge pull request #291 from mayeut/update-cpython3.8
Update CPython 3.8 from 3.8.1 to 3.8.2 on macOS/Windows
2020-03-07 14:16:01 +00:00
Joe Rickerby e06b7696a0 Add missing function call, which causing tests to be skipped
(maybe types are not such a bad idea...)
2020-03-07 14:15:09 +00:00
Joe Rickerby 54fda3f965 Add back the version field to manylinux PythonConfiguration
(needed for constraints)
2020-03-07 14:13:04 +00:00
Joe Rickerby 219266258e Fix missing pypy image name 2020-03-07 14:12:15 +00:00
Joe Rickerby 298df76b8b Consume new config file with pypy and extra architectures 2020-03-07 13:39:57 +00:00
Joe Rickerby 7e583dcab7 Update constraints 2020-03-07 13:24:52 +00:00
Joe Rickerby 9768897764 Add other architectures and pypy to pinned image config.
Also, restructure the file to have platform first, then manylinux version
2020-03-07 13:24:38 +00:00
Joe Rickerby 8de326a67a Another test 2020-03-07 12:22:44 +00:00
Joe Rickerby c33fa2ada0 Add test for boolean ops on windows 2020-03-07 12:21:31 +00:00
Joe Rickerby 6265d87d09 Try removing the explicit cmd call 2020-03-07 12:17:49 +00:00
Grzegorz Bokota baba7706e0 add example with non pip python package 2020-03-07 12:24:15 +01:00
Grzegorz Bokota d613a8c1a6 remove clean files from setup.py, fixes in doc 2020-03-07 12:24:15 +01:00
Grzegorz Bokota 01a7c2d6df reorder before_test 2020-03-07 12:24:15 +01:00
Grzegorz BokotaandJoe Rickerby 6461074ec9 Apply spell suggestions from joerick code review
Co-Authored-By: Joe Rickerby <joerick@mac.com>
2020-03-07 12:24:15 +01:00
Grzegorz Bokota d9e6bbfa4f add documentation 2020-03-07 12:24:15 +01:00
Grzegorz Bokota 4e9316036c add before test variable 2020-03-07 12:24:15 +01:00
Joe Rickerby 93913ef2fa Remove debugging fail on s390x 2020-03-07 11:19:52 +00:00
mayeut 7903ff60f9 Update CPython 3.8 from 3.8.1 to 3.8.2 on macOS/Windows
Changelog: https://docs.python.org/release/3.8.2/whatsnew/changelog.html#python-3-8-2-final
2020-03-07 12:12:08 +01:00
mayeut 028c1dbf10 Add macOS support on AppVeyor 2020-03-07 12:03:00 +01:00
Joe Rickerby ce5fc12b5f Merge pull request #283 from Czaki/test_virtualenv2
change 02_test to check if virtualenv is properly used another version
2020-03-07 10:54:47 +00:00
Joe Rickerby 07fae7e0e5 Try neatening windows config 2020-03-07 10:52:53 +00:00
Joe Rickerby d0692932fb Fix travis deprecation warnings 2020-03-07 10:46:26 +00:00
Joe Rickerby 1238c9d7e5 Try 'minimal' build image 2020-03-07 10:38:27 +00:00
Joe Rickerby 38fef4e1d8 Consistent build names 2020-03-07 10:37:21 +00:00
Joe Rickerby 863829f67b Allow the failure of x390x and update Travis job names 2020-03-07 10:31:51 +00:00
Joe Rickerby 4456d51e03 Merge pull request #290 from joerick/remove-run-with-env
Try removing appveyor_run_with_env.cmd
2020-03-07 10:14:20 +00:00
Joe Rickerby ec42cb6f42 Fix example references to python3 on Windows, where it's only python
Fix #285
2020-03-06 10:31:01 +00:00
Joe Rickerby 850db69eb7 Try removing appveyor_run_with_env.cmd 2020-03-06 10:15:30 +00:00
Joe Rickerby 4e3cef81d7 Fix style errors 2020-03-06 09:08:20 +00:00
Joe Rickerby 83452b75dd Apply suggestions from code review 2020-03-05 18:28:16 +00:00
Grzegorz Bokota be9eae6828 test path_contains 2020-03-03 23:06:27 +01:00
Grzegorz Bokota 281caf3d2e bugfix for pypy 2020-03-02 15:01:02 +01:00
Grzegorz Bokota 6e41e729fe pin virtualenv to <20 on windows
list dir in test 

use bin directory in pypy
2020-03-02 15:01:02 +01:00
Grzegorz Bokota e0c456604d verify if __CIBW_VIRTUALENV_PATH__ is set 2020-03-01 19:49:46 +01:00
Joe Rickerby 1880b6d14d Merge remote-tracking branch 'origin/master' into deterministic-builds 2020-03-01 12:53:07 +00:00
Joe Rickerby 4c7453df6c Neater test implementation based on review 2020-03-01 12:32:41 +00:00
Joe Rickerby 5e16e86355 Fix some comments from review 2020-03-01 11:09:22 +00:00
Grzegorz Bokota 01dd18bbf8 change 02_test to check if virtualenv is properly used 2020-03-01 10:14:32 +01:00
Yannick Jadoul 774af30d71 Merge pull request #274 from YannickJadoul/undo-virtualenv-workaround
Revert "Keeping virtualenv<20 on macOS, until problems get fixed by new release"
2020-02-28 18:51:20 +01:00
Joe Rickerby 958fa1b824 Fix lint errors
Serves me right for editing code in the github editor!!
2020-02-28 16:26:08 +00:00
Joe Rickerby 8d8b91a9f6 Remove commented line of code and move comment 2020-02-28 16:23:38 +00:00
Joe Rickerby bae011950c Add note about changing python after cibuildwheel run
See #266
2020-02-28 11:30:58 +00:00
Joe Rickerby 9275e7431a Merge pull request #279 from joerick/fix-266
Change twine references to be immediately preceded by pip install in examples
2020-02-28 09:31:05 +00:00
Joe Rickerby 16e23410b4 Change twine references to be immediately preceded by the pip install
line

This ensures that the python that installs is the same python that
should execute the module (this sometimes isn't true on macOS because
the python.org installs that cibuildwheel makes take precedence over
the system versions)

Fix #266
2020-02-27 20:30:02 +00:00
Joe Rickerby d32055e8a9 Merge pull request #278 from metabolize/bump-macos-image
Bump MacOS build image on Azure Pipelines
2020-02-27 20:12:55 +00:00
Yannick Jadoul 1199d78d88 Always unset __PYVENV_LAUNCHER__ environment variable to avoid unwanted surprises 2020-02-27 16:56:47 +01:00
Joe Rickerby be72b8b85d Update README.md 2020-02-27 09:12:50 +00:00
Joe Rickerby 12f0eff609 Readme improvements 2020-02-26 22:29:53 +00:00
Joe Rickerby 4bc7e4f40d Use python3 instead of python in examples 2020-02-26 22:10:42 +00:00
Paul Melnikow a68f8b23e5 Bump MacOS build image on Azure Pipelines
The 10.13 image is no longer supported and will be removed on 3/23.

Closes #276
2020-02-26 16:47:26 -05:00
Joe Rickerby 6ad0aebaf8 Merge pull request #273 from mtreinish/non-x86-support
Add support for manylinux wheels on non-x86 platforms
2020-02-26 20:43:37 +00:00
Yannick Jadoul 7d0cc37b17 Revert "Keeping virtualenv<20 on macOS, until problems get fixed by new release"
This reverts commit 691174cf11.
2020-02-25 13:36:21 +01:00
Matthew Treinish 05df9bbfd4 Add comment and update test_06 skip message 2020-02-21 09:32:09 -05:00
Matthew TreinishandJoe Rickerby f8d2982166 Update CI.md
Co-Authored-By: Joe Rickerby <joerick@mac.com>
2020-02-21 09:27:47 -05:00
Matthew Treinish 36e0618992 Update options.md 2020-02-21 06:48:10 -05:00
Matthew Treinish 549fc8a93e Extract platform check to separate function 2020-02-21 06:43:56 -05:00
Matthew Treinish 5549eb3165 Update examples and CI.md 2020-02-21 06:37:45 -05:00
Matthew Treinish 7b906fb5dc Update README table 2020-02-20 17:43:38 -05:00
Matthew Treinish 90da096b14 More test updates 2020-02-20 17:29:28 -05:00
Matthew Treinish 43c45b6011 Update tests again 2020-02-20 16:24:52 -05:00
Matthew Treinish 6ddac481c0 Fix typo 2020-02-20 16:18:51 -05:00
Matthew Treinish a83ac06c8d Fix small oversights 2020-02-20 16:17:51 -05:00
Matthew Treinish ec4ea4e011 Adjust tests when running on non-x86 2020-02-20 16:12:54 -05:00
Matthew Treinish ec5670a476 Use platform instead of distutils 2020-02-20 16:12:29 -05:00
Matthew Treinish ce76b74251 Add support for manylinux wheels on non-x86 platforms
This commit adds config options and identifiers for building manylinux
wheels on non-x86 platforms. Based on what travis and manylinux2014
support this includes aarch64 (ARMv8), ppce64le (power pc 64bit little
endian), and the s390x platforms.

Fixes #269
2020-02-20 13:57:00 -05:00
Yannick Jadoul 65792bd700 Merge pull request #264 from YannickJadoul/check-python-path
Checking python in PATH is the one `cibuildwheel` installed/expects
2020-02-20 12:10:37 +01:00
Yannick Jadoul d14427d781 Adding more informative error messages 2020-02-20 00:17:06 +01:00
Yannick Jadoul 2ce304d5d9 Add test checking cibuildwheel detects when PATH is messed up by CIBW_ENVIRONMENT 2020-02-20 00:16:09 +01:00
Yannick Jadoul 42a231f830 Making sure that python and pip are the ones we expect 2020-02-20 00:16:03 +01:00
Yannick Jadoul 4f47ab8052 Merge pull request #185 from YannickJadoul/pypy
Adding PyPy support
2020-02-20 00:06:04 +01:00
Yannick Jadoul cf73c3355e Addressing a few more minor remarks of @joerick 2020-02-19 17:10:17 +01:00
Grzegorz Bokota 0d2bec3cb8 Make sure PyPy is only patched once, and use check_call to execute 'patch' 2020-02-19 17:10:17 +01:00
Yannick Jadoul 60dd3f0807 Fixing paths of PyPy on manylinux after PyPy's manylinux image's update 2020-02-19 17:10:17 +01:00
Yannick Jadoul 8c6abf3811 Pushing creation of symlinks into install_cpython and install_pypy 2020-02-19 17:10:17 +01:00
Yannick Jadoul fc0dbe15d5 Fixing flake8 errors and warnings after rebasing 2020-02-19 17:10:17 +01:00
Yannick Jadoul 0423d79e63 Dropping PyPy version from PyPy build identifiers 2020-02-19 17:10:17 +01:00
Yannick Jadoul fd0a789988 Fix minor review comment from @Czaki and @joerick 2020-02-19 17:10:13 +01:00
Joe Rickerby 8a450b7655 Fix expected wheel test logic 2020-02-18 22:19:13 +00:00
Joe Rickerby 5187633e26 Add the --no-download flag to virtualenv, to prevent it getting the latest
version of pip, setuptools, wheel from PyPI on creation.

Virtualenv will use bundled version of those tools instead
2020-02-18 22:03:14 +00:00
Joe Rickerby fc20273f8b Remove the unit test check - the versions are determined by virtualenv at creation time 2020-02-18 21:55:03 +00:00
Joe Rickerby f55a5d44a3 Fix typo and add debug logging 2020-02-18 21:03:00 +00:00
Joe Rickerby fd69aed369 Remove dead code 2020-02-18 20:45:13 +00:00
Joe Rickerby ddc4fb2ab8 Add tests for pinned software in setup.py of test project 2020-02-18 20:44:52 +00:00
Joe Rickerby 3c20f70c5d Add test for user-specified constraints file 2020-02-18 20:38:14 +00:00
Joe Rickerby b7fc45afd9 Fix expected wheels in test 2020-02-18 20:21:08 +00:00
Joe Rickerby c9e4a66915 Add a test case for pinned tool versions 2020-02-18 09:33:07 +00:00
Joe Rickerby fe3abfba92 Docs updates 2020-02-18 09:32:02 +00:00
Yannick Jadoul 1e317895fe Adding PyPy images to main_options_test::test_manylinux_images 2020-02-15 23:47:07 +01:00
Yannick Jadoul b743b8ae5b Fixing Windows tests by skipping pp27 in 10_cpp_standards tests (and pp36 for C++17) on Windows 2020-02-15 23:47:03 +01:00
Grzegorz Bokota 176f4aca1f Apply PyPy patch with default MACOSX_DEPLOYMENT_TARGET to local installation 2020-02-15 23:24:51 +01:00
Yannick Jadoul 60f198c90d Changing the expected wheel filenames to the new pip>=20 tags 2020-02-15 23:24:51 +01:00
Yannick Jadoul 11423a47f6 Reverting PyPy manylinux docker image back to the official version, now that it supports 7.3.0 2020-02-15 23:24:51 +01:00
Yannick Jadoul aac5db8a46 Cleaning up Python installations on Windows and macOS, and creating PyPy executable python symlinks outside of installation directory 2020-02-15 23:24:51 +01:00
Yannick Jadoul 17137c3c2f Changing *-manylinux_pypy_x86_64 build identifiers to *-manylinux_x86_64 2020-02-15 23:24:51 +01:00
Yannick Jadoul bafb4fd294 Adding PyPy to the README and docs 2020-02-15 23:24:51 +01:00
Yannick Jadoul fea54e25ab PyPy 7.3.0 released! 2020-02-15 23:24:51 +01:00
Yannick Jadoul 4c718706c8 Trying out PyPy 7.3.0rc3 on manylinux2010 as well, with a temporary newer version of manylinux2010-pypy_x86_64 image 2020-02-15 23:24:51 +01:00
Yannick Jadoul 08d3ee1d91 Updating PyPy to v7.3.0rc3 on macOS and Windows 2020-02-15 23:24:51 +01:00
Yannick Jadoul e80f7f4774 Trying out PyPy 7.3.0rc1 on macOS and Windows 2020-02-15 23:24:51 +01:00
Yannick Jadoul 186e09d543 Implementing @mayeut's suggestion for alternative way of generating CPython/PyPy manylinux and Windows platform tags in test/shared/utils.py 2020-02-15 23:24:51 +01:00
Yannick Jadoul ae6832e18d Building PyPy wheels on macOS 2020-02-15 23:24:51 +01:00
Yannick Jadoul 743051a453 Using C:\cibw as base folder for PyPy installation (cfr. #197) 2020-02-15 23:24:51 +01:00
Yannick Jadoul 129cf601da Building PyPy wheels on Windows 2020-02-15 23:24:51 +01:00
Yannick Jadoul dd26ef8ac6 Updated PyPy from 7.1.1 to 7.2.0 2020-02-15 23:24:51 +01:00
Yannick Jadoul ef80beb433 Skipping PyPy for 06_docker_images test, and manylinux1 and manylinux2014 runs of 08_manylinuxXXXX_only test 2020-02-15 23:24:51 +01:00
Yannick Jadoul 100fc14411 Adding PyPy builds to Linux, using the manylinux2010-pypy_x86_64 image 2020-02-15 23:24:51 +01:00
Joe Rickerby bf87df5d62 Ensure subprocess.run commands succeed with check=True 2020-02-15 12:46:55 +00:00
Joe Rickerby 4c076b8d41 Fix piping script into docker bash 2020-02-15 12:32:33 +00:00
Joe Rickerby 50bd6f41da Merge branch 'master' into deterministic-builds 2020-02-15 12:22:34 +00:00
Joe Rickerby cf8fa693b8 Change flake8 config to make it easier to run locally 2020-02-15 12:15:44 +00:00
Joe Rickerby f2c2a06c19 Merge fixes and code style 2020-02-15 11:57:31 +00:00
Joe Rickerby 103381774c Merge remote-tracking branch 'origin/master' into deterministic-builds 2020-02-15 11:45:54 +00:00
Yannick Jadoul d9948da29a Merge pull request #212 from nsoranzo/flake8
Fix all PEP-008 issues
2020-02-14 18:14:36 +01:00
Nicola Soranzo c738481e82 Rename main_util_fixtures.py to conftest.py to allow fixture auto discovery
Also fix new PEP-008 issues.
2020-02-14 15:50:06 +00:00
Nicola Soranzo c15d656726 Add a CircleCI job for flake8 2020-02-14 15:50:06 +00:00
Nicola Soranzo cab6ecef24 Fix all PEP-008 issues 2020-02-14 15:50:06 +00:00
Yannick Jadoul 1e420a9b57 Merge pull request #270 from YannickJadoul/debug-virtualenv
Fixing macOS CI and tests after lastest release of virtualenv
2020-02-14 14:06:17 +01:00
Yannick Jadoul 691174cf11 Keeping virtualenv<20 on macOS, until problems get fixed by new release 2020-02-14 13:32:49 +01:00
Yannick Jadoul 0b0830fbbb Merge pull request #265 from YannickJadoul/drop-2.7
Dropping Python 2.7 host support
2020-02-04 23:35:19 +01:00
Yannick Jadoul 165e51aec5 Remove 'from __future__ import print_function' lines 2020-02-04 11:58:52 +01:00
Grzegorz Bokota 48055273f1 Remove inheritance from object base 2020-02-04 11:58:52 +01:00
Yannick Jadoul e8d121552c Remove a few more Python 2-compatibility workarounds 2020-02-04 11:58:52 +01:00
Yannick Jadoul 67ec8fe99f Removing Python 2-compatible imports of urllib.request.open and shlex.quote 2020-02-04 11:58:52 +01:00
Yannick Jadoul b900b2d51e Ditching run_docker for subprocess.run 2020-02-04 11:58:52 +01:00
Yannick Jadoul 9fe8d29545 Dropping Python 2 from setup.py 2020-02-04 11:58:52 +01:00
Yannick Jadoul 692c64ffd9 Removing Python 2 configurations for CI runs 2020-02-04 11:58:50 +01:00
Joe Rickerby ada46aaf43 Fix exports / version check ordering 2020-02-03 20:50:11 +00:00
Joe Rickerby 67022e620e Merge pull request #263 from joerick/cython-error-reporting
Raise a warning if .so files were found in a project that fails to build
2020-02-03 20:33:54 +00:00
Joe Rickerby 17a019b450 Neaten comment 2020-02-03 19:01:17 +00:00
Joe Rickerby bf65679cc3 Fix imports on Python 2 2020-02-03 18:59:32 +00:00
Joe Rickerby a953c5f4ee Remove auditwheel from pinned deps - it's preinstalled on manylinux
auditwheel's pinning of an old version of 'wheel' is causing problems on
mac
2020-02-03 09:02:17 +00:00
Joe Rickerby d8a245dcf6 Use abspath for constraints file 2020-02-02 23:05:58 +00:00
Joe Rickerby e32d0af532 Allow any version of the docker image in the unit test 2020-02-02 22:38:09 +00:00
Yannick Jadoul ffec9aecf8 Update line in docs/cpp_standards.md on setting MACOSX_DEPLOYMENT_TARGET >= 10.9 (see #220) 2020-02-02 20:07:22 +01:00
Joe Rickerby 6177408076 Consume our pinned manylinux image version file for the defaults 2020-02-02 18:09:29 +00:00
Joe Rickerby baa0897f1d Add unit test case and fix filename confusion 2020-02-02 17:46:12 +00:00
Joe Rickerby b9607ffae7 Add ability to pin different dependencies for each python version 2020-02-02 17:30:27 +00:00
Joe Rickerby 076987cb7e Move the config flow control of the linux build into Python
The use of separate bash processes for each build means we can be a bit
freer with environment pollution
2020-02-02 16:03:33 +00:00
Joe Rickerby bad72cbb15 Merge remote-tracking branch 'origin/master' into deterministic-builds 2020-02-02 15:21:42 +00:00
Joe Rickerby 17a224c525 Ignore a python2 virtualenv too 2020-02-02 15:16:36 +00:00
Joe Rickerby 4bc851ddf2 Add an editorconfig to standardise styles across projects
See https://editorconfig.org/
2020-02-02 15:16:23 +00:00
Joe Rickerby 0124d174be Raise a warning if .so files were found in a project that fails to build
Fix #139
2020-02-02 14:33:36 +00:00
Joe Rickerby 8236877f02 Merge pull request #220 from mayeut/macos-platform
Only build x86_64 / Intel 10.9+ on macOS
2020-02-01 23:07:47 +00:00
Joe Rickerby c3f628d03d Add migration for build identifier change, and test for migration 2020-02-01 21:44:07 +00:00
Joe Rickerby 8ead985cfd Generate separate python2 constraint files 2020-01-31 20:27:29 +00:00
Joe Rickerby 1b9b6e9000 Add the ability to pin docker image tags (this isn't consumed yet) 2020-01-31 20:00:30 +00:00
Joe Rickerby 042efd6090 Update constraints 2020-01-31 19:59:57 +00:00
Joe Rickerby b159617a3e Vendor get-pip (version 19.3.1) 2020-01-31 19:08:19 +00:00
Joe Rickerby a97b6a13f1 Fix test protection reference 2020-01-31 17:11:56 +00:00
Joe Rickerby a143ff2bfd Use the internal download() function rather than curl 2020-01-31 17:06:58 +00:00
Joe Rickerby 1a7d1d8cb1 Add MACOSX_DEPLOYMENT_TARGET flag and don't overwrite user-set env vars 2020-01-31 17:05:32 +00:00
Joe Rickerby 68d688c016 Merge pull request #257 from YannickJadoul/newer-dockcross-images
Clean up temporary workaround in test/06_docker_images/cibuildwheel_test.py
2020-01-31 15:50:42 +00:00
Yannick Jadoul 88029d2a28 Clean up temporary workaround in test/06_docker_images/cibuildwheel_test.py 2020-01-30 17:20:14 +01:00
mayeut 513ef49cd4 Only build x86_64 / Intel 10.9+ on macOS 2020-01-29 22:59:01 +01:00
Joe Rickerby c0967ad622 Fix docker copy 2020-01-28 22:26:34 +00:00
Joe Rickerby 1cae983592 Add docs for CIBW_DEPENDENCY_VERSIONS 2020-01-28 22:18:37 +00:00
Joe Rickerby 06696c46a0 Pin tool dependencies whenever we pip install using a constraints file 2020-01-28 22:04:37 +00:00
Joe Rickerby b779a88fde Add note about 254 {vmImage: 'vs2017-win2016'} on Azure to docs
See #254
2020-01-28 21:28:22 +00:00
Joe Rickerby 379cf2dc13 Merge pull request #156 from Czaki/master
upgrade macos version for support c++11
2020-01-27 18:53:32 +00:00
Grzegorz Bokota b64b106fbd use pypi wheel 2020-01-27 09:36:41 +01:00
Joe Rickerby 973ecf53b3 Merge pull request #249 from joerick/pypi-token-examples
Switch examples to use PyPI API tokens
2020-01-19 01:07:33 +00:00
Joe Rickerby 186599a1f0 Switch examples to use PyPI API tokens 2020-01-18 11:15:40 +00:00
Yannick Jadoul aca7611fc4 Merge pull request #248 from YannickJadoul/travis-ci-if-tagged
Remove check for branch of tags in examples/travis-ci-test-and-deploy.yml; fix #246
2020-01-17 11:00:00 +01:00
Yannick Jadoul 9d44d9edf0 Remove check for branch of tags in examples/travis-ci-test-and-deploy.yml; fix #246 2020-01-16 17:17:20 +01:00
Grzegorz Bokota 2473c405bc again change pinned version of wheel 2020-01-16 16:10:05 +01:00
Grzegorz Bokota 984df80ec9 change pinned version of wheel 2020-01-16 16:10:05 +01:00
Yannick Jadoul 0d5a2a7843 Moving MACOSX_DEPLOYMENT_TARGET from test utils' expected_wheels to run_cibuildwheel, and some minor style fixes 2020-01-16 16:10:05 +01:00
Grzegorz Bokota 1f784a1a29 fix conflicts with main branch 2020-01-16 16:10:05 +01:00
Yannick Jadoul e64916fe9c Rewording a few things in cpp_standards.md, and some other minor fixes 2020-01-16 16:10:05 +01:00
Grzegorz Bokota 9cb796edcd update docs 2020-01-16 16:10:05 +01:00
Grzegorz Bokota 758f158bbd Update information about need to use modern standards in c++
add test for c++ standards for all platform change macos platform tag on more generic.
2020-01-16 16:10:05 +01:00
Joe Rickerby d17517902e Merge pull request #241 from Czaki/fix_docs_link
fix link for CIBW_BUILD_VERBOSITY in README.md
2020-01-07 08:50:51 +00:00
Grzegorz Bokota 200d4e3b8c fix link for CIBW_BUILD_VERBOSITY in README.md 2020-01-07 09:04:58 +01:00
Yannick Jadoul 9648b44bdf Merge pull request #232 from Czaki/improve_platform_tag_tests
Test main function with unit tests
2019-12-30 20:12:38 +01:00
Yannick Jadoul 492b5f4039 Splitting off fake_project_dir fixture from mock_protection, only mocking os.path.exist for setup.py in the mocked project directory 2019-12-27 00:56:00 +01:00
Matthieu Darbois 651f6a9172 Merge pull request #238 from mayeut/update-python
Update CPython on macOS / Windows
2019-12-26 16:07:19 +01:00
Yannick Jadoul fabb82e9cf Add manylinux2014 to unit_test/main_options_test.py::test_manylinux_images 2019-12-26 15:03:13 +01:00
Yannick Jadoul 8bfe9ac6cd Fix @joerick's remarks in unit_test/main_options_test.py 2019-12-26 14:55:08 +01:00
Yannick Jadoul de55153931 Remove 'from cibuildwheel import linux, macos, windows' from new tests, as imports are done in fixtures 2019-12-26 14:55:08 +01:00
Yannick Jadoul a9c968868a Fix main_platform_test.py::test_platform_argument, making sure --platform overrides CIBW_PLATFORM 2019-12-26 14:55:08 +01:00
Yannick Jadoul 05e7858815 Refactoring main_function_test.py 2019-12-26 14:55:08 +01:00
Grzegorz Bokota 5e33011229 remove apply_mock_protection by making it fixture 2019-12-26 14:55:08 +01:00
Grzegorz Bokota 0b707b22ed split test function on parts to be more readable. 2019-12-26 14:55:08 +01:00
Grzegorz Bokota d66e201c3f test main function with unit tests 2019-12-26 14:55:08 +01:00
mayeut 6732812ad7 Update CPython on macOS / Windows
- Update CPython 3.7 from 3.7.5 to 3.7.6
- Update CPython 3.8 from 3.8.0 to 3.8.1
2019-12-26 14:26:58 +01:00
mayeut cbb7eafd1f Remove extras spaces 2019-12-26 14:25:33 +01:00
Joe Rickerby be721153af Merge pull request #231 from YannickJadoul/docs-include-examples
Including CI configurations from examples into docs
2019-12-26 11:57:52 +00:00
Joe Rickerby ef67ddd351 Merge pull request #237 from Czaki/repeat_get_pip_download
Repeat get-pip download on fail
2019-12-26 11:23:09 +00:00
Grzegorz BokotaandMatthieu Darbois 0af635fb86 Update cibuildwheel/macos.py
Co-Authored-By: Matthieu Darbois <mayeut@users.noreply.github.com>
2019-12-18 23:22:19 +01:00
Grzegorz Bokota 32182f3edc re raise last exception in windows 2019-12-17 23:23:57 +01:00
Grzegorz BokotaandMatthieu Darbois ebcda4d049 Update cibuildwheel/macos.py
Co-Authored-By: Matthieu Darbois <mayeut@users.noreply.github.com>
2019-12-17 22:40:00 +01:00
Grzegorz Bokota dd9b665c1d retry on macos with cli arguments 2019-12-17 21:34:26 +01:00
Grzegorz Bokota e00f03047a reduce repetition in download retry 2019-12-17 11:53:57 +01:00
Grzegorz Bokota e0b385a520 Move windows repetition download to download function. 2019-12-17 10:55:16 +01:00
Grzegorz Bokota a1832ae6c6 Repeat get-pip download on fail 2019-12-17 01:09:06 +01:00
Yannick Jadoul 795413e5c0 Fix typo in docs 2019-12-15 13:55:44 +01:00
Yannick Jadoul eda3dc1a4f Moving Azure, AppVeyor, and CircleCI minimal examples in docs also to their own file under examples/ 2019-12-10 14:57:25 +01:00
Yannick Jadoul 472fa32d9f Added {% include ... %} directive for including examples/travis-ci-minimal.yml in docs/setup.md 2019-12-08 23:51:09 +01:00
Yannick Jadoul 2f41683e85 Including example Travis CI configuration from examples/ directory in docs/setup.md 2019-12-08 23:50:47 +01:00
Joe Rickerby 7709989603 Bump version 2019-12-07 14:58:10 +00:00
Joe Rickerby 31e67c4f1f Update changelog 2019-12-07 14:58:00 +00:00
Joe Rickerby 11bde36627 Merge pull request #234 from Czaki/fix_setup_cfg
change directory to not conflict with setup.cfg of package
2019-12-07 14:35:38 +00:00
Grzegorz Bokota 5941ba7daf add tests 2019-12-05 21:13:11 +01:00
Grzegorz Bokota c1df977e11 change directory to not conflict with setup.cfg of package 2019-12-03 22:07:47 +01:00
Matthieu Darbois 1dbb12daaa Add manylinux2014 x86_64/i686 (#215) 2019-12-02 11:07:56 +01:00
Joe Rickerby a005e263fc Merge pull request #233 from Czaki/fix_doc_environment
Add example of usage more than one environment variable
2019-12-02 08:54:26 +00:00
Grzegorz Bokota 2a1081c5e5 update docs with information about more than one environment variable. 2019-12-01 21:45:08 +01:00
Joe Rickerby 9c908daf27 Merge pull request #226 from Czaki/fix_platform_bug
Add better protection to unittest to be shure that it will create no changes on developer machine
2019-11-29 09:34:52 +00:00
Joe Rickerby 054be2eff2 Merge pull request #228 from SethMMorton/update-travis-examples
Update travis examples
2019-11-28 22:45:09 +00:00
Seth Morton 20ba988b72 Add an example folder with Travis-CI examples
I have placed two example Travis-CI configurations in an examples/
folder. The first is the same as in the README, and the second shows how
to both test and deploy in two stages.

I am hoping that examples might be added for other CI providers as well,
so that users can see different approaches to building and deploying
wheels.
2019-11-25 18:59:07 -08:00
Seth Morton 190b013c61 Update Travis CI examples
For a more granular view of why each of these changes were made, please
see https://github.com/joerick/cibuildwheel-autopypi-example/pull/5.

High-level overview:
 - Adding Windows support
 - Remove "sudo: required" for linux
 - Use "python -m pip" instead of using an environment variable
 - Add "install:" and "after_success:" steps so that errors get handled
   and reported properly
 - Rename "matrix:" to "jobs:" as this is the now preferred keyword
2019-11-25 15:08:18 -08:00
Grzegorz Bokota c966c6d098 Add mock for better protection of unit tests launch.
change behavior of main function to always end with exit.
2019-11-24 12:17:08 +01:00
Grzegorz Bokota d2700bc3b4 fix UnboundLocalError instead of proper error message (#221)
* fix UnboundLocalError: local variable 'platform' referenced before assignment
* add test to protect against regression
2019-11-21 22:45:33 +01:00
Matthieu Darbois 09e72800c6 Run each test using a temporary directory (#217) 2019-11-20 22:20:53 +01:00
Joe Rickerby 2b62eef9e7 Merge pull request #211 from nsoranzo/delocate_command
Add `CIBW_REPAIR_WHEEL_COMMAND` env variable
2019-11-20 19:58:19 +00:00
Nicola Soranzo 85cba9b1eb Move Platform-specific variants before Examples 2019-11-17 19:08:22 +00:00
Nicola Soranzo 402ec9e4ac Address one more review comment 2019-11-15 02:56:30 +00:00
Nicola Soranzo e9fd9eaead Address @joerick's comments 2019-11-15 02:27:39 +00:00
Nicola Soranzo 0e04fafd3a Add CIBW_REPAIR_COMMAND env variable
to allow different options for auditwheel/delocate, alternative
commands and a future Windows equivalent.

Fix https://github.com/joerick/cibuildwheel/issues/191 .
2019-11-14 12:10:55 +00:00
Yannick Jadoul 34515b78c6 Merge pull request #209 from YannickJadoul/silence-script-not-on-path-warnings
Avoid script location warnings on Windows
2019-11-14 11:59:40 +01:00
Yannick Jadoul 7d99ccfc7b Collapse multiple 'pip install's into one in windows.py and macos.py, and replace full path by 'python' in windows.py 2019-11-12 23:47:06 +01:00
Yannick Jadoul dc01231301 Replace a few shell invocations by simple_shell in windows.py 2019-11-12 22:25:54 +01:00
Matthieu Darbois 96a2505e78 Merge pull request #207 from mayeut/doc-appveyor-linux
Update doc for AppVeyor on linux
2019-11-12 22:11:27 +01:00
Yannick Jadoul d3fd087166 Run python get-pip.py with Scripts directory in PATH to avoid warnings, and reorder steps to match macOS 2019-11-12 17:05:37 +01:00
mayeut b3f82d52cc Update doc for AppVeyor on linux 2019-11-12 01:20:06 +01:00
Matthieu Darbois 7d90a2f16b Merge pull request #204 from mayeut/appveyor-linux
Rework platform detection to ignore CI provider to determine windows/linux/macos.
A check is still present to check if CI is running or not.
2019-11-11 22:24:52 +01:00
mayeut f4318e15b7 Keep CI check for platform auto 2019-11-11 21:49:16 +01:00
mayeut d3450e84ac Rework platform detection to ignore CI provider.
CI provider is now mostly irrelevant, rework platform detection with that in mind.
Run linux test in AppVeyor
2019-11-10 23:40:20 +01:00
Joe Rickerby a3e9b7b8ec Embed readme in project for PyPI 2019-11-10 19:13:49 +00:00
Joe Rickerby 1a9c6a5f66 Add azure pipelines status badge 2019-11-10 19:02:06 +00:00
Joe Rickerby c44a084a44 Really fix link 2019-11-10 19:01:58 +00:00
Joe Rickerby 1e102b9bc5 Fix link 2019-11-10 15:54:17 +00:00
Joe Rickerby 46f1906e2d Add docs badge 2019-11-10 15:52:01 +00:00
Joe Rickerby 79c480b896 Update changelog 2019-11-10 15:47:33 +00:00
Joe Rickerby 734ca6bfbd Remove @tgarc from maintainers 2019-11-10 15:45:34 +00:00
Joe Rickerby beda529298 Bump version 2019-11-10 15:16:37 +00:00
Joe Rickerby 292bf42cb0 Merge pull request #169 from joerick/docs
Pull docs into a dedicated documentation site
2019-11-10 15:14:09 +00:00
Joe Rickerby a8d1e69783 Merge pull request #200 from joerick/test-bash-errexit-again
Add check that failing tests fail on manylinux1 specifically
2019-11-10 15:07:45 +00:00
Joe Rickerby ab53f06bc6 Merge pull request #201 from mayeut/remove-macos-travis-python2
Remove macOS python2 on Travis CI
2019-11-10 15:04:01 +00:00
Joe Rickerby 053a154d1d Merge pull request #197 from mayeut/cibw-dir
Use specific cibw directory on Windows to prevent collisions with installed software
2019-11-10 15:03:09 +00:00
Joe Rickerby 7d08bac099 Add note about command line option 2019-11-10 14:57:21 +00:00
Joe Rickerby 8e274700f4 Reformat examples on the options page and add a comment for each one 2019-11-10 14:54:56 +00:00
Joe Rickerby 22ae365ae9 Clean up plugin 2019-11-10 13:22:44 +00:00
Joe Rickerby ccd22e5a5a Allow line breaks in table headers 2019-11-10 13:22:35 +00:00
Joe Rickerby 2692162617 Improve BUILD/SKIP options formatting 2019-11-10 13:21:05 +00:00
Joe Rickerby d112b343e1 Fix link 2019-11-10 13:20:33 +00:00
Joe Rickerby 7ac8798d26 fix element id 2019-11-10 12:08:14 +00:00
Joe Rickerby a41ce8e4a0 Add options summary to readme 2019-11-09 19:41:42 +00:00
Joe Rickerby 07fd1a3203 Formatting and polish 2019-11-09 19:38:59 +00:00
mayeut 81ce8116b5 Remove macos python2 on travis-ci
Testing with python2 is already done on circle-ci
2019-11-09 20:18:39 +01:00
mayeut c82330b0bc Use specific cibw directory on Windows to prevent collisions with installed software 2019-11-09 19:44:14 +01:00
Joe Rickerby 50a518eac4 Merge remote-tracking branch 'origin/master' into test-bash-errexit-again 2019-11-09 18:41:56 +00:00
Joe Rickerby 42d1610d52 Merge pull request #175 from GjjvdBurg/returncode
Make sure build fails when test command fails
2019-11-09 18:41:26 +00:00
Joe Rickerby ac51d22884 Merge remote-tracking branch 'origin/master' into docs 2019-11-09 18:23:41 +00:00
Joe Rickerby c42cca1c86 Add test that failing tests fail on manylinux1 specifically 2019-11-09 18:07:46 +00:00
Joe Rickerby b51434b5a8 Merge pull request #199 from mayeut/cibuildwheel-pythons
Tests cibuildwheel across different python versions
2019-11-09 17:49:00 +00:00
mayeut 7dee79a96b Add python_requires metadata 2019-11-09 12:38:38 +01:00
mayeut ce93a03098 Fix tests on Windows Python 3.8 2019-11-09 12:16:25 +01:00
mayeut 319aee73f2 Force python 3.8 on Azure 2019-11-09 11:19:02 +01:00
Gertjan van den Burg 5210ad3610 clarify comment at if statement 2019-11-08 10:53:18 +00:00
Gertjan van den Burg def8f9a2e3 Remove errexit flag for test command subshell 2019-11-08 10:53:06 +00:00
Gertjan van den Burg f716f87a04 Merge branch 'master' into returncode 2019-11-08 10:51:49 +00:00
Joe Rickerby 0375e92110 Merge pull request #188 from metabolize/fix-appveyor-setup-doc-outline
Readme: Fix the outline for Appveyor setup
2019-11-05 19:28:05 +00:00
Gertjan van den Burg 560c1adeb7 Merge branch 'master' into returncode 2019-11-05 17:09:17 +00:00
Paul Melnikow 3c9875db19 Readme: Remove obsolete bullet for Appveyor setup 2019-11-05 09:41:23 -05:00
Joe Rickerby 89e2ac7ebf Merge pull request #180 from mayeut/nuget
Adding Python 3.8, Always use nuget to install python on Windows
2019-11-05 09:06:20 +00:00
mayeut 05ab66cf97 Fix documentation for macOS python 3.8 2019-11-04 22:49:53 +01:00
mayeut 104dcf1d37 Add python 3.8 support 2019-11-04 22:22:40 +01:00
mayeut f2ef7a6169 Always use nuget to install python on Windows 2019-11-04 22:08:30 +01:00
mayeut 58048b4bb1 Remove trailing-spaces from README.md
Also replace double-space by a backslash to show intent of a line-break.
2019-11-04 22:05:24 +01:00
Joe Rickerby 332674a382 Merge pull request #168 from mayeut/drop-python-3.4
Drop python 3.4
2019-11-04 19:15:05 +00:00
Joe Rickerby 88ef908bad Merge remote-tracking branch 'origin/master' into docs
Manually merged updates to README.md across to docs

# Conflicts:
#	README.md
2019-11-03 19:38:18 +00:00
Joe Rickerby eb8c926eba Remove unused CSS and visual tweaks 2019-11-03 19:13:56 +00:00
Joe Rickerby 73cba728a1 Have the page generate markdown for the README 2019-11-03 19:06:48 +00:00
Joe Rickerby 1446529f7c Sort out page titles 2019-11-03 19:06:33 +00:00
Joe Rickerby 51649fd806 Add page from wiki to 'tips and tricks' page 2019-11-03 18:40:14 +00:00
Joe Rickerby f55b663ea7 Add requirement for our markdown plugin 2019-11-03 18:35:17 +00:00
Joe Rickerby 2360c406bf Add JS code to generate a table of contents 2019-11-03 18:35:06 +00:00
Joe Rickerby 5db3763b2d Add plugin to import sections of readme into the documentation 2019-11-03 18:30:15 +00:00
mayeut bb0cad404b Drop python 3.4
Python 3.4 reached the end of its life on 16 March 2019. It's about time to drop support for Python 3.4.
2019-10-26 15:53:44 +02:00
Yannick Jadoul a6164f765c Merge pull request #183 from mayeut/macos-python3
Do not update brew python3
2019-10-26 15:47:08 +02:00
mayeut 892c7b4d9c Update .travis.yml 2019-10-26 14:45:24 +02:00
Joe Rickerby 3fcb902fd9 Merge pull request #171 from mayeut/python-3.7.5
Update CPython 2.7 from 2.7.16 to 2.7.17 & 3.7 from 3.7.4 to 3.7.5 on macOS
2019-10-25 10:06:09 +01:00
Yannick Jadoul 8c9345fa1f Updated line of README mistakenly claiming Windows is not supported on Travis CI 2019-10-24 14:00:28 +02:00
mayeut 5eab3620c9 Update CPython 2.7 from 2.7.16 to 2.7.17 & 3.7 from 3.7.4 to 3.7.5 on macOS 2019-10-23 22:59:17 +02:00
Grzegorz BokotaandJoe Rickerby 80974e5b39 Build Python wheels for windows on travis (#160)
* upgrade for windows on travis

* Install python on travis windows, update readme, update tests

* update readme, travis config and clean code

* install python inside cibuildwheel run

* use register to get python path

* fixes from review

* fix pip version

* use nuget for instal python

* clean code

* Update cibuildwheel/windows.py

Co-Authored-By: Joe Rickerby <joerick@mac.com>

* fixes from review

* Final bits of tidy up
2019-10-23 21:53:10 +01:00
Joe Rickerby 4f705b7cc9 Merge pull request #177 from joerick/failing-test-test
Add failing test check
2019-10-23 21:35:44 +01:00
Gertjan van den Burg e0eb375449 Returncode fix (#1)
Some trial and error to make sure it works reliably.

* remove test_retcode
* debug local bash settings
* set errexit explicitly in subshell
* set errexit also in the subshell in parenthesis
* debugging
* more debugging (exit code of sh)
* is the venv subshell returning exit 1?
* what if we remove the additional subshell?
* then we need to unquote the command
* if statement needs test command quoted
* simple if statement
* echo command needs to be removed of course
* remove debug statements
* check if setting errexit here is needed
* these settings can be removed
  At this point ("before") the shell already has errexit set.
* setting errexit in the sh invocation is needed
  This is not inherited, so it's good to specify it.
* just double checking that the subshell doesn't exit
* use solution from fvue.nl
* Solution doesn't seem to work, even popd is run
  So now I'm putting back the if statement, it seems
  to be the simplest and most effective solution.
* add a comment
* prove that errexit is necessary
* errexit is indeed needed for chaining
2019-10-21 11:42:43 +01:00
Joe Rickerby bbecbe43ec Add failing test check 2019-10-20 20:45:25 +01:00
Joe Rickerby 46865a5f40 Options page rework (incomplete) 2019-10-20 20:39:50 +01:00
Joe Rickerby b577c5f00f Misc copy edits 2019-10-20 19:43:13 +01:00
Joe Rickerby ee2a90880a Merge pull request #155 from YannickJadoul/manylinux2010-alternative
Adding support for building manylinux2010 wheels - alternative
2019-10-20 19:29:19 +01:00
Yannick Jadoul 31d89377da Updated README with new CIBW_MANYLINUX_*_IMAGE options 2019-10-19 14:07:50 +02:00
Gertjan van den Burg 0c33a58579 failing test breaks out of subshell 2019-10-18 11:45:48 +01:00
Gertjan van den Burg 3842cfd853 Attempt at getting the retcode of the test process 2019-10-18 11:31:48 +01:00
Yannick Jadoul 2e0dc40e3f Adding manylinux2010_i686 image and simplifying tests' utils.expected_wheels() 2019-10-16 01:15:09 +02:00
Yannick Jadoul c6f1382813 Making manylinux1 still the default for manylinux_i686 builds 2019-10-16 00:35:20 +02:00
Yannick Jadoul 1220fbbd4b Adding detection of old CIBW_MANYLINUX1_*_IMAGE options and manylinux1-* build identifiers in CIBW_BUILD and CIBW_SKIP 2019-10-16 00:35:20 +02:00
Yannick Jadoul 179148b0e5 Updated preset values for CIBW_MANYLINUX_*_IMAGE, fixed skip message in 08_manylinux2010_only test, and added clarifying comment on multiple wheels in Linux bash script 2019-10-16 00:35:20 +02:00
Yannick Jadoul 4536b23a1d Adding test accessing manylinux2010-only ABI 2019-10-16 00:34:13 +02:00
Yannick Jadoul 4571262803 Adapting Linux bash script for multiple output wheels from auditwheel 2019-10-16 00:34:13 +02:00
Yannick Jadoul 27517cd8a0 Updating test 06_docker_images to use new CIBW_MANYLINUX_*_IMAGE options 2019-10-16 00:33:45 +02:00
Yannick Jadoul 54dd72de66 Copying all created manylinux wheels to the output directory 2019-10-16 00:33:45 +02:00
Yannick Jadoul 7978247fa7 Fixing tests still failing as manylinux1 wheels are also produced by auditwheel 2019-10-16 00:33:45 +02:00
Yannick Jadoul 7cadc6374a Fixing tests failing because of new manylinux2010 default 2019-10-16 00:33:45 +02:00
Yannick Jadoul e194dad0da Alternative proposal to generalize manylinux builds and support manylinux2010 2019-10-16 00:33:45 +02:00
Joe Rickerby 5f416b194a Merge pull request #164 from astrofrog/virtualenv-notox
Run tests in clean virtual environment [version without tox]
2019-10-13 21:24:19 +01:00
Joe Rickerby 2a244616ad windows: only make venv when test is defined and isolate env vars 2019-10-12 10:47:00 +01:00
Joe Rickerby bfa3eebb7f Remove redundant if clause 2019-10-12 10:44:47 +01:00
Joe Rickerby b0c2fd8af2 macos: only make venv when test is defined and isolate env vars 2019-10-12 10:35:45 +01:00
Joe Rickerby cf90846161 linux: run tests in a subshell, only create env if test defined 2019-10-12 10:17:28 +01:00
Joe Rickerby 89bb2d352d Add docs links to the setup guide 2019-10-07 09:15:59 +01:00
Joe Rickerby c1572e4ff4 Ensure the pinned versions in docs are bumped 2019-10-06 23:09:34 +01:00
Joe Rickerby 1741d7ce1f Docs samples should pin versions 2019-10-06 23:05:55 +01:00
Joe Rickerby 05385b1cb0 Add readthedocs config 2019-10-06 22:57:41 +01:00
Joe Rickerby 3ba7aa3532 Copy improvements 2019-10-06 20:36:37 +01:00
Joe Rickerby bb2a5f8d17 Formatting improvements 2019-10-06 20:36:21 +01:00
Joe Rickerby 44d0dcba12 Update license copyright 2019-10-06 11:38:48 +01:00
Joe Rickerby 4c86af69a5 Readme tweaks 2019-10-06 11:38:36 +01:00
Joe Rickerby 93663d19df Move changelog back into the readme 2019-10-06 11:38:24 +01:00
Joe Rickerby c006fdab36 Migrate more README over to the docs 2019-10-02 09:49:31 +01:00
Joe Rickerby d280f0f16a Add options to docs 2019-09-29 21:53:18 +01:00
Joe Rickerby b49754dc7d mkdocs setup 2019-09-29 20:55:41 +01:00
Joe Rickerby 3302aa136b Update README 2019-09-29 20:46:31 +01:00
Joe Rickerby 14d9b4091e Update changelog 2019-09-29 20:46:23 +01:00
Joe Rickerby aeeac6725a Bump version 2019-09-29 20:40:44 +01:00
Joe Rickerby 41b4b092b1 Merge pull request #167 from mayeut/update-openssl
Update openssl patch from 1.0.2s to 1.0.2t on macOS
2019-09-29 20:34:56 +01:00
mayeut 28186bf142 Update openssl patch from 1.0.2s to 1.0.2t on macOS 2019-09-22 14:46:17 +02:00
Joe Rickerby 4e10d9d897 Merge pull request #163 from astrofrog/circleci-verbose
Clean up CircleCI YAML syntax
2019-09-21 16:26:13 +01:00
Yannick Jadoul c963013858 Fixing weird issue with the shebang of pip installed scripts and __PYVENV_LAUNCHER__ 2019-09-11 23:56:27 +02:00
Thomas Robitaille 9470ca623f Use python -m virtualenv on Windows and Linux 2019-09-10 09:40:20 +01:00
Thomas Robitaille 2e3bc016b4 Try and avoid relying on global virtualenv command 2019-09-10 09:40:20 +01:00
Thomas Robitaille d4732130a7 Use unique temporary directory for virtual environment on linux 2019-09-10 09:40:20 +01:00
Thomas Robitaille 853699c265 Fix calls to pip and virtualenv 2019-09-10 09:40:19 +01:00
Thomas Robitaille 40968897a8 Test package in a virtualenv on Linux and Windows 2019-09-10 09:40:19 +01:00
Thomas Robitaille fdc2ba8715 Try and work around the fact we can't source activate 2019-09-10 09:40:19 +01:00
Thomas Robitaille 3ff59eefc6 Fix syntax 2019-09-10 09:40:19 +01:00
Thomas Robitaille e3416abeb9 Use virtual environment for testing on MacOS X 2019-09-10 09:40:18 +01:00
Joe Rickerby 2ab2d079ab Merge pull request #161 from astrofrog/test-extras-require
Add support for specifying test-time dependencies via extras_require
2019-09-09 22:18:33 +01:00
Joe Rickerby 5e529969ea Merge pull request #153 from mayeut/update-python
Update Python from 3.7.2 to 3.7.4 on macOS
2019-09-09 21:48:50 +01:00
Joe Rickerby b7a689e349 Merge pull request #157 from altendky/patch-1
Add Twisted to working examples list
2019-09-09 21:48:30 +01:00
Thomas Robitaille 4f4fed06e0 Added unit test for CIBW_TEST_EXTRAS 2019-09-09 12:49:11 +01:00
Thomas Robitaille 45fcebf9d8 Fix issue on linux 2019-09-09 12:49:05 +01:00
Thomas Robitaille e67b3bc611 Added support for CIBW_TEST_EXTRAS to allow extras_require to be used to install test dependencies 2019-09-09 12:49:04 +01:00
Thomas Robitaille d8456a0ffa Use one-line commands on CircleCI to ensure that command output is shown 2019-09-07 21:55:42 +01:00
Kyle Altendorf 73681d9b24 Add Twisted to working examples list 2019-08-28 23:06:38 -04:00
mayeut 02ed7b2262 Update Python from 3.7.2 to 3.7.4 on macOS 2019-07-27 11:24:47 +02:00
Joe Rickerby ab86b8cd93 Merge pull request #149 from mayeut/update-openssl
Update openssl patch from 1.0.2r to 1.0.2s on macOS
2019-06-24 10:02:41 +01:00
mayeut 3a03df8ec9 Update openssl patch from 1.0.2r to 1.0.2s on macOS 2019-06-23 18:15:46 +02:00
Joe Rickerby 0e78b2b1f5 Merge pull request #147 from cher-nov/V_for_Veyor
Correct spelling: capitalized 'V' in 'AppVeyor'
2019-06-21 08:53:24 +01:00
Joe Rickerby 5b14c8c0ec Merge pull request #148 from delivrance/add-tgcrypto
Add pyrogram/tgcrypto to README.md
2019-06-21 08:51:49 +01:00
Dan 0627bd09d4 Add pyrogram/tgcrypto to README.md 2019-06-14 21:38:38 +02:00
Dmitry D. Chernov a5e64e216c Correct spelling: capitalized 'V' in 'AppVeyor' 2019-06-10 20:27:32 +10:00
Joe Rickerby 23cf50614f Merge pull request #142 from kngwyu/upd-readme
Specify cibuildwheel=0.11 in Azure example
2019-05-29 08:47:04 +01:00
kngwyu 1e08ff03b3 Specify cibuildwheel=0.11 in README example 2019-05-29 15:15:58 +09:00
Joe Rickerby 2216385c0b Update changelog 2019-05-28 19:22:25 +01:00
Joe Rickerby a1fc0cb117 Bump version 2019-05-28 19:17:28 +01:00
Joe Rickerby 430b71c767 Ensure resources are packaged in release tarballs and wheels
Fix #141
2019-05-28 19:17:05 +01:00
Joe Rickerby 14f14a24d3 Add config for universal wheel support so we can post wheels to PyPI too 2019-05-28 10:34:31 +01:00
Joe Rickerby b732026734 Update changelog 2019-05-26 12:53:51 +01:00
Joe Rickerby 0d85db7111 Bump version 2019-05-26 12:48:43 +01:00
Joe Rickerby 477fc7e060 Merge pull request #132 from joerick/azure-windows
Support Windows on Azure Pipelines [continued...]
2019-05-26 11:38:36 +01:00
Joe Rickerby 17566cdee7 Don't expect Python 3.4 wheels on Azure 2019-04-27 12:12:02 +01:00
Joe Rickerby 49bc742add Remove unused imports 2019-04-27 10:23:07 +01:00
Joe Rickerby 4cbb67fac1 Merge remote-tracking branch 'origin/master' into azure-windows 2019-04-27 10:22:00 +01:00
Joe Rickerby 2e3155decf Merge branch 'master' into azure-windows 2019-04-27 10:11:30 +01:00
Joe Rickerby 719352b1d2 Merge pull request #137 from joerick/custom-test-checks
Custom test checks let individual tests assert exactly which wheels they expect to produce
2019-04-25 14:56:28 +01:00
Joe Rickerby f7d93cc9e4 Fix function name 2019-04-23 22:23:54 +01:00
Joe Rickerby 3f5572e956 Make included scripts virtualenv-friendly 2019-04-23 22:17:59 +01:00
Joe Rickerby bab8b6668e Full error output during pytest fails 2019-04-23 22:17:25 +01:00
Joe Rickerby f29697d623 Retain PYTHONPATH if already in env 2019-04-23 22:17:03 +01:00
Joe Rickerby e87032c830 Rework tests check all wheels produced against a reference list
Also, wrap the cibuildwheel call to make building env easier
2019-04-23 22:15:02 +01:00
Joe Rickerby e360a04dc1 Use utils.platform for platform checks 2019-04-22 23:25:14 +01:00
Joe Rickerby 9050137d2b Neaten the environment modification using triple-quotes and dict.update 2019-04-22 23:23:49 +01:00
Joe Rickerby 857aafbd3f Move the pythonpath fiddling to the test runner
instead of including it in every test
2019-04-22 23:13:34 +01:00
Joe Rickerby 0cd3e426bc Minor formatting fixes 2019-04-22 19:05:34 +01:00
Joe Rickerby 8b632bcb6d Skip cleanup if its not needed (when a test is skipped) 2019-04-22 18:55:55 +01:00
Joe Rickerby 364fc5220e another trailing comma 2019-04-22 18:44:09 +01:00
Joe Rickerby 0ed37f268a In general, prefer single quotes 2019-04-22 18:35:57 +01:00
Joe Rickerby f410fbdd03 Remove trailing commas from environment declarations 2019-04-22 18:33:03 +01:00
Joe Rickerby 21fb27faf7 Rework custom test machinery to give the individual tests more control
on how they're run, and combine environment.json and check.py
2019-04-22 18:22:43 +01:00
Yannick Jadoul ac4b62ca07 Update README.md with --print-build-identifiers switch 2019-04-22 16:15:47 +02:00
Yannick Jadoul 3f7a4d753f Skip non-linux builds for 06_docker_images test, now that we have custom checks 2019-04-20 22:12:45 +02:00
Yannick Jadoul 95d2086ced Adding check.py to tests, rather than a simple generic assert on number of wheels 2019-04-20 20:49:56 +02:00
Yannick Jadoul 52e8f41b5c Added --print-build-identifiers command line option 2019-04-20 19:02:35 +02:00
Joe Rickerby 1e2a2e7d4d Revert "Add azure-template.yml for more compact config"
This reverts commit 6377854545.
2019-04-06 18:03:05 +01:00
Joe Rickerby 6377854545 Add azure-template.yml for more compact config 2019-04-06 17:34:36 +01:00
Joe Rickerby be57269d5d Remove 3.4 from the pipelines config because 3.4 isn't supported 2019-04-06 16:23:14 +01:00
Joe Rickerby d5856884a3 README updates 2019-04-06 16:18:26 +01:00
Joe Rickerby c2d3dc3b0f Update README.md
Fix #133. Thanks @zackw for the report!
2019-04-05 21:31:50 +01:00
Joe Rickerby 9116217b60 Update README.md
Readme improvements, adding Azure config and putting services behind disclosure triangles
2019-03-11 22:37:59 +00:00
Joe Rickerby a8f6684bfd Skip Python 3.4 builds on Azure 2019-03-11 19:59:31 +00:00
Joe Rickerby 6852d87d2e Update changelog 2019-03-10 23:37:36 +00:00
Joe Rickerby 054c273997 Bump version 2019-03-10 23:32:06 +00:00
Joe Rickerby 652d094e46 Fix typo 2019-03-10 23:19:22 +00:00
Joe Rickerby 1bfe6d45bd Add auto-detect platform for Azure 2019-03-10 23:07:14 +00:00
Joe Rickerby aefde9535b Add azure-pipelines test run config 2019-03-10 22:50:07 +00:00
Joe Rickerby d46fb62e95 Refactor for code style 2019-03-10 22:41:55 +00:00
Joe Rickerby 87a9d170b0 Merge pull request #131 from mayeut/openssl-1.0.2r
Update openssl patch from 1.0.2q to 1.0.2r on macOS
2019-03-10 22:38:47 +00:00
Joe Rickerby dcce949d3c Vendor appveyor_run_with_cmd, but don't use it on azure pipelines 2019-03-10 22:03:31 +00:00
mayeut 1d3c59d804 Update openssl patch from 1.0.2q to 1.0.2r on macOS 2019-03-10 22:28:43 +01:00
Joe Rickerby 0b791dbea5 Merge pull request #130 from YannickJadoul/macos-python-2.7.16
Updating version of Python 2.7 to 2.7.16 on macOS
2019-03-10 21:26:04 +00:00
Yannick Jadoul 44256e4aa5 Revert "Running 'pip install --upgrade setuptools' with 'sudo' on macOS, fixing #122" (#129)
This reverts commit d79ca07bbb.
2019-03-10 21:25:28 +00:00
Joe Rickerby 243103762b Merge branch 'master' into azure-windows 2019-03-10 20:29:05 +00:00
Yannick Jadoul b579cd5f2a Updating version of Python 2.7 to 2.7.16 on macOS 2019-03-10 21:22:41 +01:00
Joe Rickerby 8523b25a18 Merge pull request #128 from YannickJadoul/fix-bashlex-install-permission
Fixing issue #127 by avoiding bashlex 0.13 in 'install_requires'
2019-03-10 19:52:32 +00:00
Yannick Jadoul 637a251b79 Fixing issue #127 by avoiding bashlex 0.13 in 'install_requires' 2019-03-10 14:57:43 +01:00
Thomas Robitaille ac76af4f75 Support Python location on Windows in Azure Pipelines 2019-02-22 22:19:41 +00:00
Joe Rickerby a6ff864010 Merge pull request #125 from ushuz/patch-1
Add missing date to changelog
2019-02-15 22:28:18 +00:00
John Hu 79f044314b Add missing date to changelog 2019-02-14 11:58:56 +08:00
Joe Rickerby 0c0e21aa83 Update changelog 2019-02-03 21:58:53 +00:00
Joe Rickerby f1bba58f86 Bump version 2019-02-03 21:54:00 +00:00
Joe Rickerby 56218d896c Merge pull request #123 from YannickJadoul/fix-issue-122
Running 'pip install --upgrade setuptools' with 'sudo' on macOS, fixing #122
2019-02-03 21:37:57 +00:00
Yannick Jadoul d79ca07bbb Running 'pip install --upgrade setuptools' with 'sudo' on macOS, fixing #122 2019-01-30 17:36:17 +01:00
Joe Rickerby c6f4f01732 Update README.md
ref #93
2019-01-07 22:17:19 +00:00
mayeut 586b3c7197 Update openssl patch from 1.0.2p to 1.0.2q on macOS 2019-01-07 18:34:46 +01:00
mayeut 0b4475ed07 Update Python from 3.6.7, 3.7.1 to 3.6.8, 3.7.2 on macOS 2019-01-06 23:52:57 +01:00
Yannick Jadoul 38b3b0a3da Merge pull request #114 from YannickJadoul/deterministic-preamble-order
Sorting build options dict items when printing preamble
2018-11-30 16:09:53 +01:00
Yannick Jadoul 5adfce9838 Merge pull request #113 from xanderyzwich/master
Refactoring: remove package_name
2018-11-30 00:03:03 +01:00
Yannick Jadoul bc83839387 Sorting build options dict items when printing preamble 2018-11-30 00:02:18 +01:00
Yannick Jadoul 481b1cb060 Revert "Uninstalling oclint in Travis CI config to fix HomeBrew upgrade of gcc (triggered by upgrading Python)"
This reverts commit c43f1b6e3d.
2018-11-29 23:37:04 +01:00
Yannick Jadoul ccfc3c3aa1 Fixing indentation error, and keeping only check for setup.py in project root directory in __main__.py 2018-11-29 23:26:10 +01:00
unknown 3d23cbf2a6 corrected as per notations from @YannickJadoul on #113 2018-11-29 02:44:19 +00:00
Joe Rickerby b9a296324d Merge pull request #108 from YannickJadoul/py27-popen-args
Fixing "AttributeError: 'Popen' object has no attribute 'args'" on Python 2.7 for Linux builds
2018-11-06 21:22:22 +00:00
Corey McCarty c4822ebdd6 Remove Try/Except for package_name #102
recommended by @YannickJadoul
2018-11-05 16:30:34 -06:00
corey.d.mccarty 2ca6500bba removed '--name' pieces for #102 2018-11-05 11:47:31 -05:00
corey.d.mccarty 8dd71189b2 removed 'package-name' as per #102 2018-11-05 11:16:42 -05:00
Yannick Jadoul a448c02d7f Fixing "AttributeError: 'Popen' object has no attribute 'args'" on Python 2.7 for Linux builds 2018-10-28 11:51:10 +01:00
Yannick Jadoul 696866bfe1 Merge pull request #111 from mayeut/openssl-update
Update openssl patch from 1.0.2o to 1.0.2p on macOS
2018-10-28 11:46:20 +01:00
Yannick Jadoul 1faa2fe5df Merge pull request #110 from mayeut/python-update
Update Python from 3.6.6, 3.7.0 to 3.6.7, 3.7.1 on macOS
2018-10-28 11:46:05 +01:00
Yannick Jadoul 602acebcc8 Merge pull request #112 from YannickJadoul/brew-upgrade-gcc
Fixing Travic CI build with HomeBrew upgrade of gcc
2018-10-28 11:44:38 +01:00
Yannick Jadoul c43f1b6e3d Uninstalling oclint in Travis CI config to fix HomeBrew upgrade of gcc (triggered by upgrading Python) 2018-10-27 19:22:53 +02:00
mayeut 0d3e67b1f9 Update openssl patch from 1.0.2o to 1.0.2p on macOS 2018-10-26 19:25:25 +02:00
mayeut e3b565320c Update Python from 3.6.6, 3.7.0 to 3.6.7, 3.7.1 on macOS 2018-10-26 19:23:49 +02:00
Yannick Jadoul 56973d34df Merge pull request #109 from safijari/add_apriltags2_to_readme
Add apriltags2-ethz library to readme
2018-10-18 11:13:02 +02:00
Jariullah Safi 66e9a1cc19 Update README.md 2018-10-18 00:04:25 -07:00
Joe Rickerby 2a91396064 Bump version 2018-09-23 22:08:39 +01:00
Joe Rickerby 1c98a9ed22 Update changelog 2018-09-23 22:07:47 +01:00
Joe Rickerby dbcf5ef64b Clarify README shared library note 2018-09-23 22:07:36 +01:00
Joe Rickerby cc030312a3 Prepare changelog update 2018-09-23 21:38:36 +01:00
Joe Rickerby 31c162fa59 Remove Python 3.3 support on windows 2018-09-23 21:38:36 +01:00
Joe Rickerby d80636aa22 Merge pull request #101 from YannickJadoul/cibw-build
Adding CIBW_BUILD option
2018-09-23 21:31:42 +01:00
Yannick Jadoul 22a6f0c7a9 Fixing tests by reducing minimum number of built wheels 2018-09-23 13:08:26 +02:00
Yannick Jadoul 7362075b61 Changing variable name of BuildSelector instance, updating Python version in test 04_build_skip, and adding unit tests for BuildSelector 2018-09-23 13:08:26 +02:00
Yannick Jadoul c108807e16 Renaming test 04_skip to 04_build_skip and amending it to test CIBW_BUILD as well 2018-09-23 13:07:28 +02:00
Yannick Jadoul 05a054245a Updating README.md to include CIBW_BUILD and interation with CIBW_SKIP 2018-09-23 13:07:28 +02:00
Yannick Jadoul a5f89fa7aa Adding CIBW_BUILD option and changing util.BuildSkipper to util.BuildSelector 2018-09-23 13:07:28 +02:00
Yannick Jadoul cf73851c61 Merge pull request #97 from YannickJadoul/docker-without-timeout
Reordering the Linux docker commands to get rid of timeout logic
2018-09-23 12:18:32 +02:00
Joe Rickerby 9372e37b18 Merge pull request #95 from anthrotype/overwrite-existing-wheel
overwrite existing wheel file with same name
2018-09-16 19:24:21 +01:00
Joe Rickerby fbb447c3aa Merge pull request #100 from msanders/patch-1
Add AutoPy
2018-09-15 11:08:42 +01:00
Michael Sanders 1e978d1b35 Add AutoPy 2018-09-14 12:36:46 -07:00
Yannick Jadoul 1dbda7af7e Add '--force' to 'docker rm' command in Linux builds 2018-09-12 11:52:41 +02:00
Yannick Jadoul b64770a560 Cleaning up use of run_docker and removing some debug output 2018-09-09 16:11:42 +02:00
Yannick Jadoul 4cc09a35b4 Removing monotonic from dependencies (until necessary again) 2018-09-09 01:24:07 +02:00
Yannick Jadoul d4885fe44a Fixing outdated Python 2 syntax error 2018-09-09 01:24:07 +02:00
Yannick Jadoul fcf1e9cd84 Moving stdin communication with docker to run_docker function 2018-09-09 01:23:48 +02:00
Yannick Jadoul f417a91a57 First try at getting rid of timeout logic in Linux docker handling, by swapping splitting docker run into create and start 2018-09-09 00:53:08 +02:00
Cosimo Lupo 1b9c74aabc macos: no need to call os.remove, shutil.move overwrites on posix 2018-09-08 18:41:39 +01:00
Joe Rickerby 35832c4309 Readme tweaks 2018-09-08 17:13:39 +01:00
Cosimo Lupo c9fffab6ea remove same-named wheel before shutil.move
In https://github.com/adobe-type-tools/afdko/pull/595 we attempt to build a py2.py3 wheel
thus the filename of the wheel is the same as the previous ones, and it causes a shutil.Error
https://travis-ci.org/adobe-type-tools/afdko/jobs/424691105#L1460

just remove the previous existing file before moving the new one (they'll be identical anyway,
or at least they *should*).
2018-09-06 11:34:50 +01:00
Kyle Altendorf 9f7fdbf456 Add CircleCI support (#91)
* Initial guess at supporting CircleCI

joerick/cibuildwheel#90

* Add note about setup_remote_docker on Circle

* Add diagnostic print of entire docker command

* Add more diagnostic prints

* Retrigger for Circle build

* Preliminary .circleci/config.yml

* Add workflows to Circle

* drop osx on circle

* call python3 directly on circle

* drop repeat pip install

* use a virtualenv on circle

* use a virtualenv on circle... again

* use a virtualenv on circle... again... again

* setup_remote_docker on circle

* try to manually copy into docker on circle

* correct Host

* correct docker calls

* refactor docker calls

* take 2 on the docker cp destination

* more docker cp debugging

* more docker cp debugging... again

* docker cp explicitly to /project

* wait until docker container is up

* wait until docker container is up... again

* and copy results back

* and copy results back... again

* create /output in container

* create /output in container... again

* copy contents of container's /output

* Retrigger ci

* fix merge typo

* fix monotonic

* always install monotonic

* always install monotonic... again

* correct to use project_dir

* wait a bit longer and a bit smarter

* wait a bit longer and a bit smarter... again

* add back circle osx

* add back circle osx... again

* py2/3 for circle

* py2/3 for circle... again

* use python2.7 image on circle linux

* (mostly) remove unused ci host identification code

* skip inspecting docker for the container, just retry copy on failure

* cleanup docker container and images

* fully remove ci host detection

* docs and tidy

* add circle badge
2018-09-05 09:15:32 +01:00
Yannick Jadoul 7c6b331e15 Merge pull request #84 from YannickJadoul/unbuffered-output
Applying unbuffered output to all platforms instead of only Windows
2018-09-02 22:49:26 +02:00
Tommy 22f69e4ced Added a repo using cibuildwheel and fixed some spelling (#92)
* Added KDEpy and fixed some spelling

* Reversed spelling, added repo to README

* Fixing single 'progams' typo in README
2018-09-02 22:40:49 +02:00
Joe Rickerby 4083a7600a Merge pull request #88 from miguelsousa/show-err-output
Improve error reporting during package name fetching
2018-08-21 22:52:45 +01:00
Miguel Sousa 20624e44a3 Improve error reporting during package name fetching 2018-08-21 14:11:28 -07:00
Yannick Jadoul 332b8ec6ac Merge pull request #86 from miguelsousa/patch-1
Update README.md
2018-08-20 09:09:51 +02:00
Miguel Sousa eaf59e385c Update README.md
Add horizontal rules between option descriptions; they make it easier to understand what text belongs to each option.
2018-08-19 21:06:43 -07:00
Yannick Jadoul 57454e75b0 Applying unbuffered output to all platforms instead of only Windows 2018-08-02 12:04:39 +02:00
Joe Rickerby 391c95d355 Update README.md 2018-07-29 18:21:19 +01:00
Joe Rickerby 8124b14491 Bump version 2018-07-29 18:19:24 +01:00
Joe Rickerby b3b15f8404 Merge pull request #81 from madig/macos-test-cmd-in-shell
macOS: run test_command in shell
2018-07-29 14:05:57 +01:00
Joe Rickerby 9a96910919 Merge pull request #83 from mayeut/pybase64
Add pybase64 to the list of working examples
2018-07-29 14:01:43 +01:00
mayeut fce00dd77e Add pybase64 to the list of working examples 2018-07-11 00:03:15 +02:00
Joe Rickerby 6da52a544b Bump version 2018-07-10 19:03:48 +01:00
Joe Rickerby c8037fb237 Update changelog 2018-07-10 19:03:38 +01:00
Joe Rickerby 95a81f2216 Merge pull request #82 from mayeut/update-macos-python-3.6
Update Python 3.6 from 3.6.5 to 3.6.6 on macOS
2018-07-10 18:54:50 +01:00
Joe Rickerby 56c9c9864d Merge pull request #76 from jlaine/python37-windows
Build Windows wheels for Python 3.7 (fixes #75)
2018-07-10 18:51:47 +01:00
Joe Rickerby 0789842ef0 Add note about shell use on mac and linux 2018-07-10 18:46:10 +01:00
Joe Rickerby 5c47700d31 Add platform-specific notes to readme 2018-07-10 18:44:27 +01:00
Joe Rickerby 5ef7eeba4d Update readme: add @mayeut to maintainers team! 2018-07-10 18:39:29 +01:00
mayeut bb554acb28 Update Python 3.6 from 3.6.5 to 3.6.6 on macOS 2018-07-07 14:15:45 +02:00
Joe Rickerby ea3c52631f Add platform-specific CIBW_TEST_COMMAND and CIBW_TEST_REQUIRES variants 2018-07-05 09:58:05 +01:00
Joe Rickerby b18281867b Add test for CIBW_TEST_COMMAND running in a shell on mac and linux 2018-07-05 09:28:44 +01:00
Nikolaus Waxweiler 4a0d05df49 macOS: run test_command in shell
Fixes https://github.com/joerick/cibuildwheel/issues/39.
2018-07-04 15:56:12 +01:00
Joe Rickerby c1cd99ee4c Add check for python & pip within the configured python root 2018-07-01 21:38:14 +01:00
Joe Rickerby e68400b403 Update changelog 2018-07-01 21:30:53 +01:00
Jeremy Lainé 2f1f34f693 Build Windows wheels for Python 3.7 (fixes #75) 2018-07-01 22:30:22 +02:00
Joe Rickerby 3ef401b19e Bump version 2018-07-01 21:28:28 +01:00
Joe Rickerby 8800ea514b Merge pull request #79 from YannickJadoul/python-macos-3.7.0
Update Python 3.7.0rc1 to 3.7.0 on macOS
2018-07-01 21:27:00 +01:00
Yannick Jadoul f62b9755e1 Update Python 3.7.0rc1 to 3.7.0 on macOS 2018-06-30 18:28:04 +02:00
Joe Rickerby 033ba29ec6 Update changelog 2018-06-18 23:17:42 +01:00
Joe Rickerby 0627b38402 Bump version 2018-06-18 23:09:19 +01:00
Joe Rickerby 189dc13714 Merge pull request #71 from mayeut/macos-ssl
macOS: patch _ssl module on Python 3.4 & 3.5
2018-06-18 23:02:01 +01:00
Joe Rickerby 793026f3ed Merge pull request #60 from YannickJadoul/python-pip-replacement
Removing replacement of {python} and {pip} in CIBW_BEFORE_BUILD
2018-06-18 22:59:52 +01:00
Joe Rickerby 08b4895b9c Changelog update 2018-06-18 22:57:22 +01:00
Joe Rickerby 7c635b4550 Bump version 2018-06-18 22:52:02 +01:00
Joe Rickerby 33433f0b21 Merge pull request #73 from lelit/py37
Add support for Python 3.7
2018-06-18 22:50:54 +01:00
Joe Rickerby e3981db2a6 Skip the custom docker image specifier for Python 3.7
We'll reenable this when 3.7 is released and dockcross updates :)
2018-06-18 22:35:05 +01:00
Joe Rickerby 1ec652dff8 Fix pip variable use 2018-06-17 21:06:00 +01:00
Joe Rickerby d2394e9a57 Merge commit '57a2259a00bf7ea3309faa231406df8e487ae792' into python-pip-replacement
* commit '57a2259a00bf7ea3309faa231406df8e487ae792':
  Use travis-ci provided python3 on Linux
  linux: transfer ownership of the wheel to the current user
  Update changelog
  Bump version
  macOS/Windows: Update setuptools
  Drop python 3.3 support on Linux
  macOS: update to python 2.7.15
  Renaming util.get_build_verbosity_flag into util.get_build_verbosity_extra_flags
  Bump version
  windows: upgrade pip with 'python -m pip'
  Fixing empty verbosity flag argument to `subprocess.check_call`
  Adding an to make the `pip wheel` invocation more or less verbose
2018-06-17 21:00:16 +01:00
Joe Rickerby 0b21df216e update support matrix in readme 2018-06-17 20:52:46 +01:00
Lele Gaifax e5b9d1f586 Fix mistake in directory name 2018-06-16 15:23:26 +02:00
Lele Gaifax 9b31b5e6c9 Add support for Python 3.7
This enables building binary wheels for Python 3.7, now at its rc1 release.

It is included in the latest manylinux1 Docker image, see https://github.com/pypa/manylinux/pull/196.

Accordingly to https://www.appveyor.com/docs/build-environment/#python it is not yet available on Appveyor.
2018-06-16 13:42:11 +02:00
mayeut 1a910257bb macOS: patch _ssl module on Python 3.4 & 3.5 2018-05-06 17:13:21 +02:00
mayeut 4f542ca3d4 Add test for TLS 1.2 support & valid certificates 2018-05-06 17:13:21 +02:00
Yannick Jadoul 57a2259a00 Merge pull request #66 from mayeut/drop-linux-python3.3
Give ownership of the wheel files to the current user instead of root on Linux
2018-05-06 16:00:42 +02:00
mayeut d186b0bbb7 Use travis-ci provided python3 on Linux 2018-05-06 15:44:27 +02:00
mayeut 57cdb8711c linux: transfer ownership of the wheel to the current user 2018-05-06 15:44:27 +02:00
Joe Rickerby 7448ca3cf1 Update changelog 2018-05-04 10:21:34 -07:00
Joe Rickerby 0156a9a870 Fix "'NoneType' is not iterable" error
The build_options dict contains None objects ! :)
2018-04-08 23:38:54 +01:00
Joe Rickerby 460a4d9656 Code tidy/reorganise 2018-04-08 23:26:04 +01:00
Joe Rickerby b47a5c018f Remove unused warnings import 2018-04-08 19:11:38 +01:00
Joe Rickerby 94e33cd7e3 Switch to a more user-friendly warning style 2018-04-08 18:42:47 +01:00
Joe Rickerby c9c54602ed Correct comment 2018-04-08 18:42:21 +01:00
Joe Rickerby b74333a940 Simplify prepare_command function and add deprecation warning 2018-04-08 18:25:18 +01:00
Joe Rickerby 4655311a7a Merge origin/master into python-pip-replacement
* commit '71503b7143d22765a8f2b324dd75046644ea5726':
  Replacing leftover `test_command.format(...)` by `prepare_command(test_command, ...)` in linux.py
  Replacing {python} and {pip} in CIBW_TEST_COMMAND (and {project} in CIBW_BEFORE_BUILD) for consistency

# Conflicts:
#	README.md
#	cibuildwheel/macos.py
2018-04-08 18:11:00 +01:00
Joe Rickerby 5099d60584 Use a separate folder for bin overrides 2018-04-08 18:05:59 +01:00
Yannick Jadoul 2ebde4c078 Reverting removal of prepare_command to maintain backwards compatibility of configurations with {python} and {pip} 2018-04-08 17:01:54 +02:00
Yannick Jadoul 4d61b08fa3 Updating README, removing documentation on {python} and {pip} 2018-04-08 15:26:09 +02:00
Yannick Jadoul 5e009e53c9 Symlinking only on first-time installation of Python versions on mac OS X 2018-04-08 15:15:47 +02:00
Yannick Jadoul 783a4deec6 Symlinking python3 and pip3 to python and pip for OS X runs 2018-04-08 15:05:21 +02:00
Yannick Jadoul 529e22bfe0 Removing {python} from test 03_before_build 2018-04-08 14:14:01 +02:00
Yannick Jadoul 418cb9c39d Removing replacement of {python} and {pip} in CIBW_BEFORE_BUILD 2018-04-08 13:40:30 +02:00
111 changed files with 28506 additions and 1344 deletions
+59
View File
@@ -0,0 +1,59 @@
version: 2
jobs:
flake8-mypy:
docker:
- image: circleci/python:3.6
steps:
- checkout
- run:
name: Install flake8 & mypy
command: sudo python -m pip install flake8 mypy
- run:
name: flake8
command: flake8
- run:
name: mypy
command: mypy
osx-python3.6:
macos:
xcode: "9.4.1"
environment:
PYTHON: python3
steps:
- checkout
- run:
name: Prepare the environment.
command: bash .circleci/prepare.sh
- run:
name: Test.
command: venv/bin/python ./bin/run_tests.py
no_output_timeout: 30m
linux-python3.6:
docker:
- image: circleci/python:3.6
environment:
PYTHON: python3
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
no_output_timeout: 30m
workflows:
version: 2
all-tests:
jobs:
- flake8-mypy
- osx-python3.6
- linux-python3.6
+9
View File
@@ -0,0 +1,9 @@
set -o errexit
set -o xtrace
$PYTHON --version
$PYTHON -m pip --version
$PYTHON -m virtualenv -p $PYTHON venv
venv/bin/python -m pip install -r requirements-dev.txt
venv/bin/python -m pip freeze
venv/bin/python --version
+14
View File
@@ -0,0 +1,14 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# Use 4 spaces the Python files
[*.py]
indent_size = 4
+7
View File
@@ -0,0 +1,7 @@
# config file for https://github.com/bobvanderlinden/probot-auto-merge
# no approvals required, just the label is enough
minApprovals: {}
requiredLabels:
- merge when green
+36
View File
@@ -0,0 +1,36 @@
name: Test
on:
push: {}
pull_request:
paths-ignore:
- 'docs/**'
jobs:
test:
# skip branch builds on joerick/cibuildwheel, but always build `master` and pull requests
if: github.repository != 'joerick/cibuildwheel' || github.ref == 'refs/heads/master' || github.event_name == 'pull_request'
name: Test cibuildwheel on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, windows-latest, macos-latest]
python_version: ['3.7']
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
name: Install Python ${{ matrix.python_version }}
with:
python-version: ${{ matrix.python_version }}
- name: Install dependencies
run: |
python -m pip install -r requirements-dev.txt
- name: Install Visual C++ for Python 2.7
if: runner.os == 'Windows'
run: |
choco install vcpython27 -f -y
- name: Test cibuildwheel
run: |
python ./bin/run_tests.py
+7
View File
@@ -86,9 +86,13 @@ celerybeat-schedule
.venv
venv/
venv3/
venv2/
ENV/
env/
env2/
env2?/
env3/
env3?/
# Spyder project settings
.spyderproject
@@ -98,3 +102,6 @@ env3/
# VSCode project settings
/.vscode
# MyPy cache
.mypy_cache/
+21
View File
@@ -0,0 +1,21 @@
repos:
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.1
hooks:
- id: flake8
pass_filenames: true
# this seems to need to be here in addition to setup.cfg
exclude: cibuildwheel/resources/
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: check-yaml
- id: check-merge-conflict
- id: end-of-file-fixer
exclude: cibuildwheel/resources/pinned_docker_images.cfg
- repo: https://github.com/pre-commit/mirrors-mypy
rev: '' # Use the sha / tag you want to point at
hooks:
- id: mypy
files: cibuildwheel|test
exclude: cibuildwheel/resources
+11
View File
@@ -0,0 +1,11 @@
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
mkdocs:
configuration: mkdocs.yml
python:
version: 3.7
install:
- requirements: requirements-dev.txt
+48 -37
View File
@@ -1,46 +1,57 @@
language: generic
language: minimal
matrix:
branches:
only:
- master
jobs:
include:
# Linux Python 2
- sudo: required
- name: Linux | x86_64 + i686 | Python 3.6
language: python
services:
- docker
env:
- "PYTHON=python2"
python: 3.6
services: docker
env: PYTHON=python
# Linux Python 3
- sudo: required
- name: Linux | arm64 | Python 3.6
language: python
services:
- docker
env:
- "PYTHON=python3"
python: 3.6
services: docker
arch: arm64
env: PYTHON=python
- name: Linux | ppc64le | Python 3.6
language: python
python: 3.6
services: docker
arch: ppc64le
env: PYTHON=python
- name: macOS | x86_64 | Python 3.x
os: osx
env: PYTHON=python3
- name: Windows | x86_64 | Python 3.6
os: windows
language: shell
before_install:
- sudo apt-get -qq update
- sudo apt-get install -y python3-pip
# macOS Python 2
- os: osx
- choco install python3 --version 3.6.8 --no-progress -y
# Update root certificates to fix SSL error; see http://www.chawn.com/RootCerts.htm
- powershell "md C:\temp\certs; CertUtil -generateSSTFromWU C:\temp\certs\RootStore.sst; Get-ChildItem -Path C:\\temp\certs\Rootstore.sst | Import-Certificate -CertStoreLocation Cert:\\LocalMachine\\Root\\ | out-null"
env:
- "PYTHON=python2"
- PYTHON=C:\\Python36\\python
# macOS Python 3
- os: osx
env:
- "PYTHON=python3"
before_install:
- brew update
- brew outdated python || brew upgrade python
- &linux_s390x_36
name: Linux | s390x | Python 3.6
language: python
python: 3.6
services: docker
arch: s390x
env: PYTHON=python
script:
- |
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
$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 $PYTHON -m pip install -r requirements-dev.txt
sudo $PYTHON ./bin/run_tests.py
fi
allow_failures:
# must repeat the s390x job above exactly to match
- *linux_s390x_36
install: $PYTHON -m pip install -r requirements-dev.txt
script: $PYTHON ./bin/run_tests.py
+12
View File
@@ -0,0 +1,12 @@
This is a summary of the Python versions and platforms covered by the different CI platforms:
| | 3.6 | 3.7 | 3.8 |
|----------|------------------------------|------------------------------------------|------------------|
| Linux | Travis CI / CircleCI | AppVeyor² / GitHub Actions | Azure Pipelines |
| macOS | CircleCI | AppVeyor² / Travis CI¹ / GitHub Actions | Azure Pipelines |
| Windows | Travis CI / Azure Pipelines | AppVeyor² / GitHub Actions | Azure Pipelines |
> ¹ Python version not really pinned, but dependent on the (default) version of image used.
> ² AppVeyor only runs the "basic" test to reduce load.
Non-x86 architectures are covered on Travis CI using Python 3.6.
+5 -1
View File
@@ -1,6 +1,6 @@
This project is licensed under the 'BSD 2-clause license'.
Copyright (c) 2017, Joe Rickerby. All rights reserved.
Copyright (c) 2017-2019, Joe Rickerby and contributors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -22,3 +22,7 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Get-pip and Pip (bundled in cibuildwheel/resources) are licensed under the MIT
license. See https://github.com/pypa/get-pip/blob/master/LICENSE.txt
+402 -320
View File
@@ -1,431 +1,513 @@
cibuildwheel
============
[![PyPI](https://img.shields.io/pypi/v/cibuildwheel.svg)](https://pypi.python.org/pypi/cibuildwheel) [![Build Status](https://travis-ci.org/joerick/cibuildwheel.svg?branch=master)](https://travis-ci.org/joerick/cibuildwheel) [![Build status](https://ci.appveyor.com/api/projects/status/wbsgxshp05tt1tif/branch/master?svg=true)](https://ci.appveyor.com/project/joerick/cibuildwheel/branch/master)
[![PyPI](https://img.shields.io/pypi/v/cibuildwheel.svg)](https://pypi.python.org/pypi/cibuildwheel) [![Documentation Status](https://readthedocs.org/projects/cibuildwheel/badge/?version=stable)](https://cibuildwheel.readthedocs.io/en/stable/?badge=stable) [![Build Status](https://travis-ci.org/joerick/cibuildwheel.svg?branch=master)](https://travis-ci.org/joerick/cibuildwheel) [![Build status](https://ci.appveyor.com/api/projects/status/wbsgxshp05tt1tif/branch/master?svg=true)](https://ci.appveyor.com/project/joerick/cibuildwheel/branch/master) [![CircleCI](https://circleci.com/gh/joerick/cibuildwheel.svg?style=svg)](https://circleci.com/gh/joerick/cibuildwheel) [![Build Status](https://dev.azure.com/joerick0429/cibuildwheel/_apis/build/status/joerick.cibuildwheel?branchName=master)](https://dev.azure.com/joerick0429/cibuildwheel/_build/latest?definitionId=2&branchName=master)
[Documentation](https://cibuildwheel.readthedocs.org)
<!--intro-start-->
Python wheels are great. Building them across **Mac, Linux, Windows**, on **multiple versions of Python**, is not.
`cibuildwheel` is here to help. `cibuildwheel` runs on your CI server - currently it supports Travis CI and Appveyor - and it builds and tests your wheels across all of your platforms.
`cibuildwheel` is here to help. `cibuildwheel` runs on your CI server - currently it supports Azure Pipelines, Travis CI, AppVeyor, GitHub Actions and CircleCI - and it builds and tests your wheels across all of your platforms.
**`cibuildwheel` is in beta**. It's brand new - I'd love for you to try it and help make it better!
What does it do?
----------------
| | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit |
|---|---|---|---|---|---|
| Python 2.7 | ✅ | ✅ | ✅ | ✅ | |
| Python 3.3 | | | | ✅ | ✅ |
| Python 3.4 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ |
| | macOS x86_64 | Windows 64bit | Windows 32bit | manylinux x86_64 | manylinux i686 | manylinux aarch64 | manylinux ppc64le | manylinux s390x |
|---|---|---|---|---|---|---|---|---|
| CPython 2.7 | ✅ | ✅¹ | ✅¹ | ✅ | ✅ | | | |
| CPython 3.5 | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅² |
| CPython 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² |
| CPython 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² |
| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² |
| CPython 3.9³ | 🛠 | 🛠 | 🛠 | 🛠 | 🛠 | 🛠 | 🛠 | |
| PyPy 2.7 v7.3.0 | ✅ | | ✅ | ✅ | | | | |
| PyPy 3.6 v7.3.0 | ✅ | | ✅ | ✅ | | | | |
- Builds manylinux, macOS and Windows (32 and 64bit) wheels using Travis CI and Appveyor
<sup>¹ Not supported on Travis</sup><br>
<sup>² Beta support until Travis CI fixes <a href="https://travis-ci.community/t/no-space-left-on-device-for-system-z/5954/11">a bug</a></sup><br>
<sup>³ Python 3.9 is not yet ABI stable, so you shouldn't publish wheels with it yet. But if you want to check that your wheels build on Python 3.9, try our [`python3.9` branch](https://github.com/joerick/cibuildwheel/pull/382)!</sup>
- Builds manylinux, macOS and Windows wheels for CPython and PyPy using Azure Pipelines, Travis CI, AppVeyor, and CircleCI
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
- Runs the library test suite against the wheel-installed version of your library
Usage
-----
`cibuildwheel` currently works on **Travis CI** to build Linux and Mac wheels, and **Appveyor** to build Windows wheels.
`cibuildwheel` currently works on **Travis CI**, **Azure Pipelines**, **AppVeyor** and **GitHub Actions** to build wheels for all three supported platforms (Linux, macOS, Windows). On **CircleCI** Linux and macOS wheels can be built.
`cibuildwheel` is not intended to run on your development machine. It will try to install packages globally; this is no good. Travis CI and Appveyor run their builds in isolated environments, so are ideal for this kind of script.
| | Linux | macOS | Windows |
|-----------------|-------|-------|---------|
| Azure Pipelines | ✅ | ✅ | ✅ |
| Travis CI | ✅ | ✅ | ✅ |
| AppVeyor | ✅ | ✅ | ✅ |
| GitHub Actions | ✅ | ✅ | ✅ |
| CircleCI | ✅ | ✅ | |
### Minimal setup
`cibuildwheel` is not intended to run on your development machine. Because it uses system Python from Python.org it will try to install packages globally - not what you expect from a build tool! Instead, isolated CI services like Travis CI, CircleCI, Azure Pipelines and AppVeyor are ideal.
- Create a `.travis.yml` file in your repo.
<!--intro-end-->
```
language: python
matrix:
include:
- sudo: required
services:
- docker
env: PIP=pip
- os: osx
language: generic
env: PIP=pip2
Example setup
-------------
script:
- $PIP install cibuildwheel==0.8.0
- cibuildwheel --output-dir wheelhouse
```
To build manylinux, macOS, and Windows wheels on Travis CI and upload them to PyPI whenever you tag a version, you could use this `.travis.yml`:
Then setup a deployment method by following the [Travis CI deployment docs](https://docs.travis-ci.com/user/deployment/), or see [Delivering to PyPI](#delivering-to-pypi) below.
```yaml
language: python
- Create an `appveyor.yml` file in your repo.
jobs:
include:
# perform a linux build
- services: docker
# and a mac build
- os: osx
language: shell
# and a windows build
- os: windows
language: shell
before_install:
- choco install python --version 3.8.0
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
```
build_script:
- pip install cibuildwheel==0.8.0
- cibuildwheel --output-dir wheelhouse
artifacts:
- path: "wheelhouse\\*.whl"
name: Wheels
```
Appveyor will store the built wheels for you - you can access them from the project console. Alternatively, you may want to store them in the same place as the Travis CI build. See [Appveyor deployment docs](https://www.appveyor.com/docs/deployment/) for more info, or see [Delivering to PyPI](#delivering-to-pypi) below.
- Commit those files, enable building of your repo on Travis CI and Appveyor, and push.
env:
global:
- TWINE_USERNAME=__token__
# Note: TWINE_PASSWORD is set to a PyPI API token in Travis settings
All being well, you should get wheels delivered to you in a few minutes.
install:
- python3 -m pip install cibuildwheel==1.5.3
> ⚠️ Got an error? Check the [checklist](#it-didnt-work) below.
script:
# build the wheels, put them into './wheelhouse'
- python3 -m cibuildwheel --output-dir wheelhouse
### Configuration overview
`cibuildwheel` allows for easy customization of the various phases of the build process demonstrated above:
| | Option | |
|---|---|---|
| **Target wheels** | `CIBW_PLATFORM` | Override the auto-detected target platform |
| | `CIBW_SKIP` | Skip certain Python versions |
| **Build parameters** | `CIBW_BUILD_VERBOSITY` | Increase or decrease the output of `pip wheel` |
| **Build environment** | `CIBW_ENVIRONMENT` | Set environment variables needed during the build |
| | `CIBW_BEFORE_BUILD` | Execute a shell command preparing each wheel's build |
| | `CIBW_MANYLINUX1_X86_64_IMAGE` | Specify an alternative manylinx1 x86_64 docker image |
| | `CIBW_MANYLINUX1_I686_IMAGE` | Specify an alternative manylinux1 i686 docker image |
| **Tests** | `CIBW_TEST_COMMAND` | Execute a shell command to test all built wheels |
| | `CIBW_TEST_REQUIRES` | Install Python dependencies before running the tests |
A more detailed description of the options, the allowed values, and some examples can be found in the [Options](#options) section.
### Linux builds on Docker
Linux wheels are built in the [`manylinux1` docker images](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 513](https://www.python.org/dev/peps/pep-0513/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
- Progams and libraries cannot be installed on the Travis CI Ubuntu host with `apt-get`, but can be installed inside of the Docker image using `yum` or manually. The same goes for environment variables that are potentially needed to customize the wheel building. `cibuildwheel` supports this by providing the `CIBW_ENVIRONMENT` and `CIBW_BEFORE_BUILD` options to setup the build environment inside the running Docker image. See [below](#options) for details on these options.
- The project directory is mounted in the running Docker instance as `/project`, the output directory for the wheels as `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system.
- Alternative dockers images can be specified with the `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE` options to allow for a custom, preconfigured build environment for the Linux builds. See [below](#options) for more details.
after_success:
# if the release was tagged, upload them to PyPI
- |
if [[ $TRAVIS_TAG ]]; then
python3 -m pip install twine
python3 -m twine upload wheelhouse/*.whl
fi
```
For more information, including how to build on GitHub Actions, Appveyor, Azure Pipelines, or CircleCI, check out the [documentation](https://cibuildwheel.readthedocs.org) and the [examples](https://github.com/joerick/cibuildwheel/tree/master/examples).
Options
-------
```
usage: cibuildwheel [-h]
[--output-dir OUTPUT_DIR]
[--platform PLATFORM]
[project_dir]
Build wheels for all the platforms.
| | Option | Description |
|---|--------|-------------|
| **Build selection** | [`CIBW_PLATFORM`](https://cibuildwheel.readthedocs.io/en/stable/options/#platform) | Override the auto-detected target platform |
| | [`CIBW_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) <br> [`CIBW_SKIP`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) | Choose the Python versions to build |
| **Build customization** | [`CIBW_ENVIRONMENT`](https://cibuildwheel.readthedocs.io/en/stable/options/#environment) | Set environment variables needed during the build |
| | [`CIBW_BEFORE_ALL`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. |
| | [`CIBW_BEFORE_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build |
| | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each (non-pure Python) built wheel |
| | [`CIBW_MANYLINUX_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_I686_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PYPY_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_AARCH64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PPC64LE_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_S390X_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) | Specify alternative manylinux docker images |
| | [`CIBW_DEPENDENCY_VERSIONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#dependency-versions) | Specify how cibuildwheel controls the versions of the tools it uses |
| **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel |
| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute a shell command before testing each wheel |
| | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests |
| | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require |
| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel |
positional arguments:
project_dir Path to the project that you want wheels for.
Default: the current directory.
optional arguments:
-h, --help show this help message and exit
--platform {auto,linux,macos,windows}
Platform to build for. For "linux" you need docker
running, on Mac or Linux. For "macos", you need a Mac
machine, and note that this script is going to
automatically install MacPython on your system, so
don't run on your development machine. For "windows",
you need to run in Windows, and it will build and test
for all versions of Python at C:\PythonXX[-x64].
--output-dir OUTPUT_DIR
Destination folder for the wheels.
```
Most of the config is via environment variables. These go into `.travis.yml` and `appveyor.yml` nicely.
| Environment variable: `CIBW_PLATFORM` | Command line argument: `--platform`
| --- | ---
Options: `auto` `linux` `macos` `windows`
Default: `auto`
`auto` will auto-detect platform using environment variables, such as `TRAVIS_OS_NAME`/`APPVEYOR`.
For `linux` you need Docker running, on Mac or Linux. For `macos`, you need a Mac machine, and note that this script is going to automatically install MacPython on your system, so don't run on your development machine. For `windows`, you need to run in Windows, and it will build and test for all versions of Python at `C:\PythonXX[-x64]`.
| Environment variable: `CIBW_SKIP`
| ---
Optional.
Space-separated list of builds to skip. Each build has an identifier like `cp27-manylinux1_x86_64` or `cp34-macosx_10_6_intel` - you can list ones to skip here and `cibuildwheel` won't try to build them.
The format is `python_tag-platform_tag`. The tags are as defined in [PEP 0425](https://www.python.org/dev/peps/pep-0425/#details).
Python tags look like `cp27` `cp34` `cp35` `cp36`
Platform tags look like `macosx_10_6_intel` `manylinux1_x86_64` `manylinux1_i686` `win32` `win_amd64`
You can also use shell-style globbing syntax (as per `fnmatch`)
Examples:
- Skip building on Python 2.7 on the Mac: `cp27-macosx_10_6_intel`
- Skip building on Python 2.7 on all platforms: `cp27-*`
- Skip Python 2.7 on Windows: `cp27-win*`
- Skip Python 2.7 on 32bit Windows: `cp27-win32`
- Skip Python 3.4 and Python 3.5: `cp34-* cp35-*`
- Skip Python 3.6 on Linux: `cp36-manylinux*`
- Only build on Python 3.6: `cp27-* cp34-* cp35-*`
| Environment variable: `CIBW_BUILD_VERBOSITY`
| ---
Optional.
An number from 1 to 3 to increase the level of verbosity (corresponding to invoking pip with `-v`, `-vv`, and `-vvv`), between -1 and -3 (`-q`, `-qq`, and `-qqq`), or just 0 (default verbosity). These flags are useful while debugging a build when the output of the actual build invoked by `pip wheel` is required.
Platform-specific variants also available:
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX`
| Environment variable: `CIBW_ENVIRONMENT`
| ---
Optional.
A space-separated list of environment variables to set during the build. Bash syntax should be used (even on Windows!).
You must set this variable to pass variables to Linux builds (since they execute in a Docker container). It also works for the other platforms.
You can use `$PATH` syntax to insert other variables, or the `$(pwd)` syntax to insert the output of other shell commands.
Example: `CFLAGS="-g -Wall" CXXFLAGS="-Wall"`
Example: `PATH=$PATH:/usr/local/bin`
Example: `BUILD_TIME="$(date)"`
Example: `PIP_EXTRA_INDEX_URL="https://pypi.myorg.com/simple"`
Platform-specific variants also available:
`CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX`
In addition to the above, `cibuildwheel` always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](https://github.com/joerick/cibuildwheel/wiki/Building-packages-with-optional-C-extensions).
| Environment variable: `CIBW_BEFORE_BUILD`
| ---
Optional.
A shell command to run before building the wheel. This option allows you to run a command in **each** Python environment before the `pip wheel` command. This is useful if you need to set up some dependency so it's available during the build.
If dependencies are required to build your wheel (for example if you include a header from a Python module), set this to `{pip} install .`, and the dependencies will be installed automatically by pip. However, this means your package will be built twice - if your package takes a long time to build, you might wish to manually list the dependencies here instead.
The active Python binary can be accessed using `{python}`, and pip with `{pip}`. These are useful when you need to write `python3` or `pip3` on a Python 3.x build. `{project}` can be used as a placeholder for the absolute path to the project's root.
Example: `{pip} install .`
Example: `{pip} install pybind11`
Example: `yum install -y libffi-dev && {pip} install .`
Platform-specific variants also available:
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX`
| Environment variables: `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE`
| ---
Optional.
An alternative docker image to be used for building [`manylinux1`](https://github.com/pypa/manylinux) wheels. `cibuildwheel` will then pull these instead of the official images, [`quay.io/pypa/manylinux1_x86_64`](https://quay.io/pypa/manylinux1_i686) and [`quay.io/pypa/manylinux1_i686`](https://quay.io/pypa/manylinux1_i686).
Beware to specify a valid docker image that can be used the same as the official, default docker images: all necessary Python and pip versions need to be present in `/opt/python/`, and the `auditwheel` tool needs to be present for `cibuildwheel` to work. Apart from that, the architecture and relevant shared system libraries need to be manylinux1-compatible in order to produce valid `manylinux1` wheels (see https://github.com/pypa/manylinux and [PEP 513](https://www.python.org/dev/peps/pep-0513/) for more details).
Example: `dockcross/manylinux-x64`
Example: `dockcross/manylinux-x86`
| Environment variable: `CIBW_TEST_COMMAND`
| ---
Optional.
Shell command to run tests after the build. The wheel will be installed automatically and available for import from the tests. Just like in the `CIBW_BEFORE_BUILD` option, `{python}`, `{pip}`, and `{project}` will respectively be replaced by the Python executable, the pip executable, and the absolute project directory.
Example: `nosetests {project}/tests`
| Environment variable: `CIBW_TEST_REQUIRES`
| ---
Optional.
Space-separated list of dependencies required for running the tests.
Example: `pytest`
Example: `nose==1.3.7 moto==0.4.31`
--
#### Example YML syntax
<table>
<tr><td><i>example .travis.yml environment variables</i><pre><code>env:
global:
- CIBW_TEST_REQUIRES=nose
- CIBW_TEST_COMMAND="nosetests {project}/tests"
</code></pre></td>
<td><i>example appveyor.yml environment variables</i><pre><code>environment:
global:
CIBW_TEST_REQUIRES: nose
CIBW_TEST_COMMAND: "nosetests {project}\\tests"
</code></pre></td>
</tr></table>
Delivering to PyPI
------------------
After you've built your wheels, you'll probably want to deliver them to PyPI.
### Manual method
On your development machine, do the following...
```bash
# Clear out your 'dist' folder.
rm -rf dist
# Make a source distribution
python setup.py sdist
# 🏃🏻
# Go and download your wheel files from wherever you put them. Put
# them all into the 'dist' folder.
# Upload using 'twine' (you may need to 'pip install twine')
twine upload dist/*
```
### Semi-automatic method using wheelhouse-uploader
Obviously, manual steps are for chumps, so we can automate this a little by using [wheelhouse-uploader](https://github.com/ogrisel/wheelhouse-uploader).
> Quick note from me - using S3 as a storage didn't work due to a [bug](https://issues.apache.org/jira/browse/LIBCLOUD-792) in libcloud. Feel free to use my fork of that package that fixes the bug `pip install https://github.com/joerick/libcloud/archive/v1.5.0-s3fix.zip`
### Automatic method
If you don't need much control over the release of a package, you can set up cibuildwheel to deliver the wheels straight to PyPI. This doesn't require any cloud storage to work - you just need to bump the version and tag it.
Check out [this example repo](https://github.com/joerick/cibuildwheel-autopypi-example) for instructions on how to set this up.
It didn't work!
---------------
If your wheel didn't compile, check the list below for some debugging tips.
- A mistake in your config. To quickly test your config without doing a git push and waiting for your code to build on CI, you can run the Linux build in a Docker container. On Mac or Linux, with Docker running, try `cibuildwheel --platform linux`. You'll have to bring your config into the current environment first.
- Missing dependency. You might need to install something on the build machine. You can do this in `.travis.yml` or `appveyor.yml`, with apt-get, brew or whatever Windows uses :P . Given how the Linux build works, we'll probably have to build something into `cibuildwheel`. Let's chat about that over in the issues!
- Windows: missing C feature. The Windows C compiler doesn't support C language features invented after 1990, so you'll have to backport your C code to C90. For me, this mostly involved putting my variable declarations at the top of the function like an animal.
Working examples
----------------
Here are some repos that use cibuildwheel.
Here are some repos that use cibuildwheel.
- [pyinstrument_cext](https://github.com/joerick/pyinstrument_cext)
- [websockets](https://github.com/aaugustin/websockets)
- [Parselmouth](https://github.com/YannickJadoul/Parselmouth)
- [python-admesh](https://github.com/admesh/python-admesh)
- [pybase64](https://github.com/mayeut/pybase64)
- [KDEpy](https://github.com/tommyod/KDEpy)
- [AutoPy](https://github.com/autopilot-rs/autopy)
- [apriltags2-ethz](https://github.com/safijari/apriltags2_ethz)
- [TgCrypto](https://github.com/pyrogram/tgcrypto)
- [Twisted](https://github.com/twisted/twisted)
- [gmic-py](https://github.com/dtschump/gmic-py)
- [creme](https://github.com/creme-ml/creme)
- [PyAV](https://github.com/PyAV-Org/PyAV)
- [aiortc](https://github.com/aiortc/aiortc)
- [aioquic](https://github.com/aiortc/aioquic)
- [pikepdf](https://github.com/pikepdf/pikepdf)
> Add repo here! Send a PR.
> Add your repo here! Send a PR.
Legal note
----------
Since `cibuildwheel` runs the wheel through delocate or auditwheel, it will automatically bundle library dependencies. This is similar to static linking, so it might have some licence implications. Check the license for any code you're pulling in to make sure that's allowed.
Since `cibuildwheel` repairs the wheel with `delocate` or `auditwheel`, it might automatically bundle dynamically linked libraries from the build machine.
It helps ensure that the library can run without any dependencies outside of the pip toolchain.
This is similar to static linking, so it might have some licence implications. Check the license for any code you're pulling in to make sure that's allowed.
Changelog
=========
### 1.5.3
_19 July 2020_
- 🛠 Update CPython 3.8 to 3.8.3 (#405)
- 🛠 Internal refactoring of Linux build, to move control flow into Python (#386)
### 1.5.2
_8 July 2020_
- 🐛 Fix an issue on Windows where pyproject.toml would cause an error when
some requirements formats were used. (#401)
- 🛠 Update CPython 3.7 to 3.7.8 (#394)
### 1.5.1
_25 June 2020_
- 🐛 Fix "OSError: [WinError 17] The system cannot move the file to a different
disk drive" on Github Actions (#388, #389)
### 1.5.0
_24 June 2020_
- 🌟 Add [`CIBW_BEFORE_ALL`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-all)
option, which lets you run a command on the build machine before any wheels
are built. This is especially useful when building on Linux, to `make`
something external to Python, or to `yum install` a dependency. (#342)
- ✨ Added support for projects using pyproject.toml instead of setup.py
(#360, #358)
- ✨ Added workaround to allow Python 3.5 on Windows to pull dependencies from
pyproject.toml. (#358)
- 📚 Improved Github Actions examples and docs (#354, #362)
- 🐛 Ensure pip wheel uses the specified package, and doesn't build a wheel
from PyPI (#369)
- 🛠 Internal changes: using pathlib.Path, precommit hooks, testing
improvements.
### 1.4.2
_25 May 2020_
- 🛠 Dependency updates, including CPython 3.8.3 & manylinux images.
- 🛠 Lots of internal updates - type annotations and checking using mypy, and
a new integration testing system.
- ⚠️ Removed support for *running* cibuildwheel using Python 3.5. cibuildwheel
will continue to build Python 3.5 wheels until EOL.
### 1.4.1
_4 May 2020_
- 🐛 Fix a bug causing programs running inside the i686 manylinux images to
think they were running x86_64 and target the wrong architecture. (#336,
#338)
### 1.4.0
_2 May 2020_
- 🌟 Deterministic builds. cibuildwheel now locks the versions of the tools it
uses. This means that pinning your version of cibuildwheel pins the versions
of pip, setuptools, manylinux etc. that are used under the hood. This should
make things more reliable. But note that we don't control the entire build
environment on macOS and Windows, where the version of Xcode and Visual
Studio can still effect things.
This can be controlled using the [CIBW_DEPENDENCY_VERSIONS](https://cibuildwheel.readthedocs.io/en/stable/options/#dependency-versions)
and [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image)
options - if you always want to use the latest toolchain, you can still do
that, or you can specify your own pip constraints file and manylinux image.
(#256)
- ✨ Added `package_dir` command line option, meaning we now support building
a package that lives in a subdirectory and pulls in files from the wider
project. See [the `package_dir` option help](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line-options)
for more information.
Note that this change makes the working directory (where you call
cibuildwheel from) relevant on Linux, as it's considered the 'project' and
will be copied into the Docker container. If your builds are slower on this
version, that's likely the reason. `cd` to your project and then call
`cibuildwheel` from there. (#319, #295)
- 🛠 On macOS, we make `MACOSX_DEPLOYMENT_TARGET` default to `10.9` if it's
not set. This should make things more consistent between Python versions.
- 🛠 Dependency updates - CPython 3.7.7, CPython 2.7.18, Pypy 7.3.1.
### 1.3.0
_12 March 2020_
- 🌟 Add support for building on Github Actions! Check out the
[docs](https://cibuildwheel.readthedocs.io/en/stable/setup/#github-actions)
for information on how to set it up. (#194)
- ✨ Add the `CIBW_BEFORE_TEST` option, which lets you run a command to
prepare the environment before your tests are run. (#242)
### 1.2.0
_8 March 2020_
- 🌟 Add support for building PyPy wheels, across Manylinux, macOS, and
Windows. (#185)
- 🌟 Added the ability to build ARM64 (aarch64), ppc64le, and s390x wheels,
using manylinux2014 and Travis CI. (#273)
- ✨ You can now build macOS wheels on Appveyor. (#230)
- 🛠 Changed default macOS minimum target to 10.9, from 10.6. This allows the
use of more modern C++ libraries, among other things. (#156)
- 🛠 Stop building universal binaries on macOS. We now only build x86_64
wheels on macOS. (#220)
- ✨ Allow chaining of commands using `&&` and `||` on Windows inside
CIBW_BEFORE_BUILD and CIBW_TEST_COMMAND. (#293)
- 🛠 Improved error reporting for failed Cython builds due to stale .so files
(#263)
- 🛠 Update CPython from 3.7.5 to 3.7.6 and from 3.8.0 to 3.8.2 on Mac/Windows
- 🛠 Improved error messages when a bad config breaks cibuildwheel's PATH
variable. (#264)
- ⚠️ Removed support for *running* cibuildwheel on Python 2.7. cibuildwheel
will continue to build Python 2.7 wheels for a little while. (#265)
### 1.1.0
_7 December 2019_
- 🌟 Add support for building manylinux2014 wheels. To use, set
`CIBW_MANYLINUX_X86_64_IMAGE` and CIBW_MANYLINUX_I686_IMAGE to
`manylinux2014`.
- ✨ Add support for [Linux on Appveyor](https://www.appveyor.com/blog/2018/03/06/appveyor-for-linux/) (#204, #207)
- ✨ Add `CIBW_REPAIR_WHEEL_COMMAND` env variable, for changing how
`auditwheel` or `delocate` are invoked, or testing an equivalent on
Windows. (#211)
- 📚 Added some travis example configs - these are available in /examples. (#228)
### 1.0.0
_10 November 2019_
- 🌟 Add support for building Python 3.8 wheels! (#180)
- 🌟 Add support for building manylinux2010 wheels. cibuildwheel will now
build using the manylinux2010 images by default. If your project is still
manylinux1 compatible, you should get both manylinux1 and manylinux2010
wheels - you can upload both to PyPI. If you always require manylinux1 wheels, you can
build using the old manylinux1 image using the [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) option.
(#155)
- 📚 Documentation is now on its [own mini-site](https://cibuildwheel.readthedocs.io),
rather than on the README (#169)
- ✨ Add support for building Windows wheels on Travis CI. (#160)
- 🛠 If you set `CIBW_TEST_COMMAND`, your tests now run in a virtualenv. (#164)
- 🛠 Windows now uses Python as installed by nuget, rather than the versions
installed by the various CI providers. (#180)
- 🛠 Update Python from 2.7.16 to 2.7.17 and 3.7.4 to 3.7.5 on macOS (#171)
- ⚠️ Removed support for Python 3.4 (#168)
### 0.12.0
_29 September 2019_
- ✨ Add CIBW_TEST_EXTRAS option, to allow testing using extra_require
options. For example, set `CIBW_TEST_EXTRAS=test,qt` to make the wheel
installed with `pip install <wheel_file>[test,qt]`
- 🛠 Update Python from 3.7.2 to 3.7.4 on macOS
- 🛠 Update OpenSSL patch to 1.0.2t on macOS
### 0.11.1
_28 May 2019_
- 🐛 Fix missing file in the release tarball, that was causing problems with
Windows builds (#141)
### 0.11.0
_26 May 2019_
- 🌟 Add support for building on Azure pipelines! This lets you build all
Linux, Mac and Windows wheels on one service, so it promises to be the
easiest to set up! Check out the quickstart in the docs, or
[cibuildwheel-azure-example](https://github.com/joerick/cibuildwheel-azure-example)
for an example project. (#126, #132)
- 🛠 Internal change - the end-to-end test projects format was updated, so we
can more precisely assert what should be produced for each one. (#136, #137).
### 0.10.2
_10 March 2019_
- 🛠 Revert temporary fix in macOS, that was working around a bug in pip 19 (#129)
- 🛠 Update Python to 2.7.16 on macOS
- 🛠 Update OpenSSL patch to 1.0.2r on macOS
### 0.10.1
_3 February 2019_
- 🐛 Fix build stalling on macOS (that was introduced in pip 19) (#122)
- 🐛 Fix "AttributeError: 'Popen' object has no attribute 'args'" on Python 2.7 for Linux builds (#108)
- 🛠 Update Python from 3.6.7, 3.7.1 to 3.6.8, 3.7.2 on macOS
- 🛠 Update openssl patch from 1.0.2p to 1.0.2q on macOS
- 🛠 Sorting build options dict items when printing preamble (#114)
### 0.10.0
_23 September 2018_
- 🌟 Add `CIBW_BUILD` option, for specifying which specific builds to perform (#101)
- 🌟 Add support for building Mac and Linux on CircleCI (#91, #97)
- 🛠 Improved support for building universal wheels (#95)
- 🛠 Ensure log output is unbuffered and therefore in the correct order (#92)
- 🛠 Improved error reporting for errors that occur inside a package's setup.py (#88)
- ⚠️ Removed support for Python 3.3 on Windows.
### 0.9.4
_29 July 2018_
- 🛠 CIBW_TEST_COMMAND now runs in a shell on Mac (as well as Linux) (#81)
### 0.9.3
_10 July 2018_
- 🛠 Update to Python 3.6.6 on macOS (#82)
- ✨ Add support for building Python 3.7 wheels on Windows (#76)
- ⚠️ Deprecated support for Python 3.3 on Windows.
### 0.9.2
_1 July 2018_
- 🛠 Update Python 3.7.0rc1 to 3.7.0 on macOS (#79)
### 0.9.1
_18 June 2018_
- 🛠 Removed the need to use `{python}` and `{pip}` in `CIBW_BEFORE_BUILD` statements, by ensuring the correct version is always on the path at `python` and `pip` instead. (#60)
- 🛠 We now patch the _ssl module on Python 3.4 and 3.5 so these versions can still make SSL web requests using TLS 1.2 while building. (#71)
### 0.9.0
_18 June 2018_
- ✨ Add support for Python 3.7 (#73)
### 0.8.0
_4 May 2018_
- ⚠️ Drop support for Python 3.3 on Linux (#67)
- 🐛 Fix TLS by updating setuptools (#69)
### 0.7.1
- macOS: Fix Pip bugs resulting from PyPI TLS 1.2 enforcement
- macOS: Fix brew Python3 version problems in the CI
_2 April 2017_
- 🐛 macOS: Fix Pip bugs resulting from PyPI TLS 1.2 enforcement
- 🐛 macOS: Fix brew Python3 version problems in the CI
### 0.7.0
- You can now specify a custom docker image using the `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE` options. (#46)
- Fixed a bug where cibuildwheel would download and build a package from PyPI(!) instead of building the package on the local machine. (#51)
_7 January 2018_
- ✨ You can now specify a custom docker image using the `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE` options. (#46)
- 🐛 Fixed a bug where cibuildwheel would download and build a package from PyPI(!) instead of building the package on the local machine. (#51)
### 0.6.0
- On the Linux build, the host filesystem is now accessible via `/host` (#36)
- Fixed a bug where setup.py scripts would run the wrong version of Python when running subprocesses on Linux (#35)
_9 October 2017_
- ✨ On the Linux build, the host filesystem is now accessible via `/host` (#36)
- 🐛 Fixed a bug where setup.py scripts would run the wrong version of Python when running subprocesses on Linux (#35)
### 0.5.1
- Fixed a couple of bugs on Python 3.
- Added experimental support for Mac builds on [Bitrise.io](https://www.bitrise.io)
_10 September 2017_
- 🐛 Fixed a couple of bugs on Python 3.
- ✨ Added experimental support for Mac builds on [Bitrise.io](https://www.bitrise.io)
### 0.5.0
- `CIBW_ENVIRONMENT` added. You can now set environment variables for each build, even within the Docker container on Linux. This is a big one! (#21)
- `CIBW_BEFORE_BUILD` now runs in a system shell on all platforms. You can now do things like `CIBW_BEFORE_BUILD="cmd1 && cmd2"`. (#32)
_7 September 2017_
-`CIBW_ENVIRONMENT` added. You can now set environment variables for each build, even within the Docker container on Linux. This is a big one! (#21)
-`CIBW_BEFORE_BUILD` now runs in a system shell on all platforms. You can now do things like `CIBW_BEFORE_BUILD="cmd1 && cmd2"`. (#32)
### 0.4.1
- Fixed a bug on Windows where subprocess' output was hidden (#23)
- Fixed a bug on Appveyor where logs would appear in the wrong order due to output buffering (#24, thanks @YannickJadoul!)
_14 August 2017_
- 🐛 Fixed a bug on Windows where subprocess' output was hidden (#23)
- 🐛 Fixed a bug on AppVeyor where logs would appear in the wrong order due to output buffering (#24, thanks @YannickJadoul!)
### 0.4.0
- Fixed a bug that was increasing the build time by building the wheel twice. This was a problem for large projects that have a long build time. If you're upgrading and you need the old behaviour, use `CIBW_BEFORE_BUILD={pip} install .`, or install exactly the dependencies you need in `CIBW_BEFORE_BUILD`. See #18.
_23 July 2017_
- 🐛 Fixed a bug that was increasing the build time by building the wheel twice. This was a problem for large projects that have a long build time. If you're upgrading and you need the old behaviour, use `CIBW_BEFORE_BUILD={pip} install .`, or install exactly the dependencies you need in `CIBW_BEFORE_BUILD`. See #18.
### 0.3.0
- Removed Python 2.6 support on Linux (#12)
_27 June 2017_
- ⚠️ Removed Python 2.6 support on Linux (#12)
### 0.2.1
11 June 2017
_11 June 2017_
- Changed the build process to install the package before building the wheel - this allows direct dependencies to be installed first (#9, thanks @tgarc!)
- Added Python 3 support for the main process, for systems where Python 3 is the default (#8, thanks @tgarc).
- 🛠 Changed the build process to install the package before building the wheel - this allows direct dependencies to be installed first (#9, thanks @tgarc!)
- Added Python 3 support for the main process, for systems where Python 3 is the default (#8, thanks @tgarc).
### 0.2.0
13 April 2017
_13 April 2017_
- Added `CIBW_SKIP` option, letting users explicitly skip a build
- Added `CIBW_BEFORE_BUILD` option, letting users run a shell command before the build starts
- Added `CIBW_SKIP` option, letting users explicitly skip a build
- Added `CIBW_BEFORE_BUILD` option, letting users run a shell command before the build starts
### 0.1.3
31 March 2017
_31 March 2017_
- First public release!
- 🌟 First public release!
Contributing
============
Wheel-building is pretty complex. I expect users to find many edge-cases - please help the rest of the community out by documenting these, adding features to support them, and reporting bugs.
I plan to be pretty liberal in accepting pull requests, as long as they align with the design goals below.
`cibuildwheel` is indie open source. I'm not paid to work on this.
Design Goals
------------
- `cibuildwheel` should wrap the complexity of wheel building.
- The user interface to `cibuildwheel` is the build script (e.g. `.travis.yml`). Feature additions should not increase the complexity of this script.
- Options should be environment variables (these lend themselves better to YML config files). They should be prefixed with `CIBW_`.
- Options should be generalise to all platforms. If platform-specific options are required, they should be namespaced e.g. `CIBW_TEST_COMMAND_MACOS`
Other notes:
- The platforms are very similar, until they're not. I'd rather have straight-forward code than totally DRY code, so let's keep airy platfrom abstractions to a minimum.
- I might want to break the options into a shared config file one day, so that config is more easily shared. That has motivated some of the design decisions.
For more info on how to contribute to cibuildwheel, see the [docs](https://cibuildwheel.readthedocs.io/en/latest/contributing/).
Maintainers
-----------
- Joe Rickerby [@joerick](https://github.com/joerick)
- Tomas Garcia [@tgarc](https://github.com/tgarc)
- Yannick Jadoul [@YannickJadoul](https://github.com/YannickJadoul)
- Matthieu Darbois [@mayeut](https://github.com/mayeut)
Credits
-------
`cibuildwheel` stands on the shoulders of giants. Massive props to-
`cibuildwheel` stands on the shoulders of giants.
- ⭐️ @matthew-brett for [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild) and [matthew-brett/delocate](http://github.com/matthew-brett/delocate)
- @PyPA for the manylinux Docker images [pypa/manylinux](https://github.com/pypa/manylinux)
- @ogrisel for [wheelhouse-uploader](https://github.com/ogrisel/wheelhouse-uploader) and `run_with_env.cmd`
Massive props also to-
- @zfrenchee for [help debugging many issues](https://github.com/joerick/cibuildwheel/issues/2)
- @lelit for some great bug reports and [contributions](https://github.com/joerick/cibuildwheel/pull/73)
- @mayeut for a [phenomenal PR](https://github.com/joerick/cibuildwheel/pull/71) patching Python itself for better compatibility!
See also
--------
========
If you'd like to keep wheel building separate from the package itself, check out [astrofrog/autowheel](https://github.com/astrofrog/autowheel). It builds packages using cibuildwheel from source distributions on PyPI.
If `cibuildwheel` is too limited for your needs, consider [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild). `multibuild` is a toolbox for building a wheel on various platforms. It can do a lot more than this project - it's used to build SciPy!
+39 -7
View File
@@ -1,10 +1,42 @@
environment:
# workaround an appveyor bug on macos
# see https://github.com/appveyor/ci/issues/3376#issuecomment-611314299
APPVEYOR_CONSOLE_DISABLE_PTY: true
matrix:
- PYTHON: "C:\\Python27\\python.exe"
- PYTHON: "C:\\Python35\\python.exe"
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu
APPVEYOR_JOB_NAME: "python37-x64-ubuntu"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
APPVEYOR_JOB_NAME: "python37-x64-vs2015"
- APPVEYOR_BUILD_WORKER_IMAGE: macos-mojave
APPVEYOR_JOB_NAME: "python37-x64-macos-mojave"
build_script:
- "%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"
# while pypy libffi dependency is failing the build, allow failures on macos
matrix:
allow_failures:
- APPVEYOR_BUILD_WORKER_IMAGE: macos-mojave
stack: python 3.7
build: off
init:
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
- ps: |
$BRANCH = if ($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH) { $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH } else { $env:APPVEYOR_REPO_BRANCH }
if (-not ($BRANCH -eq 'master' -or $BRANCH.ToLower().StartsWith('appveyor-'))) {
$env:PYTEST_ADDOPTS='-k "unit_test or _basic" --suppress-no-test-exit-code'
}
install: python -m pip install -r requirements-dev.txt pytest-custom-exit-code
# the '-u' flag is required so the output is in the correct order.
# See https://github.com/joerick/cibuildwheel/pull/24 for more info.
test_script: python -u ./bin/run_tests.py
branches:
only:
- master
skip_commits:
files:
- docs/*
+44
View File
@@ -0,0 +1,44 @@
jobs:
- job: linux_38
pool: {vmImage: 'Ubuntu-18.04'}
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.8'
- bash: |
python -m pip install -r requirements-dev.txt pytest-azurepipelines
python ./bin/run_tests.py
- job: macos_38
pool: {vmImage: 'macOS-10.15'}
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.8'
- bash: |
python -m pip install -r requirements-dev.txt pytest-azurepipelines
python ./bin/run_tests.py
- 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 pytest-azurepipelines
python ./bin/run_tests.py
- job: windows_38
pool: {vmImage: 'vs2017-win2016'}
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.8'
- script: choco install vcpython27 -f -y
displayName: Install Visual C++ for Python 2.7
- bash: |
python -m pip install -r requirements-dev.txt pytest-azurepipelines
python ./bin/run_tests.py
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/env python3
import click
from pathlib import Path
import os
import cibuildwheel
from packaging.version import Version, InvalidVersion
import subprocess
import glob
config = [
# file path, version find/replace format
('cibuildwheel/__init__.py', "__version__ = '{}'"),
('setup.py', "version='{}'"),
('README.md', "cibuildwheel=={}"),
('examples/*', "cibuildwheel=={}"),
]
@click.command()
def bump_version():
git_changes_result = subprocess.run(['git diff-index --quiet HEAD --'], shell=True)
repo_has_uncommitted_changes = git_changes_result.returncode != 0
if repo_has_uncommitted_changes:
print('error: Uncommitted changes detected.')
exit(1)
current_version = cibuildwheel.__version__
print( 'Current version:', current_version) # noqa
new_version = input(' New version: ').strip()
try:
Version(new_version)
except InvalidVersion:
print("error: This version doesn't conform to PEP440")
print(' https://www.python.org/dev/peps/pep-0440/')
exit(1)
actions = []
for path_pattern, version_pattern in config:
paths = [Path(p) for p in glob.glob(path_pattern)]
if not paths:
print(f'error: Pattern {path_pattern} didnt match any files')
exit(1)
find_pattern = version_pattern.format(current_version)
replace_pattern = version_pattern.format(new_version)
found_at_least_one_file_needing_update = False
for path in paths:
contents = path.read_text(encoding='utf8')
if find_pattern in contents:
found_at_least_one_file_needing_update = True
actions.append(
(path, find_pattern, replace_pattern)
)
if not found_at_least_one_file_needing_update:
print('error: Didnt find any occurences of “{}” in “{}'.format(find_pattern, path_pattern))
exit(1)
print()
print("Here's the plan:")
print()
for action in actions:
print('{} {red}{}{off}{green}{}{off}'.format(
*action,
red="\u001b[31m", green="\u001b[32m", off="\u001b[0m"
))
print('Then commit, and tag as v{}'.format(new_version))
answer = input('Proceed? [y/N] ').strip()
if answer != 'y':
print('Aborted')
exit(1)
for path, find, replace in actions:
contents = path.read_text(encoding='utf8')
contents = contents.replace(find, replace)
path.write_text(contents, encoding='utf8')
print('Files updated. If you want to update the changelog as part of this')
print('commit, do that now.')
while input('Type "done" to continue: ').strip().lower() != 'done':
pass
subprocess.run([
'git', 'commit',
'-a',
'-m', f'Bump version: v{new_version}'
], check=True)
subprocess.run([
'git', 'tag',
'-a',
'-m', f'v{new_version}',
f'v{new_version}'
], check=True)
print('Done.')
if __name__ == '__main__':
os.chdir(os.path.dirname(__file__))
os.chdir('..')
bump_version()
+1 -4
View File
@@ -1,6 +1,3 @@
#!/bin/bash
cd "$(dirname "$0")"
cd ..
CIBW_PLATFORM=linux ./bin/run_test.py $1
CIBW_PLATFORM=linux pytest "$@"
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
import os
import time
from pathlib import Path
from subprocess import run
import click
import textwrap
def shell(cmd, **kwargs):
return run([cmd], shell=True, **kwargs)
def git_repo_has_changes():
unstaged_changes = shell('git diff-index --quiet HEAD --').returncode != 0
staged_changes = shell('git diff-index --quiet --cached HEAD --').returncode != 0
return unstaged_changes or staged_changes
@click.command()
def main():
project_root = Path(__file__).parent / '..'
os.chdir(project_root)
if git_repo_has_changes():
print('Your git repo has uncommitted changes. Commit or stash before continuing.')
exit(1)
previous_branch = shell('git rev-parse --abbrev-ref HEAD',
check=True,
capture_output=True,
encoding='utf8').stdout.strip()
shell('git fetch origin', check=True)
timestamp = time.strftime('%Y-%m-%dT%H-%M-%S', time.gmtime())
branch_name = f'update-constraints-{timestamp}'
shell(f'git checkout -b {branch_name} origin/master', check=True)
try:
shell('bin/update_dependencies.py', check=True)
if not git_repo_has_changes():
print('Done: no constraint updates required.')
return
shell('git commit -a -m "Update dependencies"', check=True)
run(
[
'gh', 'pr', 'create',
'--repo', 'joerick/cibuildwheel',
'--base', 'master',
'--title', 'Update dependencies',
'--body', textwrap.dedent(f'''
Update the versions of our dependencies.
PR generated by `{os.path.basename(__file__)}`.
''')
],
check=True
)
print('Done.')
finally:
# remove any local changes
shell('git checkout -- .')
shell(f'git checkout {previous_branch}', check=True)
shell(f'git branch -D --force {branch_name}', check=True)
if __name__ == '__main__':
main.main(standalone_mode=True)
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/python
from __future__ import print_function
import os, sys, subprocess, shutil, json
from glob import glob
def single_run(test_project):
# load project settings into environment
env_file = os.path.join(test_project, 'environment.json')
project_env = {}
if os.path.exists(env_file):
with open(env_file) as f:
project_env = json.load(f)
# run the build
env = os.environ.copy()
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([sys.executable, '-m', 'cibuildwheel', test_project], env=env)
wheels = glob('wheelhouse/*.whl')
print('%s built successfully. %i wheels built.' % (test_project, len(wheels)))
# check some wheels were actually built
assert len(wheels) >= 4
# clean up
shutil.rmtree('wheelhouse')
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("test_project_dir")
args = parser.parse_args()
project_path = os.path.abspath(args.test_project_dir)
if not os.path.exists(project_path):
print('No test project not found.', file=sys.stderr)
exit(2)
single_run(project_path)
print('Project built successfully.')
+14 -23
View File
@@ -1,29 +1,20 @@
#!/usr/bin/python
#!/usr/bin/env python3
from __future__ import print_function
import os, sys, subprocess, shutil, json
from glob import glob
import os
import subprocess
import sys
from pathlib import Path
if __name__ == '__main__':
# move cwd to the project root
os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
os.chdir(Path(__file__).resolve().parents[1])
### run the unit tests
# run the unit tests
unit_test_args = [sys.executable, '-m', 'pytest', 'unit_test']
# run the docker unit tests only on Linux
if sys.platform.startswith('linux'):
unit_test_args += ['--run-docker']
subprocess.check_call(unit_test_args)
subprocess.check_call([sys.executable, '-m', 'pytest', 'unit_test'])
### run the integration tests
test_projects = glob('test/??_*')
if len(test_projects) == 0:
print('No test projects found. Aborting.', file=sys.stderr)
exit(2)
print('Testing projects:', test_projects)
run_test_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'run_test.py')
for project_path in test_projects:
subprocess.check_call([sys.executable, run_test_path, project_path])
print('%d projects built successfully.' % len(test_projects))
# run the integration tests
subprocess.check_call([sys.executable, '-m', 'pytest', '-x', '--durations', '0', 'test'])
+99
View File
@@ -0,0 +1,99 @@
#!/usr/bin/env python3
import configparser
import os
import subprocess
from collections import namedtuple
import requests
os.chdir(os.path.dirname(__file__))
os.chdir('..')
# CUSTOM_COMPILE_COMMAND is a pip-compile option that tells users how to
# regenerate the constraints files
os.environ['CUSTOM_COMPILE_COMMAND'] = "bin/update_constraints.py"
subprocess.check_call([
'pip-compile',
'--allow-unsafe',
'--upgrade',
'cibuildwheel/resources/constraints.in',
])
for python_version in ['27', '35', '36']:
subprocess.check_call([
f'./env{python_version}/bin/pip-compile',
'--allow-unsafe',
'--upgrade',
'cibuildwheel/resources/constraints.in',
'--output-file', f'cibuildwheel/resources/constraints-python{python_version}.txt'
])
Image = namedtuple('Image', [
'manylinux_version',
'platform',
'image_name',
])
images = [
Image('manylinux1', 'x86_64', 'quay.io/pypa/manylinux1_x86_64'),
Image('manylinux1', 'i686', 'quay.io/pypa/manylinux1_i686'),
Image('manylinux2010', 'x86_64', 'quay.io/pypa/manylinux2010_x86_64'),
Image('manylinux2010', 'i686', 'quay.io/pypa/manylinux2010_i686'),
Image('manylinux2010', 'pypy_x86_64', 'pypywheels/manylinux2010-pypy_x86_64'),
Image('manylinux2014', 'x86_64', 'quay.io/pypa/manylinux2014_x86_64'),
Image('manylinux2014', 'i686', 'quay.io/pypa/manylinux2014_i686'),
Image('manylinux2014', 'aarch64', 'quay.io/pypa/manylinux2014_aarch64'),
Image('manylinux2014', 'ppc64le', 'quay.io/pypa/manylinux2014_ppc64le'),
Image('manylinux2014', 's390x', 'quay.io/pypa/manylinux2014_s390x'),
]
config = configparser.ConfigParser()
for image in images:
# get the tag name whose digest matches 'latest'
if image.image_name.startswith('quay.io/'):
_, _, repository_name = image.image_name.partition('/')
response = requests.get(
f'https://quay.io/api/v1/repository/{repository_name}?includeTags=true'
)
response.raise_for_status()
repo_info = response.json()
tags_dict = repo_info['tags']
latest_tag = tags_dict.pop('latest')
# find the tag whose manifest matches 'latest'
tag_name = next(
name
for (name, info) in tags_dict.items()
if info['manifest_digest'] == latest_tag['manifest_digest']
)
else:
response = requests.get(
f'https://hub.docker.com/v2/repositories/{image.image_name}/tags'
)
response.raise_for_status()
tags = response.json()['results']
latest_tag = next(
tag for tag in tags if tag['name'] == 'latest'
)
# i don't know what it would mean to have multiple images per tag
assert len(latest_tag['images']) == 1
digest = latest_tag['images'][0]['digest']
pinned_tag = next(
tag
for tag in tags
if tag != latest_tag and tag['images'][0]['digest'] == digest
)
tag_name = pinned_tag['name']
if not config.has_section(image.platform):
config[image.platform] = {}
config[image.platform][image.manylinux_version] = f'{image.image_name}:{tag_name}'
with open('cibuildwheel/resources/pinned_docker_images.cfg', 'w') as f:
config.write(f)
+1 -1
View File
@@ -1 +1 @@
__version__ = '0.8.0'
__version__ = '1.5.3'
+235 -93
View File
@@ -1,12 +1,35 @@
from __future__ import print_function
import argparse, os, subprocess, sys, textwrap
import argparse
import os
import sys
import textwrap
import traceback
from configparser import ConfigParser
from pathlib import Path
from typing import Any, Dict, List, Optional, overload
import cibuildwheel
import cibuildwheel.linux, cibuildwheel.windows, cibuildwheel.macos
from cibuildwheel.environment import parse_environment, EnvironmentParseError
from cibuildwheel.util import BuildSkipper
import cibuildwheel.linux
import cibuildwheel.macos
import cibuildwheel.windows
from cibuildwheel.environment import (
EnvironmentParseError,
parse_environment,
)
from cibuildwheel.util import (
BuildOptions,
BuildSelector,
DependencyConstraints,
Unbuffered,
resources_dir,
)
def get_option_from_environment(option_name, platform=None):
@overload
def get_option_from_environment(option_name: str, platform: Optional[str], default: str) -> str: ... # noqa: E704
@overload
def get_option_from_environment(option_name: str, platform: Optional[str] = None, default: None = None) -> Optional[str]: ... # noqa: E704 E302
def get_option_from_environment(option_name: str, platform: Optional[str] = None, default: Optional[str] = None) -> Optional[str]: # noqa: E302
'''
Returns an option from the environment, optionally scoped by the platform.
@@ -17,145 +40,231 @@ def get_option_from_environment(option_name, platform=None):
CIBW_COLOR.
'''
if platform:
option = os.environ.get('%s_%s' % (option_name, platform.upper()))
option = os.environ.get(f'{option_name}_{platform.upper()}')
if option is not None:
return option
return os.environ.get(option_name)
return os.environ.get(option_name, default)
def main():
def strtobool(val: str) -> bool:
if val.lower() in ('y', 'yes', 't', 'true', 'on', '1'):
return True
return False
def main() -> None:
parser = argparse.ArgumentParser(
description='Build wheels for all the platforms.',
epilog=('Most options are supplied via environment variables. '
'See https://github.com/joerick/cibuildwheel#options for info.'))
epilog='''
Most options are supplied via environment variables.
See https://github.com/joerick/cibuildwheel#options for info.
''')
parser.add_argument('--platform',
choices=['auto', 'linux', 'macos', 'windows'],
default=os.environ.get('CIBW_PLATFORM', 'auto'),
help=('Platform to build for. For "linux" you need docker running, on Mac '
'or Linux. For "macos", you need a Mac machine, and note that this '
'script is going to automatically install MacPython on your system, '
'so don\'t run on your development machine. For "windows", you need to '
'run in Windows, and it will build and test for all versions of '
'Python at C:\\PythonXX[-x64]. Default: auto.'))
help='''
Platform to build for. For "linux" you need docker running, on Mac
or Linux. For "macos", you need a Mac machine, and note that this
script is going to automatically install MacPython on your system,
so don't run on your development machine. For "windows", you need to
run in Windows, and it will build and test for all versions of
Python. Default: auto.
''')
parser.add_argument('--output-dir',
default=os.environ.get('CIBW_OUTPUT_DIR', 'wheelhouse'),
help='Destination folder for the wheels.')
parser.add_argument('project_dir',
parser.add_argument('package_dir',
default='.',
nargs='?',
help=('Path to the project that you want wheels for. Default: the current '
'directory.'))
help='''
Path to the package that you want wheels for. Must be a subdirectory of
the working directory. When set, the working directory is still
considered the 'project' and is copied into the Docker container on
Linux. Default: the working directory.
''')
parser.add_argument('--print-build-identifiers',
action='store_true',
help='Print the build identifiers matched by the current invocation and exit.')
args = parser.parse_args()
detect_obsolete_options()
if args.platform != 'auto':
platform = args.platform
else:
if os.environ.get('TRAVIS_OS_NAME') == 'linux':
platform = 'linux'
elif os.environ.get('TRAVIS_OS_NAME') == 'osx':
platform = 'macos'
elif 'APPVEYOR' in os.environ:
platform = 'windows'
elif 'BITRISE_BUILD_NUMBER' in os.environ:
platform = 'macos'
else:
ci = strtobool(os.environ.get('CI', 'false')) or 'BITRISE_BUILD_NUMBER' in os.environ or 'AZURE_HTTP_USER_AGENT' in os.environ or 'GITHUB_WORKFLOW' in os.environ
if not ci:
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 '
'machine using the --platform argument. Check --help output for more '
'information.',
'Travis CI, AppVeyor, Azure Pipelines, GitHub Actions and CircleCI are supported. You '
'can run on your development machine or other CI providers using the --platform argument. '
'Check --help output for more information.',
file=sys.stderr)
exit(2)
if sys.platform.startswith('linux'):
platform = 'linux'
elif sys.platform == 'darwin':
platform = 'macos'
elif sys.platform == 'win32':
platform = 'windows'
else:
print('cibuildwheel: Unable to detect platform from "sys.platform" in a CI environment. You can run '
'cibuildwheel using the --platform argument. Check --help output for more information.',
file=sys.stderr)
exit(2)
output_dir = args.output_dir
test_command = os.environ.get('CIBW_TEST_COMMAND', None)
test_requires = os.environ.get('CIBW_TEST_REQUIRES', '').split()
project_dir = args.project_dir
before_build = get_option_from_environment('CIBW_BEFORE_BUILD', platform=platform)
build_verbosity = get_option_from_environment('CIBW_BUILD_VERBOSITY', platform=platform) or ''
skip_config = os.environ.get('CIBW_SKIP', '')
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform) or ''
package_dir = Path(args.package_dir)
output_dir = Path(args.output_dir)
try:
build_verbosity = min(3, max(-3, int(build_verbosity)))
except ValueError:
build_verbosity = 0
if platform == 'linux':
repair_command_default = 'auditwheel repair -w {dest_dir} {wheel}'
elif platform == 'macos':
repair_command_default = 'delocate-listdeps {wheel} && delocate-wheel --require-archs x86_64 -w {dest_dir} {wheel}'
else:
repair_command_default = ''
build_config, skip_config = os.environ.get('CIBW_BUILD', '*'), os.environ.get('CIBW_SKIP', '')
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
before_all = get_option_from_environment('CIBW_BEFORE_ALL', platform=platform, default='')
before_build = get_option_from_environment('CIBW_BEFORE_BUILD', platform=platform)
repair_command = get_option_from_environment('CIBW_REPAIR_WHEEL_COMMAND', platform=platform, default=repair_command_default)
dependency_versions = get_option_from_environment('CIBW_DEPENDENCY_VERSIONS', platform=platform, default='pinned')
test_command = get_option_from_environment('CIBW_TEST_COMMAND', platform=platform)
before_test = get_option_from_environment('CIBW_BEFORE_TEST', platform=platform)
test_requires = get_option_from_environment('CIBW_TEST_REQUIRES', platform=platform, default='').split()
test_extras = get_option_from_environment('CIBW_TEST_EXTRAS', platform=platform, default='')
build_verbosity_str = get_option_from_environment('CIBW_BUILD_VERBOSITY', platform=platform, default='')
build_selector = BuildSelector(build_config, skip_config)
try:
environment = parse_environment(environment_config)
except (EnvironmentParseError, ValueError) as e:
print('cibuildwheel: Malformed environment option "%s"' % environment_config, file=sys.stderr)
import traceback
except (EnvironmentParseError, ValueError):
print(f'cibuildwheel: Malformed environment option "{environment_config}"', file=sys.stderr)
traceback.print_exc(None, sys.stderr)
exit(2)
skip = BuildSkipper(skip_config)
if dependency_versions == 'pinned':
dependency_constraints: Optional[DependencyConstraints] = DependencyConstraints.with_defaults()
elif dependency_versions == 'latest':
dependency_constraints = None
else:
dependency_versions_path = Path(dependency_versions)
dependency_constraints = DependencyConstraints(dependency_versions_path)
if test_extras:
test_extras = f'[{test_extras}]'
try:
build_verbosity = min(3, max(-3, int(build_verbosity_str)))
except ValueError:
build_verbosity = 0
# Add CIBUILDWHEEL environment variable
# This needs to be passed on to the docker container in linux.py
os.environ['CIBUILDWHEEL'] = '1'
try:
project_setup_py = os.path.join(project_dir, 'setup.py')
name_output = subprocess.check_output([sys.executable, project_setup_py, '--name'],
universal_newlines=True)
# the last line of output is the name
package_name = name_output.strip().splitlines()[-1]
except subprocess.CalledProcessError as err:
if not os.path.exists(project_setup_py):
print('cibuildwheel: Could not find setup.py at root of project', file=sys.stderr)
exit(2)
else:
print('cibuildwheel: Failed to get name of the package. Command was %s' % err.cmd,
file=sys.stderr)
exit(2)
if package_name == '' or package_name == 'UNKNOWN':
print('cibuildwheel: Invalid package name "%s". Check your setup.py' % package_name,
file=sys.stderr)
if not any((package_dir / name).exists()
for name in ["setup.py", "setup.cfg", "pyproject.toml"]):
print('cibuildwheel: Could not find setup.py, setup.cfg or pyproject.toml at root of package', file=sys.stderr)
exit(2)
build_options = dict(
project_dir=project_dir,
package_name=package_name,
if args.print_build_identifiers:
print_build_identifiers(platform, build_selector)
exit(0)
manylinux_images: Optional[Dict[str, str]] = None
if platform == 'linux':
pinned_docker_images_file = resources_dir / 'pinned_docker_images.cfg'
all_pinned_docker_images = ConfigParser()
all_pinned_docker_images.read(pinned_docker_images_file)
# all_pinned_docker_images looks like a dict of dicts, e.g.
# { 'x86_64': {'manylinux1': '...', 'manylinux2010': '...', 'manylinux2014': '...'},
# 'i686': {'manylinux1': '...', 'manylinux2010': '...', 'manylinux2014': '...'},
# 'pypy_x86_64': {'manylinux2010': '...' }
# ... }
manylinux_images = {}
for build_platform in ['x86_64', 'i686', 'pypy_x86_64', 'aarch64', 'ppc64le', 's390x']:
pinned_images = all_pinned_docker_images[build_platform]
config_name = f'CIBW_MANYLINUX_{build_platform.upper()}_IMAGE'
config_value = os.environ.get(config_name)
if config_value is None:
# default to manylinux2010 if it's available, otherwise manylinux2014
image = pinned_images.get('manylinux2010') or pinned_images.get('manylinux2014')
elif config_value in pinned_images:
image = pinned_images[config_value]
else:
image = config_value
manylinux_images[build_platform] = image
build_options = BuildOptions(
package_dir=package_dir,
output_dir=output_dir,
test_command=test_command,
test_requires=test_requires,
test_extras=test_extras,
before_test=before_test,
before_build=before_build,
before_all=before_all,
build_verbosity=build_verbosity,
skip=skip,
build_selector=build_selector,
repair_command=repair_command,
environment=environment,
dependency_constraints=dependency_constraints,
manylinux_images=manylinux_images,
)
if platform == 'linux':
manylinux1_x86_64_image = os.environ.get('CIBW_MANYLINUX1_X86_64_IMAGE', None)
manylinux1_i686_image = os.environ.get('CIBW_MANYLINUX1_I686_IMAGE', None)
build_options.update(
manylinux1_images={'x86_64': manylinux1_x86_64_image, 'i686': manylinux1_i686_image},
)
elif platform == 'macos':
pass
elif platform == 'windows':
pass
# Python is buffering by default when running on the CI platforms, giving problems interleaving subprocess call output with unflushed calls to 'print'
sys.stdout = Unbuffered(sys.stdout) # type: ignore
print_preamble(platform, build_options)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
if not output_dir.exists():
output_dir.mkdir(parents=True)
if platform == 'linux':
cibuildwheel.linux.build(**build_options)
cibuildwheel.linux.build(build_options)
elif platform == 'windows':
cibuildwheel.windows.build(**build_options)
cibuildwheel.windows.build(build_options)
elif platform == 'macos':
cibuildwheel.macos.build(**build_options)
cibuildwheel.macos.build(build_options)
else:
raise Exception('Unsupported platform')
print(f'cibuildwheel: Unsupported platform: {platform}', file=sys.stderr)
exit(2)
def print_preamble(platform, build_options):
def detect_obsolete_options() -> None:
# Check the old 'MANYLINUX1_*_IMAGE' options
for (deprecated, alternative) in [('CIBW_MANYLINUX1_X86_64_IMAGE', 'CIBW_MANYLINUX_X86_64_IMAGE'),
('CIBW_MANYLINUX1_I686_IMAGE', 'CIBW_MANYLINUX_I686_IMAGE')]:
if deprecated in os.environ:
print(f"'{deprecated}' has been deprecated, and will be removed in a future release. Use the option '{alternative}' instead.")
if alternative not in os.environ:
print(f"Using value of option '{deprecated}' as replacement for '{alternative}'")
os.environ[alternative] = os.environ[deprecated]
else:
print(f"Option '{alternative}' is not empty. Please unset '{deprecated}'")
exit(2)
# Check for deprecated identifiers in 'CIBW_BUILD' and 'CIBW_SKIP' options
for option in ['CIBW_BUILD', 'CIBW_SKIP']:
for deprecated, alternative in [('manylinux1', 'manylinux'),
('macosx_10_6_intel', 'macosx_x86_64'),
('macosx_10_9_x86_64', 'macosx_x86_64')]:
if option in os.environ and deprecated in os.environ[option]:
print(f"Build identifiers with '{deprecated}' have been deprecated. Replacing all occurences of '{deprecated}' with '{alternative}' in the option '{option}'")
os.environ[option] = os.environ[option].replace(deprecated, alternative)
def print_preamble(platform: str, build_options: BuildOptions) -> None:
print(textwrap.dedent('''
_ _ _ _ _ _ _
___|_| |_ _ _|_| |_| |_ _ _| |_ ___ ___| |
@@ -163,15 +272,48 @@ def print_preamble(platform, build_options):
|___|_|___|___|_|_|___|_____|_|_|___|___|_|
'''))
print('cibuildwheel version %s\n' % cibuildwheel.__version__)
print(f'cibuildwheel version {cibuildwheel.__version__}\n')
print('Build options:')
print(' platform: %r' % platform)
for option, value in build_options.items():
print(' %s: %r' % (option, value))
print(f' platform: {platform!r}')
for option, value in sorted(build_options._asdict().items()):
print(f' {option}: {value!r}')
warnings = detect_warnings(platform, build_options)
if warnings:
print('\nWarnings:')
for warning in warnings:
print(' ' + warning)
print('\nHere we go!\n')
def print_build_identifiers(platform: str, build_selector: BuildSelector) -> None:
python_configurations: List[Any] = []
if platform == 'linux':
python_configurations = cibuildwheel.linux.get_python_configurations(build_selector)
elif platform == 'windows':
python_configurations = cibuildwheel.windows.get_python_configurations(build_selector)
elif platform == 'macos':
python_configurations = cibuildwheel.macos.get_python_configurations(build_selector)
for config in python_configurations:
print(config.identifier)
def detect_warnings(platform: str, build_options: BuildOptions) -> List[str]:
warnings = []
# warn about deprecated {python} and {pip}
for option_name in ['test_command', 'before_build']:
option_value = getattr(build_options, option_name)
if option_value:
if '{python}' in option_value or '{pip}' in option_value:
warnings.append(option_name + ": '{python}' and '{pip}' are no longer needed, and will be removed in a future release. Simply use 'python' or 'pip' instead.")
return warnings
if __name__ == '__main__':
main()
+72 -37
View File
@@ -1,10 +1,24 @@
import subprocess, shlex, sys
from collections import namedtuple
import bashlex
import shlex
import subprocess
from typing import Callable, Dict, List, NamedTuple, Optional, Sequence
NodeExecutionContext = namedtuple('NodeExecutionContext', ['environment', 'input'])
import bashlex # type: ignore
def evaluate(value, environment):
# a function that takes a shell command and the environment, and returns the result
EnvironmentExecutor = Callable[[str, Dict[str, str]], str]
def local_environment_executor(command: str, env: Dict[str, str]) -> str:
return subprocess.check_output(shlex.split(command), env=env, universal_newlines=True)
class NodeExecutionContext(NamedTuple):
environment: Dict[str, str]
input: str
executor: EnvironmentExecutor
def evaluate(value: str, environment: Dict[str, str], executor: Optional[EnvironmentExecutor] = None) -> str:
if not value:
# empty string evaluates to empty string
# (but trips up bashlex)
@@ -13,59 +27,80 @@ def evaluate(value, environment):
command_node = bashlex.parsesingle(value)
if len(command_node.parts) != 1:
raise ValueError('"%s" has too many parts' % value)
raise ValueError(f'"{value}" has too many parts')
value_word_node = command_node.parts[0]
return evaluate_node(
value_word_node,
context=NodeExecutionContext(environment=environment, input=value)
value_word_node,
context=NodeExecutionContext(environment=environment, input=value, executor=executor or local_environment_executor)
)
def evaluate_node(node, context):
def evaluate_node(node: bashlex.ast.node, context: NodeExecutionContext) -> str:
if node.kind == 'word':
return evaluate_word_node(node, context=context)
elif node.kind == 'commandsubstitution':
return evaluate_command_node(node.command, context=context)
node_result = evaluate_command_node(node.command, context=context)
# bash removes training newlines in command substitution
return node_result.rstrip()
elif node.kind == 'parameter':
return evaluate_parameter_node(node, context=context)
else:
raise ValueError('Unsupported bash construct: "%s"' % node.word)
raise ValueError(f'Unsupported bash construct: "{node.kind}"')
def evaluate_word_node(node, context):
word_start = node.pos[0]
word_end = node.pos[1]
word_string = context.input[word_start:word_end]
letters = list(word_string)
def evaluate_word_node(node: bashlex.ast.node, context: NodeExecutionContext) -> str:
value = node.word
for part in node.parts:
part_start = part.pos[0] - word_start
part_end = part.pos[1] - word_start
part_string = context.input[part.pos[0]:part.pos[1]]
part_value = evaluate_node(part, context=context)
# Set all the characters in the part to None
for i in range(part_start, part_end):
letters[i] = None
if part_string not in value:
raise RuntimeError(
'bash parse failed. part "{}" not found in "{}". Word was "{}". Full input was "{}"'.format(
part_string, value, node.word, context.input,
)
)
letters[part_start] = evaluate_node(part, context=context)
value = value.replace(part_string, part_value, 1)
# remove the None letters and concat
value = ''.join(l for l in letters if l is not None)
# apply bash-like quotes/whitespace treatment
return ' '.join(word.strip() for word in shlex.split(value))
return value
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)
if sys.version_info[0] >= 3:
return output.decode('utf8', 'replace')
def evaluate_command_node(node: bashlex.ast.node, context: NodeExecutionContext) -> str:
if any(n.kind == 'operator' for n in node.parts):
return evaluate_nodes_as_compound_command(node.parts, context=context)
else:
return output
return evaluate_nodes_as_simple_command(node.parts, context=context)
def evaluate_parameter_node(node, context):
def evaluate_nodes_as_compound_command(nodes: Sequence[bashlex.ast.node], context: NodeExecutionContext) -> str:
# bashlex doesn't support any operators besides ';' inside command
# substitutions, so we only need to handle that case. We do so assuming
# that `set -o errexit` is on, because it's easier to code!
result = ''
for node in nodes:
if node.kind == 'command':
result += evaluate_command_node(node, context=context)
elif node.kind == 'operator':
if node.op == ';':
pass
else:
raise ValueError(f'Unsupported bash operator: "{node.op}"')
else:
raise ValueError(f'Unsupported bash node in compound command: "{node.kind}"')
return result
def evaluate_nodes_as_simple_command(nodes: List[bashlex.ast.node], context: NodeExecutionContext):
words = [evaluate_node(part, context=context) for part in nodes]
command = ' '.join(words)
return context.executor(command, context.environment)
def evaluate_parameter_node(node: bashlex.ast.node, context: NodeExecutionContext) -> str:
return context.environment.get(node.value, '')
+189
View File
@@ -0,0 +1,189 @@
import io
import json
import os
import shlex
import subprocess
import sys
import uuid
from os import PathLike
from pathlib import Path, PurePath
from typing import IO, Dict, List, Optional, Sequence, Union
class DockerContainer:
'''
An object that represents a running Docker container.
Intended for use as a context manager e.g.
`with DockerContainer('ubuntu') as docker:`
A bash shell is running in the remote container. When `call()` is invoked,
the command is relayed to the remote shell, and the results are streamed
back to cibuildwheel.
'''
UTILITY_PYTHON = '/opt/python/cp38-cp38/bin/python'
process: subprocess.Popen
bash_stdin: IO[bytes]
bash_stdout: IO[bytes]
def __init__(self, docker_image: str, simulate_32_bit=False):
self.docker_image = docker_image
self.simulate_32_bit = simulate_32_bit
def __enter__(self) -> 'DockerContainer':
self.name = f'cibuildwheel-{uuid.uuid4()}'
shell_args = ['linux32', '/bin/bash'] if self.simulate_32_bit else ['/bin/bash']
subprocess.run(
[
'docker', 'create',
'--env', 'CIBUILDWHEEL',
'--name', self.name,
'-i',
'-v', '/:/host', # ignored on CircleCI
self.docker_image,
*shell_args
],
check=True,
)
self.process = subprocess.Popen(
[
'docker', 'start',
'--attach', '--interactive',
self.name,
],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
assert self.process.stdin and self.process.stdout
self.bash_stdin = self.process.stdin
self.bash_stdout = self.process.stdout
# run a noop command to block until the container is responding
self.call(['/bin/true'])
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.bash_stdin.close()
self.process.terminate()
self.process.wait()
subprocess.run(['docker', 'rm', '--force', '-v', self.name])
self.name = None
def copy_into(self, from_path: Path, to_path: PurePath) -> None:
# `docker cp` causes 'no space left on device' error when
# a container is running and the host filesystem is
# mounted. https://github.com/moby/moby/issues/38995
# Use `docker exec` instead.
if from_path.is_dir():
self.call(['mkdir', '-p', to_path])
subprocess.run(
f'tar cf - . | docker exec -i {self.name} tar -xC {shell_quote(to_path)} -f -',
shell=True,
check=True,
cwd=from_path)
else:
subprocess.run(
f'cat {shell_quote(from_path)} | docker exec -i {self.name} sh -c "cat > {shell_quote(to_path)}"',
shell=True,
check=True)
def copy_out(self, from_path: PurePath, to_path: Path) -> None:
# note: we assume from_path is a dir
to_path.mkdir(parents=True, exist_ok=True)
subprocess.run(
f'docker exec -i {self.name} tar -cC {shell_quote(from_path)} -f - . | tar -xf -',
shell=True,
check=True,
cwd=to_path
)
def glob(self, path: PurePath, pattern: str) -> List[PurePath]:
glob_pattern = os.path.join(str(path), pattern)
path_strs = json.loads(self.call([
self.UTILITY_PYTHON,
'-c',
f'import sys, json, glob; json.dump(glob.glob({glob_pattern!r}), sys.stdout)'
], capture_output=True))
return [PurePath(p) for p in path_strs]
def call(self, args: Sequence[Union[str, PathLike]], env: Dict[str, str] = {},
capture_output=False, cwd: Optional[Union[str, PathLike]] = None) -> str:
chdir = f'cd {cwd}' if cwd else ''
env_assignments = ' '.join(f'{shlex.quote(k)}={shlex.quote(v)}'
for k, v in env.items())
command = ' '.join(shlex.quote(str(a)) for a in args)
end_of_message = str(uuid.uuid4())
# log the command we're executing
print(f' + {command}')
# Write a command to the remote shell. First we change the
# cwd, if that's required. Then, we use the `env` utility to run
# `command` inside the specified environment. We use `env` because it
# can cope with spaces and strange characters in the name or value.
# Finally, the remote shell is told to write a footer - this will show
# up in the output so we know when to stop reading, and will include
# the returncode of `command`.
self.bash_stdin.write(bytes(f'''(
{chdir}
env {env_assignments} {command}
printf "%04d%s\n" $? {end_of_message}
)
''', encoding='utf8', errors='surrogateescape'))
self.bash_stdin.flush()
if capture_output:
output_io: IO[bytes] = io.BytesIO()
else:
output_io = sys.stdout.buffer
while True:
line = self.bash_stdout.readline()
if line.endswith(b'%s\n' % (bytes(end_of_message, encoding='utf8'))):
footer_offset = (
len(line)
- 1 # newline character
- len(end_of_message) # delimiter
- 4 # 4 returncode decimals
)
returncode_str = line[footer_offset:footer_offset+4]
returncode = int(returncode_str)
# add the last line to output, without the footer
output_io.write(line[0:footer_offset])
break
else:
output_io.write(line)
if isinstance(output_io, io.BytesIO):
output = str(output_io.getvalue(), encoding='utf8', errors='surrogateescape')
else:
output = ''
if returncode != 0:
raise subprocess.CalledProcessError(returncode, args, output)
return output
def get_environment(self) -> Dict[str, str]:
return json.loads(self.call([
self.UTILITY_PYTHON,
'-c',
'import sys, json, os; json.dump(os.environ.copy(), sys.stdout)'
], capture_output=True))
def environment_executor(self, command: str, environment: Dict[str, str]) -> str:
# used as an EnvironmentExecutor to evaluate commands and capture output
return self.call(shlex.split(command), env=environment)
def shell_quote(path: PurePath) -> str:
return shlex.quote(str(path))
+29 -24
View File
@@ -1,4 +1,7 @@
import bashlex
import bashlex # type: ignore
from typing import Dict, List, Mapping, Optional
from . import bashlex_eval
@@ -6,13 +9,7 @@ class EnvironmentParseError(Exception):
pass
def parse_environment(env_string):
env_items = split_env_items(env_string)
assignments = [EnvironmentAssignment(item) for item in env_items]
return ParsedEnvironment(assignments=assignments)
def split_env_items(env_string):
def split_env_items(env_string: str) -> List[str]:
'''Splits space-separated variable assignments into a list of individual assignments.
>>> split_env_items('VAR=abc')
@@ -41,40 +38,48 @@ def split_env_items(env_string):
return result
class EnvironmentAssignment(object):
def __init__(self, assignment):
class EnvironmentAssignment:
def __init__(self, assignment: str):
name, equals, value = assignment.partition('=')
if not equals:
raise EnvironmentParseError(assignment)
self.name = name
self.value = value
def evaluated_value(self, environment):
def evaluated_value(self, environment: Dict[str, str], executor: Optional[bashlex_eval.EnvironmentExecutor] = None) -> str:
'''Returns the value of this assignment, as evaluated in the environment'''
return bashlex_eval.evaluate(self.value, environment=environment)
return bashlex_eval.evaluate(self.value, environment=environment, executor=executor)
def as_shell_assignment(self):
return 'export %s=%s' % (self.name, self.value)
def as_shell_assignment(self) -> str:
return f'export {self.name}={self.value}'
def __repr__(self):
return '%s=%s' % (self.name, self.value)
def __repr__(self) -> str:
return f'{self.name}={self.value}'
class ParsedEnvironment(object):
def __init__(self, assignments):
class ParsedEnvironment:
def __init__(self, assignments: List[EnvironmentAssignment]):
self.assignments = assignments
def as_dictionary(self, prev_environment):
environment = prev_environment.copy()
def as_dictionary(self,
prev_environment: Mapping[str, str],
executor: Optional[bashlex_eval.EnvironmentExecutor] = None) -> Dict[str, str]:
environment = dict(**prev_environment)
for assignment in self.assignments:
value = assignment.evaluated_value(environment=environment)
value = assignment.evaluated_value(environment=environment, executor=executor)
environment[assignment.name] = value
return environment
def as_shell_commands(self):
def as_shell_commands(self) -> List[str]:
return [a.as_shell_assignment() for a in self.assignments]
def __repr__(self):
return 'ParsedEnvironment(%r)' % [repr(a) for a in self.assignments]
def __repr__(self) -> str:
return f'ParsedEnvironment({[repr(a) for a in self.assignments]!r})'
def parse_environment(env_string: str) -> ParsedEnvironment:
env_items = split_env_items(env_string)
assignments = [EnvironmentAssignment(item) for item in env_items]
return ParsedEnvironment(assignments=assignments)
+232 -116
View File
@@ -1,134 +1,250 @@
from __future__ import print_function
import os, subprocess, sys
from collections import namedtuple
from .util import prepare_command, get_build_verbosity_extra_flags
import platform
import subprocess
import sys
import textwrap
from os import PathLike
from pathlib import Path, PurePath
from typing import List, NamedTuple, Union
try:
from shlex import quote as shlex_quote
except ImportError:
from pipes import quote as shlex_quote
from .docker_container import DockerContainer
from .util import (BuildOptions, BuildSelector,
get_build_verbosity_extra_flags, prepare_command)
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, skip, environment, manylinux1_images):
def matches_platform(identifier: str) -> bool:
pm = platform.machine()
if pm == "x86_64":
# x86_64 machines can run i686 docker containers
if identifier.endswith('x86_64') or identifier.endswith('i686'):
return True
elif pm == "i686":
if identifier.endswith('i686'):
return True
elif pm == "aarch64":
if identifier.endswith('aarch64'):
return True
elif pm == "ppc64le":
if identifier.endswith('ppc64le'):
return True
elif pm == "s390x":
if identifier.endswith('s390x'):
return True
return False
class PythonConfiguration(NamedTuple):
version: str
identifier: str
path_str: str
@property
def path(self):
return PurePath(self.path_str)
def get_python_configurations(build_selector: BuildSelector) -> List[PythonConfiguration]:
python_configurations = [
PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path_str='/opt/python/cp27-cp27m'),
PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path_str='/opt/python/cp27-cp27mu'),
PythonConfiguration(version='3.5', identifier='cp35-manylinux_x86_64', path_str='/opt/python/cp35-cp35m'),
PythonConfiguration(version='3.6', identifier='cp36-manylinux_x86_64', path_str='/opt/python/cp36-cp36m'),
PythonConfiguration(version='3.7', identifier='cp37-manylinux_x86_64', path_str='/opt/python/cp37-cp37m'),
PythonConfiguration(version='3.8', identifier='cp38-manylinux_x86_64', path_str='/opt/python/cp38-cp38'),
PythonConfiguration(version='2.7', identifier='cp27-manylinux_i686', path_str='/opt/python/cp27-cp27m'),
PythonConfiguration(version='2.7', identifier='cp27-manylinux_i686', path_str='/opt/python/cp27-cp27mu'),
PythonConfiguration(version='3.5', identifier='cp35-manylinux_i686', path_str='/opt/python/cp35-cp35m'),
PythonConfiguration(version='3.6', identifier='cp36-manylinux_i686', path_str='/opt/python/cp36-cp36m'),
PythonConfiguration(version='3.7', identifier='cp37-manylinux_i686', path_str='/opt/python/cp37-cp37m'),
PythonConfiguration(version='3.8', identifier='cp38-manylinux_i686', path_str='/opt/python/cp38-cp38'),
PythonConfiguration(version='2.7', identifier='pp27-manylinux_x86_64', path_str='/opt/python/pp27-pypy_73'),
PythonConfiguration(version='3.6', identifier='pp36-manylinux_x86_64', path_str='/opt/python/pp36-pypy36_pp73'),
PythonConfiguration(version='3.5', identifier='cp35-manylinux_aarch64', path_str='/opt/python/cp35-cp35m'),
PythonConfiguration(version='3.6', identifier='cp36-manylinux_aarch64', path_str='/opt/python/cp36-cp36m'),
PythonConfiguration(version='3.7', identifier='cp37-manylinux_aarch64', path_str='/opt/python/cp37-cp37m'),
PythonConfiguration(version='3.8', identifier='cp38-manylinux_aarch64', path_str='/opt/python/cp38-cp38'),
PythonConfiguration(version='3.5', identifier='cp35-manylinux_ppc64le', path_str='/opt/python/cp35-cp35m'),
PythonConfiguration(version='3.6', identifier='cp36-manylinux_ppc64le', path_str='/opt/python/cp36-cp36m'),
PythonConfiguration(version='3.7', identifier='cp37-manylinux_ppc64le', path_str='/opt/python/cp37-cp37m'),
PythonConfiguration(version='3.8', identifier='cp38-manylinux_ppc64le', path_str='/opt/python/cp38-cp38'),
PythonConfiguration(version='3.5', identifier='cp35-manylinux_s390x', path_str='/opt/python/cp35-cp35m'),
PythonConfiguration(version='3.6', identifier='cp36-manylinux_s390x', path_str='/opt/python/cp36-cp36m'),
PythonConfiguration(version='3.7', identifier='cp37-manylinux_s390x', path_str='/opt/python/cp37-cp37m'),
PythonConfiguration(version='3.8', identifier='cp38-manylinux_s390x', path_str='/opt/python/cp38-cp38'),
]
# skip builds as required
return [c for c in python_configurations if matches_platform(c.identifier) and build_selector(c.identifier)]
def build(options: BuildOptions) -> None:
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 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',
file=sys.stderr)
exit(2)
PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path'])
python_configurations = [
PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27m'),
PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27mu'),
PythonConfiguration(identifier='cp34-manylinux1_x86_64', path='/opt/python/cp34-cp34m'),
PythonConfiguration(identifier='cp35-manylinux1_x86_64', path='/opt/python/cp35-cp35m'),
PythonConfiguration(identifier='cp36-manylinux1_x86_64', path='/opt/python/cp36-cp36m'),
PythonConfiguration(identifier='cp27-manylinux1_i686', path='/opt/python/cp27-cp27m'),
PythonConfiguration(identifier='cp27-manylinux1_i686', path='/opt/python/cp27-cp27mu'),
PythonConfiguration(identifier='cp34-manylinux1_i686', path='/opt/python/cp34-cp34m'),
PythonConfiguration(identifier='cp35-manylinux1_i686', path='/opt/python/cp35-cp35m'),
PythonConfiguration(identifier='cp36-manylinux1_i686', path='/opt/python/cp36-cp36m'),
]
# skip builds as required
python_configurations = [c for c in python_configurations if not skip(c.identifier)]
assert options.manylinux_images is not None
python_configurations = get_python_configurations(options.build_selector)
platforms = [
('manylinux1_x86_64', manylinux1_images.get('x86_64') or 'quay.io/pypa/manylinux1_x86_64'),
('manylinux1_i686', manylinux1_images.get('i686') or 'quay.io/pypa/manylinux1_i686'),
('cp', 'manylinux_x86_64', options.manylinux_images['x86_64']),
('cp', 'manylinux_i686', options.manylinux_images['i686']),
('cp', 'manylinux_aarch64', options.manylinux_images['aarch64']),
('cp', 'manylinux_ppc64le', options.manylinux_images['ppc64le']),
('cp', 'manylinux_s390x', options.manylinux_images['s390x']),
('pp', 'manylinux_x86_64', options.manylinux_images['pypy_x86_64']),
]
for platform_tag, docker_image in platforms:
platform_configs = [c for c in python_configurations if c.identifier.endswith(platform_tag)]
cwd = Path.cwd()
abs_package_dir = options.package_dir.resolve()
if cwd != abs_package_dir and cwd not in abs_package_dir.parents:
raise Exception('package_dir must be inside the working directory')
container_package_dir = PurePath('/project') / abs_package_dir.relative_to(cwd)
container_output_dir = PurePath('/output')
for implementation, platform_tag, docker_image in platforms:
platform_configs = [c for c in python_configurations if c.identifier.startswith(implementation) and c.identifier.endswith(platform_tag)]
if not platform_configs:
continue
bash_script = '''
set -o errexit
set -o xtrace
cd /project
{environment_exports}
for PYBIN in {pybin_paths}; do
# Setup
rm -rf /tmp/built_wheel
rm -rf /tmp/delocated_wheel
mkdir /tmp/built_wheel
mkdir /tmp/delocated_wheel
if [ ! -z {before_build} ]; then
PATH="$PYBIN:$PATH" sh -c {before_build}
fi
# Build that wheel
PATH="$PYBIN:$PATH" "$PYBIN/pip" wheel . -w /tmp/built_wheel --no-deps {build_verbosity_flag}
built_wheel=(/tmp/built_wheel/*.whl)
# Delocate the wheel
# NOTE: 'built_wheel' here is a bash array of glob matches; "$built_wheel" returns
# the first element
if [[ "$built_wheel" == *none-any.whl ]]; then
# pure python wheel - just copy
mv "$built_wheel" /tmp/delocated_wheel
else
auditwheel repair "$built_wheel" -w /tmp/delocated_wheel
fi
delocated_wheel=(/tmp/delocated_wheel/*.whl)
# Install the wheel we just built
"$PYBIN/pip" install "$delocated_wheel"
# Install any requirements to run the tests
if [ ! -z "{test_requires}" ]; then
"$PYBIN/pip" install {test_requires}
fi
# Run the tests from a different directory
if [ ! -z {test_command} ]; then
pushd $HOME
PATH="$PYBIN:$PATH" sh -c {test_command}
popd
fi
# we're all done here; move it to output
mv "$delocated_wheel" /output
done
'''.format(
package_name=package_name,
pybin_paths=' '.join(c.path+'/bin' for c in platform_configs),
test_requires=' '.join(test_requires),
test_command=shlex_quote(
prepare_command(test_command, python='python', pip='pip', project='/project') if test_command else ''
),
before_build=shlex_quote(
prepare_command(before_build, python='python', pip='pip', project='/project') if before_build else ''
),
build_verbosity_flag=' '.join(get_build_verbosity_extra_flags(build_verbosity)),
environment_exports='\n'.join(environment.as_shell_commands()),
)
docker_process = subprocess.Popen([
'docker',
'run',
'--env',
'CIBUILDWHEEL',
'--rm',
'-i',
'-v', '%s:/project' % os.path.abspath(project_dir),
'-v', '%s:/output' % os.path.abspath(output_dir),
'-v', '/:/host',
docker_image,
'/bin/bash'],
stdin=subprocess.PIPE, universal_newlines=True)
try:
docker_process.communicate(bash_script)
except KeyboardInterrupt:
docker_process.kill()
docker_process.wait()
with DockerContainer(docker_image, simulate_32_bit=platform_tag.endswith('i686')) as docker:
docker.copy_into(Path.cwd(), Path('/project'))
if docker_process.returncode != 0:
if options.before_all:
env = docker.get_environment()
env['PATH'] = f'/opt/python/cp38-cp38:{env["PATH"]}'
env = options.environment.as_dictionary(env, executor=docker.environment_executor)
before_all_prepared = prepare_command(options.before_all, project='/project', package=container_package_dir)
docker.call(['sh', '-c', before_all_prepared], env=env)
for config in platform_configs:
dependency_constraint_flags: List[Union[str, PathLike]] = []
if options.dependency_constraints:
constraints_file = options.dependency_constraints.get_for_python_version(config.version)
container_constraints_file = PurePath('/constraints.txt')
docker.copy_into(constraints_file, container_constraints_file)
dependency_constraint_flags = ['-c', container_constraints_file]
env = docker.get_environment()
# put this config's python top of the list
python_bin = config.path / 'bin'
env['PATH'] = f'{python_bin}:{env["PATH"]}'
env = options.environment.as_dictionary(env, executor=docker.environment_executor)
# check config python and pip are still on PATH
which_python = docker.call(['which', 'python'], env=env, capture_output=True).strip()
if PurePath(which_python) != python_bin / 'python':
print("cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.", file=sys.stderr)
exit(1)
which_pip = docker.call(['which', 'pip'], env=env, capture_output=True).strip()
if PurePath(which_pip) != python_bin / 'pip':
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
exit(1)
if options.before_build:
before_build_prepared = prepare_command(options.before_build, project='/project', package=container_package_dir)
docker.call(['sh', '-c', before_build_prepared], env=env)
temp_dir = PurePath('/tmp/cibuildwheel')
built_wheel_dir = temp_dir / 'built_wheel'
docker.call(['rm', '-rf', built_wheel_dir])
docker.call(['mkdir', '-p', built_wheel_dir])
docker.call([
'pip', 'wheel',
container_package_dir,
'-w', built_wheel_dir,
'--no-deps',
*get_build_verbosity_extra_flags(options.build_verbosity)
], env=env)
built_wheel = docker.glob(built_wheel_dir, '*.whl')[0]
repaired_wheel_dir = temp_dir / 'repaired_wheel'
docker.call(['rm', '-rf', repaired_wheel_dir])
docker.call(['mkdir', '-p', repaired_wheel_dir])
if built_wheel.name.endswith('none-any.whl') or not options.repair_command:
docker.call(['mv', built_wheel, repaired_wheel_dir])
else:
repair_command_prepared = prepare_command(options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir)
docker.call(['sh', '-c', repair_command_prepared], env=env)
repaired_wheels = docker.glob(repaired_wheel_dir, '*.whl')
if options.test_command:
# set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time.
docker.call(['pip', 'install', 'virtualenv', *dependency_constraint_flags], env=env)
venv_dir = PurePath(docker.call(['mktemp', '-d'], capture_output=True).strip()) / 'venv'
docker.call(['python', '-m', 'virtualenv', '--no-download', venv_dir], env=env)
virtualenv_env = env.copy()
virtualenv_env['PATH'] = f"{venv_dir / 'bin'}:{virtualenv_env['PATH']}"
if options.before_test:
before_test_prepared = prepare_command(options.before_test, project='/project', package=container_package_dir)
docker.call(['sh', '-c', before_test_prepared], env=virtualenv_env)
# Install the wheel we just built
# Note: If auditwheel produced two wheels, it's because the earlier produced wheel
# conforms to multiple manylinux standards. These multiple versions of the wheel are
# functionally the same, differing only in name, wheel metadata, and possibly include
# different external shared libraries. so it doesn't matter which one we run the tests on.
# Let's just pick the first one.
wheel_to_test = repaired_wheels[0]
docker.call(['pip', 'install', str(wheel_to_test) + options.test_extras], env=virtualenv_env)
# Install any requirements to run the tests
if options.test_requires:
docker.call(['pip', 'install', *options.test_requires], env=virtualenv_env)
# Run the tests from a different directory
test_command_prepared = prepare_command(options.test_command, project='/project', package=container_package_dir)
docker.call(['sh', '-c', test_command_prepared], cwd='/root', env=virtualenv_env)
# clean up test environment
docker.call(['rm', '-rf', venv_dir])
# move repaired wheels to output
docker.call(['mkdir', '-p', container_output_dir])
docker.call(['mv', *repaired_wheels, container_output_dir])
# copy the output back into the host
docker.copy_out(container_output_dir, options.output_dir)
except subprocess.CalledProcessError as error:
print(f'Command {error.cmd} failed with code {error.returncode}. {error.stdout}')
troubleshoot(options.package_dir, error)
exit(1)
def troubleshoot(package_dir: Path, error: Exception) -> None:
if (isinstance(error, subprocess.CalledProcessError) and 'exec' in error.cmd):
# the bash script failed
print('Checking for common errors...')
so_files = list(package_dir.glob('**/*.so'))
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' {f}' for f in so_files]))
print('')
+244 -92
View File
@@ -1,118 +1,270 @@
from __future__ import print_function
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
import os
import shlex
import shutil
import subprocess
import sys
import tempfile
from os import PathLike
from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Sequence, Union
from .util import prepare_command, get_build_verbosity_extra_flags
from .environment import ParsedEnvironment
from .util import (BuildOptions, BuildSelector, download,
get_build_verbosity_extra_flags, get_pip_script,
prepare_command)
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, skip, environment):
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'url'])
def call(args: Union[str, Sequence[Union[str, PathLike]]], env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None, shell: bool = False) -> int:
# print the command executing for the logs
if shell:
print(f'+ {args}')
else:
print('+ ' + ' '.join(shlex.quote(str(a)) for a in args))
return subprocess.check_call(args, env=env, cwd=cwd, shell=shell)
class PythonConfiguration(NamedTuple):
version: str
identifier: str
url: str
def get_python_configurations(build_selector: BuildSelector) -> List[PythonConfiguration]:
python_configurations = [
PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.15/python-2.7.15-macosx10.6.pkg'),
PythonConfiguration(version='3.4', identifier='cp34-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.4.4/python-3.4.4-macosx10.6.pkg'),
PythonConfiguration(version='3.5', identifier='cp35-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg'),
PythonConfiguration(version='3.6', identifier='cp36-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.6.5/python-3.6.5-macosx10.6.pkg'),
# CPython
PythonConfiguration(version='2.7', identifier='cp27-macosx_x86_64', url='https://www.python.org/ftp/python/2.7.18/python-2.7.18-macosx10.9.pkg'),
PythonConfiguration(version='3.5', identifier='cp35-macosx_x86_64', url='https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg'),
PythonConfiguration(version='3.6', identifier='cp36-macosx_x86_64', url='https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.9.pkg'),
PythonConfiguration(version='3.7', identifier='cp37-macosx_x86_64', url='https://www.python.org/ftp/python/3.7.8/python-3.7.8-macosx10.9.pkg'),
PythonConfiguration(version='3.8', identifier='cp38-macosx_x86_64', url='https://www.python.org/ftp/python/3.8.4/python-3.8.4-macosx10.9.pkg'),
# PyPy
PythonConfiguration(version='2.7', identifier='pp27-macosx_x86_64', url='https://downloads.python.org/pypy/pypy2.7-v7.3.1-osx64.tar.bz2'),
PythonConfiguration(version='3.6', identifier='pp36-macosx_x86_64', url='https://downloads.python.org/pypy/pypy3.6-v7.3.1-osx64.tar.bz2'),
]
get_pip_url = 'https://bootstrap.pypa.io/get-pip.py'
get_pip_script = '/tmp/get-pip.py'
pkgs_output = subprocess.check_output(['pkgutil', '--pkgs'])
if sys.version_info[0] >= 3:
pkgs_output = pkgs_output.decode('utf8')
installed_system_packages = pkgs_output.splitlines()
# skip builds as required
return [c for c in python_configurations if build_selector(c.identifier)]
def call(args, env=None, cwd=None, shell=False):
# print the command executing for the logs
if shell:
print('+ %s' % args)
else:
print('+ ' + ' '.join(shlex_quote(a) for a in args))
return subprocess.check_call(args, env=env, cwd=cwd, shell=shell)
SYMLINKS_DIR = Path('/tmp/cibw_bin')
abs_project_dir = os.path.abspath(project_dir)
# get latest pip once and for all
call(['curl', '-L', '-o', get_pip_script, get_pip_url])
def make_symlinks(installation_bin_path: Path, python_executable: str, pip_executable: str) -> None:
assert (installation_bin_path / python_executable).exists()
# Python bin folders on Mac don't symlink `python3` to `python`, and neither
# does PyPy for `pypy` or `pypy3`, so we do that so `python` and `pip` always
# point to the active configuration.
if SYMLINKS_DIR.exists():
shutil.rmtree(SYMLINKS_DIR)
SYMLINKS_DIR.mkdir(parents=True)
(SYMLINKS_DIR / 'python').symlink_to(installation_bin_path / python_executable)
(SYMLINKS_DIR / 'python-config').symlink_to(installation_bin_path / (python_executable + '-config'))
(SYMLINKS_DIR / 'pip').symlink_to(installation_bin_path / pip_executable)
def install_cpython(version: str, url: str) -> Path:
installed_system_packages = subprocess.check_output(['pkgutil', '--pkgs'], universal_newlines=True).splitlines()
# if this version of python isn't installed, get it from python.org and install
python_package_identifier = f'org.python.Python.PythonFramework-{version}'
if python_package_identifier not in installed_system_packages:
# download the pkg
download(url, Path('/tmp/Python.pkg'))
# install
call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/'])
# patch open ssl
if version == '3.5':
open_ssl_patch_url = f'https://github.com/mayeut/patch-macos-python-openssl/releases/download/v1.0.2u/patch-macos-python-{version}-openssl-v1.0.2u.tar.gz'
download(open_ssl_patch_url, Path('/tmp/python-patch.tar.gz'))
call(['sudo', 'tar', '-C', f'/Library/Frameworks/Python.framework/Versions/{version}/', '-xmf', '/tmp/python-patch.tar.gz'])
installation_bin_path = Path(f'/Library/Frameworks/Python.framework/Versions/{version}/bin')
python_executable = 'python3' if version[0] == '3' else 'python'
pip_executable = 'pip3' if version[0] == '3' else 'pip'
make_symlinks(installation_bin_path, python_executable, pip_executable)
return installation_bin_path
def install_pypy(version: str, url: str) -> Path:
pypy_tar_bz2 = url.rsplit('/', 1)[-1]
extension = ".tar.bz2"
assert pypy_tar_bz2.endswith(extension)
pypy_base_filename = pypy_tar_bz2[:-len(extension)]
installation_path = Path('/tmp') / pypy_base_filename
if not installation_path.exists():
downloaded_tar_bz2 = Path("/tmp") / pypy_tar_bz2
download(url, downloaded_tar_bz2)
call(['tar', '-C', '/tmp', '-xf', downloaded_tar_bz2])
installation_bin_path = installation_path / 'bin'
python_executable = 'pypy3' if version[0] == '3' else 'pypy'
pip_executable = 'pip3' if version[0] == '3' else 'pip'
make_symlinks(installation_bin_path, python_executable, pip_executable)
return installation_bin_path
def setup_python(python_configuration: PythonConfiguration,
dependency_constraint_flags: Sequence[Union[str, PathLike]],
environment: ParsedEnvironment) -> Dict[str, str]:
if python_configuration.identifier.startswith('cp'):
installation_bin_path = install_cpython(python_configuration.version, python_configuration.url)
elif python_configuration.identifier.startswith('pp'):
installation_bin_path = install_pypy(python_configuration.version, python_configuration.url)
else:
raise ValueError("Unknown Python implementation")
env = os.environ.copy()
env['PATH'] = os.pathsep.join([
str(SYMLINKS_DIR),
str(installation_bin_path),
env['PATH'],
])
# Fix issue with site.py setting the wrong `sys.prefix`, `sys.exec_prefix`,
# `sys.path`, ... for PyPy: https://foss.heptapod.net/pypy/pypy/issues/3175
# Also fix an issue with the shebang of installed scripts inside the
# testing virtualenv- see https://github.com/theacodes/nox/issues/44 and
# https://github.com/pypa/virtualenv/issues/620
# Also see https://github.com/python/cpython/pull/9516
env.pop('__PYVENV_LAUNCHER__', None)
env = environment.as_dictionary(prev_environment=env)
# check what version we're on
call(['which', 'python'], env=env)
call(['python', '--version'], env=env)
which_python = subprocess.check_output(['which', 'python'], env=env, universal_newlines=True).strip()
if which_python != '/tmp/cibw_bin/python':
print("cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.", file=sys.stderr)
exit(1)
# install pip & wheel
call(['python', get_pip_script, *dependency_constraint_flags], env=env, cwd="/tmp")
assert (installation_bin_path / 'pip').exists()
call(['which', 'pip'], env=env)
call(['pip', '--version'], env=env)
which_pip = subprocess.check_output(['which', 'pip'], env=env, universal_newlines=True).strip()
if which_pip != '/tmp/cibw_bin/pip':
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
exit(1)
call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', 'delocate', *dependency_constraint_flags], env=env)
# Set MACOSX_DEPLOYMENT_TARGET to 10.9, if the user didn't set it.
# CPython 3.5 defaults to 10.6, and pypy defaults to 10.7, causing
# inconsistencies if it's left unset.
env.setdefault('MACOSX_DEPLOYMENT_TARGET', '10.9')
if python_configuration.version == '3.5':
# Cross-compilation platform override - CPython 3.5 has an
# i386/x86_64 version of Python, but we only want a x64_64 build
env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-10.9-x86_64')
# https://github.com/python/cpython/blob/a5ed2fe0eedefa1649aa93ee74a0bafc8e628a10/Lib/_osx_support.py#L260
env.setdefault('ARCHFLAGS', '-arch x86_64')
return env
def build(options: BuildOptions) -> None:
temp_dir = Path(tempfile.mkdtemp(prefix='cibuildwheel'))
built_wheel_dir = temp_dir / 'built_wheel'
repaired_wheel_dir = temp_dir / 'repaired_wheel'
if options.before_all:
env = options.environment.as_dictionary(prev_environment=os.environ)
before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir)
call([before_all_prepared], shell=True, env=env)
python_configurations = get_python_configurations(options.build_selector)
for config in python_configurations:
if skip(config.identifier):
print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr)
continue
dependency_constraint_flags: Sequence[Union[str, PathLike]] = []
if options.dependency_constraints:
dependency_constraint_flags = [
'-c', options.dependency_constraints.get_for_python_version(config.version)
]
# if this version of python isn't installed, get it from python.org and install
python_package_identifier = 'org.python.Python.PythonFramework-%s' % config.version
if python_package_identifier not in installed_system_packages:
# download the pkg
call(['curl', '-L', '-o', '/tmp/Python.pkg', config.url])
# install
call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/'])
env = os.environ.copy()
env['PATH'] = os.pathsep.join([
'/Library/Frameworks/Python.framework/Versions/%s/bin' % config.version,
env['PATH'],
])
env = environment.as_dictionary(prev_environment=env)
python = 'python3' if config.version[0] == '3' else 'python2'
pip = 'pip3' if config.version[0] == '3' else 'pip2'
# check what version we're on
call(['which', python], env=env)
call([python, '--version'], env=env)
# install pip & wheel
call([python, get_pip_script, '--no-setuptools', '--no-wheel'], env=env)
call([pip, '--version'], env=env)
call([pip, 'install', '--upgrade', 'setuptools'], env=env)
call([pip, 'install', 'wheel'], env=env)
call([pip, 'install', 'delocate'], env=env)
# setup dirs
if os.path.exists('/tmp/built_wheel'):
shutil.rmtree('/tmp/built_wheel')
os.makedirs('/tmp/built_wheel')
if os.path.exists('/tmp/delocated_wheel'):
shutil.rmtree('/tmp/delocated_wheel')
os.makedirs('/tmp/delocated_wheel')
env = setup_python(config, dependency_constraint_flags, options.environment)
# run the before_build command
if before_build:
before_build_prepared = prepare_command(before_build, python=python, pip=pip, project=abs_project_dir)
if options.before_build:
before_build_prepared = prepare_command(options.before_build, project='.', package=options.package_dir)
call(before_build_prepared, env=env, shell=True)
# build the wheel
call([pip, 'wheel', abs_project_dir, '-w', '/tmp/built_wheel', '--no-deps'] + get_build_verbosity_extra_flags(build_verbosity), env=env)
built_wheel = glob('/tmp/built_wheel/*.whl')[0]
if built_wheel_dir.exists():
shutil.rmtree(built_wheel_dir)
built_wheel_dir.mkdir(parents=True)
if built_wheel.endswith('none-any.whl'):
# pure python wheel - just move
shutil.move(built_wheel, '/tmp/delocated_wheel')
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
# see https://github.com/joerick/cibuildwheel/pull/369
call([
'pip', 'wheel',
options.package_dir.resolve(),
'-w', built_wheel_dir,
'--no-deps',
*get_build_verbosity_extra_flags(options.build_verbosity)
], env=env)
built_wheel = next(built_wheel_dir.glob('*.whl'))
# repair the wheel
if repaired_wheel_dir.exists():
shutil.rmtree(repaired_wheel_dir)
repaired_wheel_dir.mkdir(parents=True)
if built_wheel.name.endswith('none-any.whl') or not options.repair_command:
# pure Python wheel or empty repair command
shutil.move(str(built_wheel), repaired_wheel_dir)
else:
# list the dependencies
call(['delocate-listdeps', built_wheel], env=env)
# rebuild the wheel with shared libraries included and place in output dir
call(['delocate-wheel', '-w', '/tmp/delocated_wheel', built_wheel], env=env)
delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0]
repair_command_prepared = prepare_command(options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir)
call(repair_command_prepared, env=env, shell=True)
repaired_wheel = next(repaired_wheel_dir.glob('*.whl'))
# install the wheel
call([pip, 'install', delocated_wheel], env=env)
if options.test_command:
# set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time.
call(['pip', 'install', 'virtualenv', *dependency_constraint_flags], env=env)
venv_dir = Path(tempfile.mkdtemp())
# Use --no-download to ensure determinism by using seed libraries
# built into virtualenv
call(['python', '-m', 'virtualenv', '--no-download', venv_dir], env=env)
virtualenv_env = env.copy()
virtualenv_env['PATH'] = os.pathsep.join([
str(venv_dir / 'bin'),
virtualenv_env['PATH'],
])
# check that we are using the Python from the virtual environment
call(['which', 'python'], env=virtualenv_env)
if options.before_test:
before_test_prepared = prepare_command(options.before_test, project='.', package=options.package_dir)
call(before_test_prepared, env=virtualenv_env, shell=True)
# install the wheel
call(['pip', 'install', str(repaired_wheel) + options.test_extras], env=virtualenv_env)
# test the wheel
if options.test_requires:
call(['pip', 'install'] + options.test_requires, env=virtualenv_env)
# test the wheel
if test_requires:
call([pip, 'install'] + test_requires, env=env)
if test_command:
# run the tests from $HOME, with an absolute path in the command
# (this ensures that Python runs the tests against the installed wheel
# and not the repo code)
test_command_prepared = prepare_command(test_command, python=python, pip=pip, project=abs_project_dir)
call(shlex.split(test_command_prepared), cwd=os.environ['HOME'], env=env)
test_command_prepared = prepare_command(
options.test_command,
project=Path('.').resolve(),
package=options.package_dir.resolve()
)
call(test_command_prepared, cwd=os.environ['HOME'], env=virtualenv_env, shell=True)
# we're all done here; move it to output
shutil.move(delocated_wheel, output_dir)
# clean up
shutil.rmtree(venv_dir)
# we're all done here; move it to output (overwrite existing)
shutil.move(str(repaired_wheel), options.output_dir)
@@ -0,0 +1,26 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# bin/update_constraints.py
#
appdirs==1.4.4 # via virtualenv
configparser==4.0.2 # via importlib-metadata
contextlib2==0.6.0.post1 # via importlib-metadata, importlib-resources, virtualenv
delocate==0.8.0 # via -r cibuildwheel/resources/constraints.in
distlib==0.3.0 # via virtualenv
filelock==3.0.12 # via virtualenv
importlib-metadata==1.6.0 # via importlib-resources, virtualenv
importlib-resources==1.5.0 # via virtualenv
pathlib2==2.3.5 # via importlib-metadata, importlib-resources, virtualenv
scandir==1.10.0 # via pathlib2
singledispatch==3.4.0.3 # via importlib-resources
six==1.15.0 # via pathlib2, virtualenv
typing==3.7.4.1 # via importlib-resources
virtualenv==20.0.21 # via -r cibuildwheel/resources/constraints.in
wheel==0.34.2 # via -r cibuildwheel/resources/constraints.in, delocate
zipp==1.2.0 # via importlib-metadata, importlib-resources
# The following packages are considered to be unsafe in a requirements file:
pip==20.1.1 # via -r cibuildwheel/resources/constraints.in
setuptools==44.1.0 # via -r cibuildwheel/resources/constraints.in
@@ -0,0 +1,20 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# bin/update_constraints.py
#
appdirs==1.4.4 # via virtualenv
delocate==0.8.0 # via -r cibuildwheel/resources/constraints.in
distlib==0.3.0 # via virtualenv
filelock==3.0.12 # via virtualenv
importlib-metadata==1.6.0 # via importlib-resources, virtualenv
importlib-resources==1.5.0 # via virtualenv
six==1.15.0 # via virtualenv
virtualenv==20.0.21 # via -r cibuildwheel/resources/constraints.in
wheel==0.34.2 # via -r cibuildwheel/resources/constraints.in, delocate
zipp==1.2.0 # via importlib-metadata, importlib-resources
# The following packages are considered to be unsafe in a requirements file:
pip==20.1.1 # via -r cibuildwheel/resources/constraints.in
setuptools==46.4.0 # via -r cibuildwheel/resources/constraints.in
@@ -0,0 +1,20 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# bin/update_constraints.py
#
appdirs==1.4.4 # via virtualenv
delocate==0.8.0 # via -r cibuildwheel/resources/constraints.in
distlib==0.3.0 # via virtualenv
filelock==3.0.12 # via virtualenv
importlib-metadata==1.6.0 # via importlib-resources, virtualenv
importlib-resources==1.5.0 # via virtualenv
six==1.15.0 # via virtualenv
virtualenv==20.0.21 # via -r cibuildwheel/resources/constraints.in
wheel==0.34.2 # via -r cibuildwheel/resources/constraints.in, delocate
zipp==3.1.0 # via importlib-metadata, importlib-resources
# The following packages are considered to be unsafe in a requirements file:
pip==20.1.1 # via -r cibuildwheel/resources/constraints.in
setuptools==46.4.0 # via -r cibuildwheel/resources/constraints.in
+5
View File
@@ -0,0 +1,5 @@
pip
setuptools
wheel
delocate
virtualenv
+19
View File
@@ -0,0 +1,19 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# bin/update_constraints.py
#
appdirs==1.4.4 # via virtualenv
delocate==0.8.0 # via -r cibuildwheel/resources/constraints.in
distlib==0.3.0 # via virtualenv
filelock==3.0.12 # via virtualenv
importlib-metadata==1.6.0 # via virtualenv
six==1.15.0 # via virtualenv
virtualenv==20.0.21 # via -r cibuildwheel/resources/constraints.in
wheel==0.34.2 # via -r cibuildwheel/resources/constraints.in, delocate
zipp==3.1.0 # via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
pip==20.1.1 # via -r cibuildwheel/resources/constraints.in
setuptools==46.4.0 # via -r cibuildwheel/resources/constraints.in
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,22 @@
[x86_64]
manylinux1 = quay.io/pypa/manylinux1_x86_64:2020-05-25-b56702d
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2020-05-20-c7bbd11
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2020-05-17-2f8ac3b
[i686]
manylinux1 = quay.io/pypa/manylinux1_i686:2020-05-25-b56702d
manylinux2010 = quay.io/pypa/manylinux2010_i686:2020-05-20-c7bbd11
manylinux2014 = quay.io/pypa/manylinux2014_i686:2020-05-17-2f8ac3b
[pypy_x86_64]
manylinux2010 = pypywheels/manylinux2010-pypy_x86_64:2020-04-25-eb2cdff
[aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2020-05-17-2f8ac3b
[ppc64le]
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2020-05-17-2f8ac3b
[s390x]
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2020-05-17-2f8ac3b
+98 -20
View File
@@ -1,19 +1,25 @@
import os
import urllib.request
from fnmatch import fnmatch
from pathlib import Path
from time import sleep
from typing import Dict, List, NamedTuple, Optional, Union
from .environment import ParsedEnvironment
def prepare_command(command, python, pip, project):
def prepare_command(command: str, **kwargs: Union[str, os.PathLike]) -> str:
'''
Preprocesses a command by expanding variables like {python} or {pip}.
Preprocesses a command by expanding variables like {python}.
For example, used for the before_build option, where the user would
like to run a command like `python setup.py test`. If the command should run on
Python 3, the user could write `{python} setup.py test`. This command would expand
it out to python2 or python3 as appropriate.
For example, used in the test_command option to specify the path to the
project's root.
'''
return command.format(python=python, pip=pip, project=project)
return command.format(python='python', pip='pip', **kwargs)
def get_build_verbosity_extra_flags(level):
def get_build_verbosity_extra_flags(level: int) -> List[str]:
if level > 0:
return ['-' + level * 'v']
elif level < 0:
@@ -22,29 +28,101 @@ def get_build_verbosity_extra_flags(level):
return []
class BuildSkipper(object):
def __init__(self, skip_config):
self.patterns = skip_config.split()
class BuildSelector:
def __init__(self, build_config: str, skip_config: str):
self.build_patterns = build_config.split()
self.skip_patterns = skip_config.split()
def __call__(self, build_id):
return any(fnmatch(build_id, pattern) for pattern in self.patterns)
def __call__(self, build_id: str) -> bool:
def match_any(patterns: List[str]) -> bool:
return any(fnmatch(build_id, pattern) for pattern in patterns)
return match_any(self.build_patterns) and not match_any(self.skip_patterns)
def __repr__(self):
return 'BuildSkipper(%r)' % ' '.join(self.patterns)
def __repr__(self) -> str:
return f'BuildSelector({" ".join(self.build_patterns)!r} - {" ".join(self.skip_patterns)!r})'
# Taken from https://stackoverflow.com/a/107717
class Unbuffered(object):
def __init__(self, stream):
class Unbuffered:
def __init__(self, stream): # type: ignore
self.stream = stream
def write(self, data):
def write(self, data): # type: ignore
self.stream.write(data)
self.stream.flush()
def writelines(self, datas):
def writelines(self, datas): # type: ignore
self.stream.writelines(datas)
self.stream.flush()
def __getattr__(self, attr):
def __getattr__(self, attr): # type: ignore
return getattr(self.stream, attr)
def download(url: str, dest: Path) -> None:
print(f'+ Download {url} to {dest}')
dest_dir = dest.parent
if not dest_dir.exists():
dest_dir.mkdir(parents=True)
repeat_num = 3
for i in range(repeat_num):
try:
response = urllib.request.urlopen(url)
except Exception:
if i == repeat_num - 1:
raise
sleep(3)
continue
break
try:
dest.write_bytes(response.read())
finally:
response.close()
class DependencyConstraints:
def __init__(self, base_file_path: Path):
assert base_file_path.exists()
self.base_file_path = base_file_path.resolve()
@staticmethod
def with_defaults() -> 'DependencyConstraints':
return DependencyConstraints(
base_file_path=resources_dir / 'constraints.txt'
)
def get_for_python_version(self, version: str) -> Path:
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
specific_stem = self.base_file_path.stem + f'-python{version_parts[0]}{version_parts[1]}'
specific_name = specific_stem + self.base_file_path.suffix
specific_file_path = self.base_file_path.with_name(specific_name)
if specific_file_path.exists():
return specific_file_path
else:
return self.base_file_path
class BuildOptions(NamedTuple):
package_dir: Path
output_dir: Path
build_selector: BuildSelector
environment: ParsedEnvironment
before_all: str
before_build: Optional[str]
repair_command: str
manylinux_images: Optional[Dict[str, str]]
dependency_constraints: Optional[DependencyConstraints]
test_command: Optional[str]
before_test: Optional[str]
test_requires: List[str]
test_extras: str
build_verbosity: int
resources_dir = Path(__file__).resolve().parent / 'resources'
get_pip_script = resources_dir / 'get-pip.py'
+273 -81
View File
@@ -1,103 +1,295 @@
from __future__ import print_function
import os, tempfile, subprocess, sys, shutil
try:
from urllib2 import urlopen
except ImportError:
from urllib.request import urlopen
from collections import namedtuple
from glob import glob
import os
import shutil
import subprocess
import sys
import tempfile
from os import PathLike
from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Sequence, Union
from zipfile import ZipFile
import toml
from .util import prepare_command, get_build_verbosity_extra_flags, Unbuffered
from .environment import ParsedEnvironment
from .util import (BuildOptions, BuildSelector, download,
get_build_verbosity_extra_flags, get_pip_script,
prepare_command)
IS_RUNNING_ON_AZURE = Path('C:\\hostedtoolcache').exists()
IS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows'
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, 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 = Unbuffered(sys.stdout)
def call(args: Sequence[Union[str, PathLike]], env: Optional[Dict[str, str]] = None,
cwd: Optional[str] = None) -> None:
print('+ ' + ' '.join(str(a) for a in args))
# we use shell=True here, even though we don't need a shell due to a bug
# https://bugs.python.org/issue8557
subprocess.check_call([str(a) for a in args], env=env, cwd=cwd, shell=True)
# 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')
if not os.path.exists(run_with_env):
with open(run_with_env, 'wb') as f:
request = urlopen('https://github.com/ogrisel/python-appveyor-demo/raw/09a1c8672e5015a74d8f69d07add6ee803c176ec/appveyor/run_with_env.cmd')
f.write(request.read())
def shell(args, env=None, cwd=None):
# print the command executing for the logs
print('+ ' + ' '.join(args))
args = ['cmd', '/E:ON', '/V:ON', '/C', run_with_env] + args
return subprocess.check_call(' '.join(args), env=env, cwd=cwd)
def shell(command: str, env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None) -> None:
print(f'+ {command}')
subprocess.check_call(command, env=env, cwd=cwd, shell=True)
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path'])
def get_nuget_args(version: str, arch: str) -> List[str]:
python_name = 'python' if version[0] == '3' else 'python2'
if arch == '32':
python_name = python_name + 'x86'
return [python_name, '-Version', version, '-OutputDirectory', 'C:\\cibw\\python']
class PythonConfiguration(NamedTuple):
version: str
arch: str
identifier: str
url: Optional[str]
def get_python_configurations(build_selector: BuildSelector) -> List[PythonConfiguration]:
python_configurations = [
PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\Python27'),
PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\Python27-x64'),
PythonConfiguration(version='3.3.x', arch="32", identifier='cp33-win32', path='C:\Python33'),
PythonConfiguration(version='3.3.x', arch="64", identifier='cp33-win_amd64', path='C:\Python33-x64'),
PythonConfiguration(version='3.4.x', arch="32", identifier='cp34-win32', path='C:\Python34'),
PythonConfiguration(version='3.4.x', arch="64", identifier='cp34-win_amd64', path='C:\Python34-x64'),
PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\Python35'),
PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\Python35-x64'),
PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\Python36'),
PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\Python36-x64'),
# CPython
PythonConfiguration(version='2.7.18', arch='32', identifier='cp27-win32', url=None),
PythonConfiguration(version='2.7.18', arch='64', identifier='cp27-win_amd64', url=None),
PythonConfiguration(version='3.5.4', arch='32', identifier='cp35-win32', url=None),
PythonConfiguration(version='3.5.4', arch='64', identifier='cp35-win_amd64', url=None),
PythonConfiguration(version='3.6.8', arch='32', identifier='cp36-win32', url=None),
PythonConfiguration(version='3.6.8', arch='64', identifier='cp36-win_amd64', url=None),
PythonConfiguration(version='3.7.8', arch='32', identifier='cp37-win32', url=None),
PythonConfiguration(version='3.7.8', arch='64', identifier='cp37-win_amd64', url=None),
PythonConfiguration(version='3.8.4', arch='32', identifier='cp38-win32', url=None),
PythonConfiguration(version='3.8.4', arch='64', identifier='cp38-win_amd64', url=None),
# PyPy
PythonConfiguration(version='2.7', arch='32', identifier='pp27-win32', url='https://downloads.python.org/pypy/pypy2.7-v7.3.1-win32.zip'),
PythonConfiguration(version='3.6', arch='32', identifier='pp36-win32', url='https://downloads.python.org/pypy/pypy3.6-v7.3.1-win32.zip'),
]
abs_project_dir = os.path.abspath(project_dir)
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
if IS_RUNNING_ON_TRAVIS:
# cannot install VCForPython27.msi which is needed for compiling C software
# 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
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
return python_configurations
def extract_zip(zip_src: Path, dest: Path) -> None:
with ZipFile(zip_src) as zip:
zip.extractall(dest)
def install_cpython(version: str, arch: str, nuget: Path) -> Path:
nuget_args = get_nuget_args(version, arch)
installation_path = Path(nuget_args[-1]) / (nuget_args[0] + '.' + version) / 'tools'
call([nuget, 'install', *nuget_args])
return installation_path
def install_pypy(version: str, arch: str, url: str) -> Path:
assert arch == '32'
# Inside the PyPy zip file is a directory with the same name
zip_filename = url.rsplit('/', 1)[-1]
extension = ".zip"
assert zip_filename.endswith(extension)
installation_path = Path('C:\\cibw') / zip_filename[:-len(extension)]
if not installation_path.exists():
pypy_zip = Path('C:\\cibw') / zip_filename
download(url, pypy_zip)
# Extract to the parent directory because the zip file still contains a directory
extract_zip(pypy_zip, installation_path.parent)
pypy_exe = 'pypy3.exe' if version[0] == '3' else 'pypy.exe'
(installation_path / 'python.exe').symlink_to(installation_path / pypy_exe)
return installation_path
def setup_python(python_configuration: PythonConfiguration, dependency_constraint_flags: Sequence[Union[str, PathLike]], environment: ParsedEnvironment) -> Dict[str, str]:
nuget = Path('C:\\cibw\\nuget.exe')
if not nuget.exists():
download('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', nuget)
if python_configuration.identifier.startswith('cp'):
installation_path = install_cpython(python_configuration.version, python_configuration.arch, nuget)
elif python_configuration.identifier.startswith('pp'):
assert python_configuration.url is not None
installation_path = install_pypy(python_configuration.version, python_configuration.arch, python_configuration.url)
else:
raise ValueError("Unknown Python implementation")
assert (installation_path / 'python.exe').exists()
# set up PATH and environment variables for run_with_env
env = os.environ.copy()
env['PYTHON_VERSION'] = python_configuration.version
env['PYTHON_ARCH'] = python_configuration.arch
env['PATH'] = os.pathsep.join([
str(installation_path),
str(installation_path / 'Scripts'),
env['PATH']
])
# update env with results from CIBW_ENVIRONMENT
env = environment.as_dictionary(prev_environment=env)
# for the logs - check we're running the right version of python
call(['where', 'python'], env=env)
call(['python', '--version'], env=env)
call(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)"'], env=env)
where_python = subprocess.check_output(['where', 'python'], env=env, universal_newlines=True).splitlines()[0].strip()
if where_python != str(installation_path / 'python.exe'):
print("cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.", file=sys.stderr)
exit(1)
# make sure pip is installed
if not (installation_path / 'Scripts' / 'pip.exe').exists():
call(['python', get_pip_script, *dependency_constraint_flags], env=env, cwd="C:\\cibw")
assert (installation_path / 'Scripts' / 'pip.exe').exists()
where_pip = subprocess.check_output(['where', 'pip'], env=env, universal_newlines=True).splitlines()[0].strip()
if where_pip.strip() != str(installation_path / 'Scripts' / 'pip.exe'):
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
exit(1)
# prepare the Python environment
call(['python', '-m', 'pip', 'install', '--upgrade', 'pip', *dependency_constraint_flags], env=env)
call(['pip', '--version'], env=env)
call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', *dependency_constraint_flags], env=env)
return env
def pep_518_cp35_workaround(package_dir: Path, env: Dict[str, str]) -> None:
"""
Python 3.5 PEP 518 hack (see https://github.com/pypa/pip/issues/8392#issuecomment-639563494)
Basically, nuget's Python is an embedded Python distribution, which is not supported by pip.
Before version 3.6, there was no way to disable the "embedded" behavior, including the ignoring
of environment variables, including the ones pip uses to setup PEP 518 builds.
The fix here is as suggested in that issue; we manually setup the PEP 518 requirements. Since we
are in a fresh environment (except for pinned cibuildweel dependencies), the build is already
mostly "isolated".
"""
pyproject_path = package_dir / 'pyproject.toml'
if pyproject_path.exists():
data = toml.load(pyproject_path)
requirements = (
data['build-system'].get('requires', [])
if 'build-system' in data
else []
)
if requirements:
shell(['pip', 'install'] + requirements, env=env)
def build(options: BuildOptions) -> None:
temp_dir = Path(tempfile.mkdtemp(prefix='cibuildwheel'))
built_wheel_dir = temp_dir / 'built_wheel'
repaired_wheel_dir = temp_dir / 'repaired_wheel'
# install nuget as best way to provide python
nuget = Path('C:\\cibw\\nuget.exe')
download('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', nuget)
if options.before_all:
env = options.environment.as_dictionary(prev_environment=os.environ)
before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir)
shell(before_all_prepared, env=env)
python_configurations = get_python_configurations(options.build_selector)
for config in python_configurations:
if skip(config.identifier):
print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr)
continue
dependency_constraint_flags: Sequence[Union[str, PathLike]] = []
if options.dependency_constraints:
dependency_constraint_flags = [
'-c', options.dependency_constraints.get_for_python_version(config.version)
]
# setup dirs
if os.path.exists(built_wheel_dir):
shutil.rmtree(built_wheel_dir)
os.makedirs(built_wheel_dir)
env = os.environ.copy()
# set up environment variables for run_with_env
env['PYTHON_VERSION'] = config.version
env['PYTHON_ARCH'] = config.arch
env['PATH'] = os.pathsep.join([
config.path,
os.path.join(config.path, 'Scripts'),
env['PATH']
])
env = environment.as_dictionary(prev_environment=env)
# for the logs - check we're running the right version of python
shell(['python', '--version'], env=env)
shell(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)\"'], env=env)
# prepare the Python environment
shell(['python', '-m', 'pip', 'install', '--upgrade', 'pip'],
env=env)
shell(['pip', 'install', '--upgrade', 'setuptools'], env=env)
shell(['pip', 'install', 'wheel'], env=env)
# install Python
env = setup_python(config, dependency_constraint_flags, options.environment)
# run the before_build command
if before_build:
before_build_prepared = prepare_command(before_build, python='python', pip='pip', project=abs_project_dir)
shell([before_build_prepared], env=env)
if options.before_build:
before_build_prepared = prepare_command(options.before_build, project='.', package=options.package_dir)
shell(before_build_prepared, env=env)
# activate the PEP 518 patch if on Windows Python 3.5
# (will only have an effect if PEP 517 builds are used):
if config.version.startswith('3.5'):
pep_518_cp35_workaround(options.package_dir, env)
# build the wheel
shell(['pip', 'wheel', abs_project_dir, '-w', built_wheel_dir, '--no-deps'] + get_build_verbosity_extra_flags(build_verbosity), env=env)
built_wheel = glob(built_wheel_dir+'/*.whl')[0]
if built_wheel_dir.exists():
shutil.rmtree(built_wheel_dir)
built_wheel_dir.mkdir(parents=True)
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
# see https://github.com/joerick/cibuildwheel/pull/369
call([
'pip', 'wheel',
options.package_dir.resolve(),
'-w', built_wheel_dir,
'--no-deps',
*get_build_verbosity_extra_flags(options.build_verbosity)
], env=env)
# install the wheel
shell(['pip', 'install', built_wheel], env=env)
built_wheel = next(built_wheel_dir.glob('*.whl'))
# repair the wheel
if repaired_wheel_dir.exists():
shutil.rmtree(repaired_wheel_dir)
repaired_wheel_dir.mkdir(parents=True)
if built_wheel.name.endswith('none-any.whl') or not options.repair_command:
# pure Python wheel or empty repair command
shutil.move(str(built_wheel), repaired_wheel_dir)
else:
repair_command_prepared = prepare_command(options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir)
shell(repair_command_prepared, env=env)
repaired_wheel = next(repaired_wheel_dir.glob('*.whl'))
if options.test_command:
# set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time.
call(['pip', 'install', 'virtualenv', *dependency_constraint_flags], env=env)
venv_dir = Path(tempfile.mkdtemp())
# Use --no-download to ensure determinism by using seed libraries
# built into virtualenv
call(['python', '-m', 'virtualenv', '--no-download', venv_dir], env=env)
virtualenv_env = env.copy()
virtualenv_env['PATH'] = os.pathsep.join([
str(venv_dir / 'Scripts'),
virtualenv_env['PATH'],
])
# check that we are using the Python from the virtual environment
call(['which', 'python'], env=virtualenv_env)
if options.before_test:
before_test_prepared = prepare_command(
options.before_test,
project='.',
package=options.package_dir
)
shell(before_test_prepared, env=virtualenv_env)
# install the wheel
call(['pip', 'install', str(repaired_wheel) + options.test_extras], env=virtualenv_env)
# test the wheel
if options.test_requires:
call(['pip', 'install'] + options.test_requires, env=virtualenv_env)
# test the wheel
if test_requires:
shell(['pip', 'install'] + test_requires, env=env)
if test_command:
# run the tests from c:\, with an absolute path in the command
# (this ensures that Python runs the tests against the installed wheel
# and not the repo code)
test_command_prepared = prepare_command(test_command, python='python', pip='pip', project=abs_project_dir)
shell([test_command_prepared], cwd='c:\\', env=env)
test_command_prepared = prepare_command(
options.test_command,
project=Path('.').resolve(),
package=options.package_dir.resolve()
)
shell(test_command_prepared, cwd='c:\\', env=virtualenv_env)
# we're all done here; move it to output
shutil.move(built_wheel, output_dir)
# clean up
shutil.rmtree(venv_dir)
# we're all done here; move it to output (remove if already exists)
shutil.move(str(repaired_wheel), options.output_dir)
+30
View File
@@ -0,0 +1,30 @@
---
title: Contributing
---
Wheel-building can be pretty complex. I expect users to find many edge-cases - please help the rest of the community out by documenting these, adding features to support them, and reporting bugs.
I plan to be pretty liberal in accepting pull requests, as long as they align with the design goals below.
`cibuildwheel` is indie open source. We're not paid to work on this.
Design Goals
------------
- `cibuildwheel` should wrap the complexity of wheel building.
- The user interface to `cibuildwheel` is the build script (e.g. `.travis.yml`). Feature additions should not increase the complexity of this script.
- Options should be environment variables (these lend themselves better to YML config files). They should be prefixed with `CIBW_`.
- Options should be generalise to all platforms. If platform-specific options are required, they should be namespaced e.g. `CIBW_TEST_COMMAND_MACOS`
Other notes:
- The platforms are very similar, until they're not. I'd rather have straight-forward code than totally DRY code, so let's keep airy platfrom abstractions to a minimum.
- I might want to break the options into a shared config file one day, so that config is more easily shared. That has motivated some of the design decisions.
### cibuildwheel's relationship with build errors
cibuildwheel doesn't really do anything itself - it's always deferring to other tools (pip, wheel, auditwheel, delocate, docker). Without cibuildwheel, the process is really fragmented. Different tools, across different OSs need to be stitched together in just the right way to make it work.
We're not responsible for errors in those tools, for fixing errors/crashes there. But cibuildwheel's job is providing users with an 'integrated' user experience across those tools. We provide an abstraction. The user says 'build me some wheels', not 'open the docker container, build a wheel with pip, fix up the symbols with auditwheel' etc. However, errors have a habit of breaking abstractions. And this is where users get confused, because the mechanism of cibuildwheel is laid bare, and they must understand a little bit how it works to debug.
So, if we can, I'd like to improve the experience on errors as well. In [this](https://github.com/joerick/cibuildwheel/issues/139) case, it takes a bit of knowledge to understand that the linux builds are happening in a totally different OS via docker, that the linked symbols won't match, that auditwheel will fail because of this. A problem with how the tools fit together, instead of the tools themselves.
+69
View File
@@ -0,0 +1,69 @@
---
title: Modern C++ standards
---
Building Python wheels with modern C++ standards (C++11 and later) requires a few tricks.
## Python 2.7 and C++17
The Python 2.7 header files use the `register` keyword, which is [reserved and unused from C+17 onwards](https://en.cppreference.com/w/cpp/keyword/register). Compiling a wheel for Python 2.7 with the C++17 standard is still possible to allow usage of `register` using proper flag `-Wno-register` for gcc/clang and `/wd5033` for MSVC.
## manylinux1 and C++14
The default `manylinux1` image (based on CentOS 5) contains a version of GCC and libstdc++ that only supports C++11 and earlier standards. There are however ways to compile wheels with the C++14 standard (and later): https://github.com/pypa/manylinux/issues/118
`manylinux2010` and `manylinux2014` are newer and support all C++ standards (up to C++17).
## macOS and deployment target versions
OS X/macOS allows you to specify a so-called "deployment target" version that will ensure backwards compatibility with older versions of macOS. One way to do this is by setting the `MACOSX_DEPLOYMENT_TARGET` environment variable.
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, `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, Xcode 9.3+ is needed, requiring at least macOS 10.13 on the build machine. To use C++17 library features and link against the C++ runtime library, set `MACOSX_DEPLOYMENT_TARGET` to `"10.13"` or `"10.14"` (or higher) - 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.
However, if only C++17 compiler and standard template library (STL) features are used (not needing a C++17 runtime) it might be possible to set `MACOSX_DEPLOYMENT_TARGET` to a lower value, such as `"10.9"`. To find out if this is the case, try compiling and running with a lower `MACOSX_DEPLOYMENT_TARGET`: if C++17 features are used that require a more recent deployment target, building the wheel should fail.
For more details see https://en.cppreference.com/w/cpp/compiler_support, https://en.wikipedia.org/wiki/Xcode, and https://xcodereleases.com/: Xcode 10 needs macOS 10.13 and Xcode 11 needs macOS 10.14.
## Windows and Python 2.7
Visual C++ for Python 2.7 does not support modern C++ standards (i.e., C++11 and later). When building on Appveyor, you will need to either use the "Visual Studio 2017" or "Visual Studio 2019" image, but Python 2.7 is not supported on these images - skip it by setting `CIBW_SKIP=cp27-win*`.
There is an optional workaround for this, though: the pybind11 project argues and shows that it is [possible to compile Python 2.7 extension with a newer compiler](https://pybind11.readthedocs.io/en/stable/faq.html#working-with-ancient-visual-studio-2008-builds-on-windows) and has an example project showing how to do this: https://github.com/pybind/python_example. The main catch is that a user might need to install [a newer "Microsoft Visual C++ Redistributable"](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads), since the newer C++ standard library's binaries are not included by default with the Python 2.7 installation.
Forcing `distutils` or `setuptools` to use a more recent version of MSVC that supports modern C++ can be done in the following way:
1. Set the environment variables `DISTUTILS_USE_SDK=1` and `MSSdk=1`. These two environment variables will tell `distutils`/`setuptools` to not search and set up a build environment that uses Visual C++ for Python 2.7 (aka. MSVC 9).
2. Set up the build Visual Studio build environment you want to use, making sure that e.g. `PATH` contains `cl`, `link`, etc.
- Usually, this can be done through `vcvarsall.bat x86` or `vcvarsall.bat x64`. The exact location of this file depends on the installation, but the default path for VS 2019 Community (e.g. used in AppVeyor's `Visual Studio 2019` image) is `C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat`. **Note**: `vcvarsall.bat` changes the environment variables, so this cannot be run in a subprocess/subshell and consequently running `vsvarsall.bat` in `CIBW_BEFORE_BUILD` does not have any effect.
- In Azure Pipelines, [a `VSBuild` task is available](https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/visual-studio-build)
- In GitHub Actions, the default shell is powershell, so you'll need to use `shell: cmd` to source a `.bat` file, and the directory is `"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"`. Or you can use an action, such as the [`ilammy/msvc-dev-cmd@v1`](https://github.com/ilammy/msvc-dev-cmd) action to setup the environment (see example below).
3. Next, call `cibuildwheel`. Unfortunately, MSVC has separate toolchains for compiling 32-bit and 64-bit, so you will need to run `cibuildwheel` twice: once with `CIBW_BUILD=*-win32` after setting up the `x86` build environment, and once with `CIBW_BUILD=*-win_amd64` in a `x64` environment (see previous step).
**GitHub Action example with ilammy/msvc-dev-cmd**:
```yaml
- uses: ilammy/msvc-dev-cmd@v1
- name: Build 64-bit wheel
run: python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_BUILD: cp27-win_amd64
DISTUTILS_USE_SDK: 1
MSSdk: 1
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x86
- name: Build 32-bit wheel
run: python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_BUILD: cp27-win32
DISTUTILS_USE_SDK: 1
MSSdk: 1
```
+36
View File
@@ -0,0 +1,36 @@
---
title: Delivering to PyPI
---
After you've built your wheels, you'll probably want to deliver them to PyPI.
### Manual method
On your development machine, do the following...
```bash
# Clear out your 'dist' folder.
rm -rf dist
# Make a source distribution
python setup.py sdist
# 🏃🏻
# Go and download your wheel files from wherever you put them. e.g. your CI
# provider can be configured to store them for you. Put them all into the
# 'dist' folder.
# Upload using 'twine' (you may need to 'pip install twine')
twine upload dist/*
```
### Semi-automatic method using wheelhouse-uploader
Obviously, manual steps are for chumps, so we can automate this a little by using [wheelhouse-uploader](https://github.com/ogrisel/wheelhouse-uploader).
> Quick note from me - using S3 as a storage didn't work due to a [bug](https://issues.apache.org/jira/browse/LIBCLOUD-792) in libcloud. Feel free to use my fork of that package that fixes the bug `pip install https://github.com/joerick/libcloud/archive/v1.5.0-s3fix.zip`
### Automatic method
If you don't need much control over the release of a package, you can set up cibuildwheel to deliver the wheels straight to PyPI. This doesn't require anycloud storage to work - you just need to bump the version and tag it.
[`examples/travis-ci-deploy.yml`](https://github.com/joerick/cibuildwheel/blob/master/examples/travis-ci-deploy.yml) and [`examples/github-deploy.yml`](https://github.com/joerick/cibuildwheel/blob/master/examples/github-deploy.yml) are example configurations that automatocially upload wheels to PyPI. Also check out [this example repo](https://github.com/joerick/cibuildwheel-autopypi-example) for more detailed instructions on how to set this up.
+88
View File
@@ -0,0 +1,88 @@
/* Global styles */
p {
margin-bottom: 12px;
}
code {
font-size: 85%;
background-color: rgba(27,31,35,.05);
border-radius: 3px;
padding: .2em .4em;
color: inherit;
border: none;
margin: 0 1px;
}
code, pre, tt {
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
}
.hljs {
padding: 1em;
background-color: #f6f8fa;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 2em;
border-bottom: 1px solid #e1e4e5;
margin-bottom: 0.8em;
padding-bottom: 0.2em;
}
.rst-content blockquote {
margin-bottom: 14px;
}
.rst-content th {
white-space: normal;
}
/*
Code block filename style
Use by putting a quote before a code block e.g.
> filename.txt
```
code here
```
JS adds the relevant classes to make the following selectors work.
*/
.rst-content .code-block-filename {
margin: 0;
padding: 2px 1em;
background-color: #eff1f3;
font-size: 85%;
font-weight: bold;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border-bottom: 1px solid #e6e8e9;
color: #444;
}
.rst-content .code-block-filename * {
font-size: inherit;
}
.rst-content .code-block-filename :last-child {
margin-bottom: 0;
}
.code-block-filename + pre {
margin-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.code-block-filename + pre code {
padding-top: 0.9em;
}
/* import font awesome 4 for icons */
@import url(https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css);
+4
View File
@@ -0,0 +1,4 @@
$('.rst-content pre')
.prev('blockquote')
.addClass('code-block-filename');
+63
View File
@@ -0,0 +1,63 @@
---
title: Tips and tricks
---
### Troubleshooting
If your wheel didn't compile, check the list below for some debugging tips.
- A mistake in your config. To quickly test your config without doing a git push and waiting for your code to build on CI, you can test the Linux build in a Docker container. On Mac or Linux, with Docker running, try `cibuildwheel --platform linux`. You'll have to bring your config into the current environment first.
- Missing dependency. You might need to install something on the build machine. You can do this in `.travis.yml`, `appveyor.yml`, or `.circleci/config.yml`, with apt-get, brew or choco. Given how the Linux build works, you'll need to use the [`CIBW_BEFORE_BUILD`](options.md#before-build) option.
- Windows: missing C feature. The Windows C compiler doesn't support C language features invented after 1990, so you'll have to backport your C code to C90. For me, this mostly involved putting my variable declarations at the top of the function like an animal.
- MacOS: calling cibuildwheel from a python3 script and getting a `ModuleNotFoundError`? Due to a [bug](https://bugs.python.org/issue22490) in CPython, you'll need to [unset the `__PYVENV_LAUNCHER__` variable](https://github.com/joerick/cibuildwheel/issues/133#issuecomment-478288597) before activating a venv.
### Linux builds on Docker
Linux wheels are built in the [`manylinux` docker images](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 571](https://www.python.org/dev/peps/pep-0571/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
- Programs and libraries cannot be installed on the Travis CI Ubuntu host with `apt-get`, but can be installed inside of the Docker image using `yum` or manually. The same goes for environment variables that are potentially needed to customize the wheel building. `cibuildwheel` supports this by providing the `CIBW_ENVIRONMENT` and `CIBW_BEFORE_BUILD` options to setup the build environment inside the running Docker image. See [the options docs](options.md#build-environment) for details on these options.
- The project directory is mounted in the running Docker instance as `/project`, the output directory for the wheels as `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system. Note that this is not available on CircleCI due to their Docker policies.
- Alternative dockers images can be specified with the `CIBW_MANYLINUX_X86_64_IMAGE`, `CIBW_MANYLINUX_I686_IMAGE`, and `CIBW_MANYLINUX_PYPY_X86_64_IMAGE` options to allow for a custom, preconfigured build environment for the Linux builds. See [options](options.md#manylinux-image) for more details.
### Building packages with optional C extensions
`cibuildwheel` defines the environment variable `CIBUILDWHEEL` to the value `1` allowing projects for which the C extension is optional to make it mandatory when building wheels.
An easy way to do it in Python 3 is through the `optional` named argument of `Extension` constructor in your `setup.py`:
```python
myextension = Extension(
"myextension",
["myextension.c"],
optional=os.environ.get('CIBUILDWHEEL', '0') != '1',
)
```
### 'No module named XYZ' errors after running cibuildwheel on macOS
`cibuildwheel` on Mac installs the distributions from Python.org system-wide during its operation. This is necessary, but it can cause some confusing errors after cibuildwheel has finished.
Consider the build script:
```bash
python3 -m pip install twine cibuildwheel
python3 -m cibuildwheel --output-dir wheelhouse
python3 -m twine upload wheelhouse/*.whl
# error: no module named 'twine'
```
This doesn't work because while `cibuildwheel` was running, it installed a few new versions of 'python3', so the `python3` run on line 3 isn't the same as the `python3` that ran on line 1.
Solutions to this vary, but the simplest is to install tools immediately before they're used:
```bash
python3 -m pip install cibuildwheel
python3 -m cibuildwheel --output-dir wheelhouse
python3 -m pip install twine
python3 -m twine upload wheelhouse/*.whl
```
+11
View File
@@ -0,0 +1,11 @@
---
title: Home
---
{%
includemarkdown "../README.md"
start="<!--intro-start-->"
end="<!--intro-end-->"
%}
To get started, head over to the [setup guide](setup.md).
@@ -0,0 +1,84 @@
import cgi
import re
from pathlib import Path
import mkdocs
INCLUDE_TAG_REGEX = re.compile(
r'''
{% # opening tag
\s*
include # directive name
\s+
"(?P<filename>[^"]+)" # "filename"
\s*
%} # closing tag
''',
flags=re.VERBOSE,
)
INCLUDEMARKDOWN_TAG_REGEX = re.compile(
r'''
{% # opening tag
\s*
includemarkdown # directive name
\s+
"(?P<filename>[^"]+)" # "filename"
(?:\s+start="(?P<start>[^"]+)")? # optional start expression
(?:\s+end="(?P<end>[^"]+)")? # optional end expression
\s*
%} # closing tag
''',
flags=re.VERBOSE,
)
class ImportMarkdownPlugin(mkdocs.plugins.BasePlugin):
def on_page_markdown(self, markdown, page, **kwargs):
page_src_path = page.file.abs_src_path
def found_include_tag(match):
filename = match.group('filename')
file_path_abs = Path(page_src_path).parent / filename
if not file_path_abs.exists():
raise ValueError('file not found', filename)
text_to_include = file_path_abs.read_text(encoding='utf8')
# Allow good practice of having a final newline in the file
if text_to_include.endswith('\n'):
text_to_include = text_to_include[:-1]
return text_to_include
def found_includemarkdown_tag(match):
filename = match.group('filename')
start = match.group('start')
end = match.group('end')
file_path_abs = Path(page_src_path).parent / filename
if not file_path_abs.exists():
raise ValueError('file not found', filename)
text_to_include = file_path_abs.read_text(encoding='utf8')
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 '')
)
+ text_to_include
+ '\n<!-- END INCLUDE -->'
)
markdown = re.sub(INCLUDE_TAG_REGEX, found_include_tag, markdown)
markdown = re.sub(INCLUDEMARKDOWN_TAG_REGEX, found_includemarkdown_tag, markdown)
return markdown
@@ -0,0 +1,15 @@
from setuptools import setup
setup(
name='mkdocs_include_markdown_plugin',
version='1.0',
author='Joe Rickerby',
license='Apache 2',
packages=['mkdocs_include_markdown_plugin'],
entry_points={
'mkdocs.plugins': [
'importmarkdown = mkdocs_include_markdown_plugin.plugin:ImportMarkdownPlugin',
]
},
zip_safe=False
)
+638
View File
@@ -0,0 +1,638 @@
## Options summary
<div class="options-toc"></div>
## Setting options
cibuildwheel is configured using environment variables, that can be set using
your CI config.
For example, to configure cibuildwheel to run tests, add the following YAML to
your CI config file:
> .travis.yml ([docs](https://docs.travis-ci.com/user/environment-variables/))
```yaml
env:
global:
- CIBW_TEST_REQUIRES=pytest
- CIBW_TEST_COMMAND="pytest {project}/tests"
```
> appveyor.yml ([docs](https://www.appveyor.com/docs/build-configuration/#environment-variables))
```yaml
environment:
global:
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: "pytest {project}\\tests"
```
> .circleci/config.yml ([docs](https://circleci.com/docs/2.0/configuration-reference/#environment))
```yaml
jobs:
job_name:
environment:
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: "pytest {project}/tests"
```
> azure-pipelines.yml ([docs](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables))
```yaml
variables:
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: "pytest {project}/tests"
```
> .github/workflows/*.yml ([docs](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables)) (can be global, in job, or in step)
```yaml
env:
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: "pytest {project}/tests"
```
## Build selection
### `CIBW_PLATFORM` {: #platform}
> Override the auto-detected target platform
Options: `auto` `linux` `macos` `windows`
Default: `auto`
`auto` will auto-detect platform using environment variables, such as `TRAVIS_OS_NAME`/`APPVEYOR`/`CIRCLECI`.
For `linux` you need Docker running, on macOS or Linux. For `macos`, you need a Mac machine, and note that this script is going to automatically install MacPython on your system, so don't run on your development machine. For `windows`, you need to run in Windows, and `cibuildwheel` will install required versions of Python to `C:\cibw\python` using NuGet.
This option can also be set using the command-line option `--platform`.
### `CIBW_BUILD`, `CIBW_SKIP` {: #build-skip}
> Choose the Python versions to build
Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux_x86_64` or `cp35-macosx_x86_64` - you can list specific ones to build and `cibuildwheel` will only build those, and/or list ones to skip and `cibuildwheel` won't try to build them.
When both options are specified, both conditions are applied and only builds with a tag that matches `CIBW_BUILD` and does not match `CIBW_SKIP` will be built.
When setting the options, you can use shell-style globbing syntax (as per [`fnmatch`](https://docs.python.org/3/library/fnmatch.html)). All the build identifiers supported by cibuildwheel are shown below:
<div class="build-id-table-marker"></div>
| | macOS 64bit | Manylinux x86 64bit | Manylinux x86 32bit | Windows 64bit | Windows 32bit | Manylinux Armv8 64bit | Manylinux PPC64LE | Manylinux s390x |
|-----------------|---------------------|------------------------|----------------------|-----------------|----------------|------------------------|------------------------|----------------------|
| Python 2.7 | cp27-macosx_x86_64 | cp27-manylinux_x86_64 | cp27-manylinux_i686 | cp27-win_amd64 | cp27-win32 | | | |
| Python 3.5 | cp35-macosx_x86_64 | cp35-manylinux_x86_64 | cp35-manylinux_i686 | cp35-win_amd64 | cp35-win32 | cp35-manylinux_aarch64 | cp35-manylinux_ppc64le | cp35-manylinux_s390x |
| Python 3.6 | cp36-macosx_x86_64 | cp36-manylinux_x86_64 | cp36-manylinux_i686 | cp36-win_amd64 | cp36-win32 | cp36-manylinux_aarch64 | cp36-manylinux_ppc64le | cp36-manylinux_s390x |
| Python 3.7 | cp37-macosx_x86_64 | cp37-manylinux_x86_64 | cp37-manylinux_i686 | cp37-win_amd64 | cp37-win32 | cp37-manylinux_aarch64 | cp37-manylinux_ppc64le | cp37-manylinux_s390x |
| Python 3.8 | cp38-macosx_x86_64 | cp38-manylinux_x86_64 | cp38-manylinux_i686 | cp38-win_amd64 | cp38-win32 | cp38-manylinux_aarch64 | cp38-manylinux_ppc64le | cp38-manylinux_s390x |
| PyPy 2.7 v7.3.0 | pp27-macosx_x86_64 | pp27-manylinux_x86_64 | | | pp27-win32 | | | |
| PyPy 3.6 v7.3.0 | pp36-macosx_x86_64 | pp36-manylinux_x86_64 | | | pp36-win32 | | | |
The list of supported and currently selected build identifiers can also be retrieved by passing the `--print-build-identifiers` flag to `cibuildwheel`.
The format is `python_tag-platform_tag`, with tags similar to those in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details).
For CPython, the minimally supported macOS version is 10.9; for PyPy 2.7 and PyPy 3.6, respectively macOS 10.7 and 10.13 or higher is required.
#### Examples
```yaml
# Only build on Python 3.6
CIBW_BUILD: cp36-*
# Skip building on Python 2.7 on the Mac
CIBW_SKIP: cp27-macosx_x86_64
# Skip building on Python 3.8 on the Mac
CIBW_SKIP: cp38-macosx_x86_64
# Skip building on Python 2.7 on all platforms
CIBW_SKIP: cp27-*
# Skip Python 2.7 on Windows
CIBW_SKIP: cp27-win*
# Skip Python 2.7 on 32-bit Windows
CIBW_SKIP: cp27-win32
# Skip Python 2.7 and Python 3.5
CIBW_SKIP: cp27-* cp35-*
# Skip Python 3.6 on Linux
CIBW_SKIP: cp36-manylinux*
# Only build on Python 3 and skip 32-bit builds
CIBW_BUILD: cp3?-*
CIBW_SKIP: "*-win32 *-manylinux_i686"
# Only build PyPy and CPython 3
CIBW_BUILD: pp* cp3?-*
# Disable building PyPy wheels on all platforms
CIBW_SKIP: pp*
```
<style>
.build-id-table-marker + table {
font-size: 90%;
white-space: nowrap;
}
.rst-content .build-id-table-marker + table td,
.rst-content .build-id-table-marker + table th {
padding: 4px 4px;
}
.build-id-table-marker + table td:not(:first-child) {
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
font-size: 85%;
}
dt code {
font-size: 100%;
background-color: rgba(41, 128, 185, 0.1);
padding: 0;
}
</style>
## Build customization
### `CIBW_ENVIRONMENT` {: #environment}
> Set environment variables needed during the build
A space-separated list of environment variables to set during the build. Bash syntax should be used, even on Windows.
You must set this variable to pass variables to Linux builds (since they execute in a Docker container). It also works for the other platforms.
You can use `$PATH` syntax to insert other variables, or the `$(pwd)` syntax to insert the output of other shell commands.
To specify more than one environment variable, separate the assignments by spaces.
Platform-specific variants also available:<br/>
`CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX`
#### Examples
```yaml
# Set some compiler flags
CIBW_ENVIRONMENT: "CFLAGS='-g -Wall' CXXFLAGS='-Wall'"
# Append a directory to the PATH variable (this is expanded in the build environment)
CIBW_ENVIRONMENT: "PATH=$PATH:/usr/local/bin"
# Set BUILD_TIME to the output of the `date` command
CIBW_ENVIRONMENT: "BUILD_TIME=$(date)"
# Supply options to `pip` to affect how it downloads dependencies
CIBW_ENVIRONMENT: "PIP_EXTRA_INDEX_URL=https://pypi.myorg.com/simple"
# Set two flags
CIBW_ENVIRONMENT: "BUILD_TIME=$(date) SAMPLE_TEXT=\"sample text\""
```
!!! note
`cibuildwheel` always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](faq.md#building-packages-with-optional-c-extensions).
### `CIBW_BEFORE_ALL` {: #before-all}
> Execute a shell command on the build system before any wheels are built.
Shell command to prepare a common part of the project (e.g. build or install libraries which does not depend on the specific version of Python).
This option is very useful for the Linux build, where builds take place in isolated Docker containers managed by cibuildwheel. This command will run inside the container before the wheel builds start. Note, if you're building both x86_64 and i686 wheels (the default), your build uses two different Docker images. In that case, this command will execute twice - once per build container.
The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by `cibuildwheel`.
On Windows and macOS, the version of Python available inside `CIBW_BEFORE_ALL` is whatever is available on the host machine. On Linux, a modern Python version is available on PATH.
Platform-specific variants also available:<br/>
`CIBW_BEFORE_ALL_MACOS` | `CIBW_BEFORE_ALL_WINDOWS` | `CIBW_BEFORE_ALL_LINUX`
#### Examples
```yaml
# build third party library
CIBW_BEFORE_ALL: make -C third_party_lib
# install system library
CIBW_BEFORE_ALL_LINUX: yum install -y libffi-dev
```
### `CIBW_BEFORE_BUILD` {: #before-build}
> Execute a shell command preparing each wheel's build
A shell command to run before building the wheel. This option allows you to run a command in **each** Python environment before the `pip wheel` command. This is useful if you need to set up some dependency so it's available during the build.
If dependencies are required to build your wheel (for example if you include a header from a Python module), set this to `pip install .`, and the dependencies will be installed automatically by pip. However, this means your package will be built twice - if your package takes a long time to build, you might wish to manually list the dependencies here instead.
The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by `cibuildwheel`.
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
Platform-specific variants also available:<br/>
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX`
#### Examples
```yaml
# install your project and dependencies before building
CIBW_BEFORE_BUILD: pip install .
# install something required for the build
CIBW_BEFORE_BUILD: pip install pybind11
# chain commands using &&
CIBW_BEFORE_BUILD: yum install -y libffi-dev && pip install .
# run a script that's inside your project
CIBW_BEFORE_BUILD: bash scripts/prepare_for_build.sh
# if cibuildwheel is called with a package_dir argument, it's available as {package}
CIBW_BEFORE_BUILD: "{package}/bin/prepare_for_build.sh"
```
### `CIBW_REPAIR_WHEEL_COMMAND` {: #repair-wheel-command}
> Execute a shell command to repair each (non-pure Python) built wheel
Default:
- on Linux: `'auditwheel repair -w {dest_dir} {wheel}'`
- on macOS: `'delocate-listdeps {wheel} && delocate-wheel --require-archs x86_64 -w {dest_dir} {wheel}'`
- on Windows: `''`
A shell command to repair a built wheel by copying external library dependencies into the wheel tree and relinking them.
The command is run on each built wheel (except for pure Python ones) before testing it.
The following placeholders must be used inside the command and will be replaced by `cibuildwheel`:
- `{wheel}` for the absolute path to the built wheel
- `{dest_dir}` for the absolute path of the directory where to create the repaired wheel.
The command is run in a shell, so you can run multiple commands like `cmd1 && cmd2`.
Platform-specific variants also available:<br/>
`CIBW_REPAIR_WHEEL_COMMAND_MACOS` | `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS` | `CIBW_REPAIR_WHEEL_COMMAND_LINUX`
#### Examples
```yaml
# don't repair macOS wheels
CIBW_REPAIR_WHEEL_COMMAND_MACOS: ""
# pass the `--lib-sdir .` flag to auditwheel on Linux
CIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel repair --lib-sdir . -w {dest_dir} {wheel}"
```
### `CIBW_MANYLINUX_X86_64_IMAGE`, `CIBW_MANYLINUX_I686_IMAGE`, `CIBW_MANYLINUX_PYPY_X86_64_IMAGE`, `CIBW_MANYLINUX_AARCH64_IMAGE`, `CIBW_MANYLINUX_PPC64LE_IMAGE`, `CIBW_MANYLINUX_S390X_IMAGE` {: #manylinux-image}
> Specify alternative manylinux docker images
An alternative Docker image to be used for building [`manylinux`](https://github.com/pypa/manylinux) wheels. `cibuildwheel` will then pull these instead of the default images, [`quay.io/pypa/manylinux2010_x86_64`](https://quay.io/pypa/manylinux2010_x86_64), [`quay.io/pypa/manylinux2010_i686`](https://quay.io/pypa/manylinux2010_i686), [`pypywheels/manylinux2010-pypy_x86_64`](https://hub.docker.com/r/pypywheels/manylinux2010-pypy_x86_64), [`quay.io/pypa/manylinux2014_aarch64`](https://quay.io/pypa/manylinux2014_aarch64), [`quay.io/pypa/manylinux2014_ppc64le`](https://quay.io/pypa/manylinux2014_ppc64le), and [`quay.io/pypa/manylinux2014_s390x`](https://quay.io/pypa/manylinux2010_s390x).
The value of this option can either be set to `manylinux1`, `manylinux2010` or `manylinux2014` to use a pinned version of the [official `manylinux` images](https://github.com/pypa/manylinux) and [PyPy `manylinux` images](https://github.com/pypy/manylinux). Alternatively, set these options to any other valid Docker image name. Note that for PyPy, only the official `manylinux2010` image is currently available. For architectures other
than x86 (x86\_64 and i686) manylinux2014 must be used because this is the first version of the manylinux specification that supports additional architectures.
Beware to specify a valid Docker image that can be used in the same way as the official, default Docker images: all necessary Python and pip versions need to be present in `/opt/python/`, and the `auditwheel` tool needs to be present for `cibuildwheel` to work. Apart from that, the architecture and relevant shared system libraries need to be manylinux1-, manylinux2010- or manylinux2014-compatible in order to produce valid `manylinux1`/`manylinux2010`/`manylinux2014` wheels (see [pypa/manylinux on GitHub](https://github.com/pypa/manylinux), [PEP 513](https://www.python.org/dev/peps/pep-0513/), [PEP 571](https://www.python.org/dev/peps/pep-0571/) and [PEP 599](https://www.python.org/dev/peps/pep-0599/) for more details).
Note that `auditwheel` detects the version of the `manylinux` standard in the Docker image through the `AUDITWHEEL_PLAT` environment variable, as `cibuildwheel` has no way of detecting the correct `--plat` command line argument to pass to `auditwheel` for a custom image. If a Docker image does not correctly set this `AUDITWHEEL_PLAT` environment variable, the `CIBW_ENVIRONMENT` option can be used to do so (e.g., `CIBW_ENVIRONMENT='AUDITWHEEL_PLAT="manylinux2010_$(uname -m)"'`).
Note that `manylinux2014` doesn't support builds with Python 2.7 - when building with `manylinux2014`, skip Python 2.7 using `CIBW_SKIP` (see example below).
#### Examples
```yaml
# build using the manylinux1 image to ensure manylinux1 wheels are produced
# skip PyPy, since there is no PyPy manylinux1 image
CIBW_MANYLINUX_X86_64_IMAGE: manylinux1
CIBW_MANYLINUX_I686_IMAGE: manylinux1
CIBW_SKIP: pp*
# build using the manylinux2014 image
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_I686_IMAGE: manylinux2014
CIBW_SKIP: cp27-manylinux*
# build using the latest manylinux2010 release, instead of the cibuildwheel
# pinned version
CIBW_MANYLINUX_X86_64_IMAGE: quay.io/pypa/manylinux2010_x86_64:latest
CIBW_MANYLINUX_I686_IMAGE: quay.io/pypa/manylinux2010_i686:latest
# build using a different image from the docker registry
CIBW_MANYLINUX_X86_64_IMAGE: dockcross/manylinux-x64
CIBW_MANYLINUX_I686_IMAGE: dockcross/manylinux-x86
```
### `CIBW_DEPENDENCY_VERSIONS` {: #dependency-versions}
> Specify how cibuildwheel controls the versions of the tools it uses
Options: `pinned` `latest` `<your constraints file>`
Default: `pinned`
If `CIBW_DEPENDENCY_VERSIONS` is `pinned`, cibuildwheel uses versions of tools
like `pip`, `setuptools`, `virtualenv` that were pinned with that release of
cibuildwheel. This represents a known-good set of dependencies, and is
recommended for build repeatability.
If set to `latest`, cibuildwheel will use the latest of these packages that
are available on PyPI. This might be preferable if these packages have bug
fixes that can't wait for a new cibuildwheel release.
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`
!!! note
This option does not affect the tools used on the Linux build - those versions
are bundled with the manylinux image that cibuildwheel uses. To change
dependency versions on Linux, use the [CIBW_MANYLINUX_*](#manylinux-image)
options.
#### Examples
```yaml
# use tools versions that are bundled with cibuildwheel (this is the default)
CIBW_DEPENDENCY_VERSIONS: pinned
# use the latest versions available on PyPI
CIBW_DEPENDENCY_VERSIONS: latest
# use your own pip constraints file
CIBW_DEPENDENCY_VERSIONS: ./constraints.txt
```
## Testing
### `CIBW_TEST_COMMAND` {: #test-command}
> Execute a shell command to test each built wheel
Shell command to run tests after the build. The wheel will be installed automatically and available for import from the tests. To ensure the wheel is imported by your tests (instead of your source copy), tests are run from a different directory. Use the placeholders `{project}` and `{package}` when specifying paths in your project.
- `{project}` is an absolute path to the project root - the working directory where cibuildwheel was called.
- `{package}` is the path to the package being built - the `package_dir` argument supplied to cibuildwheel on the command line.
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
Platform-specific variants also available:<br/>
`CIBW_TEST_COMMAND_MACOS` | `CIBW_TEST_COMMAND_WINDOWS` | `CIBW_TEST_COMMAND_LINUX`
#### Examples
```yaml
# run the project tests against the installed wheel using `nose`
CIBW_TEST_COMMAND: nosetests {project}/tests
# run the package tests using `pytest`
CIBW_TEST_COMMAND: pytest {package}/tests
```
### `CIBW_BEFORE_TEST` {: #before-test}
> Execute a shell command before testing each wheel
A shell command to run in **each** test virtual environment, before your wheel is installed and tested. This is useful if you need to install a non pip package, change values of environment variables
or perform multi step pip installation (e.g. installing `scikit-build` or `cython` before install test package)
The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by `cibuildwheel`.
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
Platform-specific variants also available:<br/>
`CIBW_BEFORE_TEST_MACOS` | `CIBW_BEFORE_TEST_WINDOWS` | `CIBW_BEFORE_TEST_LINUX`
#### Examples
```yaml
# install test dependencies with overwritten environment variables.
CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt
# chain commands using &&
CIBW_BEFORE_TEST: rm -rf ./data/cache && mkdir -p ./data/cache
# install non pip python package
CIBW_BEFORE_TEST: cd some_dir; ./configure; make; make install
# install python packages that are required to install test dependencies
CIBW_BEFORE_TEST: pip install cmake scikit-build
```
### `CIBW_TEST_REQUIRES` {: #test-requires}
> Install Python dependencies before running the tests
Space-separated list of dependencies required for running the tests.
Platform-specific variants also available:<br/>
`CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX`
#### Examples
```yaml
# install pytest before running CIBW_TEST_COMMAND
CIBW_TEST_REQUIRES: pytest
# install specific versions of test dependencies
CIBW_TEST_REQUIRES: nose==1.3.7 moto==0.4.31
```
### `CIBW_TEST_EXTRAS` {: #test-extras}
> Install your wheel for testing using `extras_require`
Comma-separated list of
[extras_require](https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies)
options that should be included when installing the wheel prior to running the
tests. This can be used to avoid having to redefine test dependencies in
`CIBW_TEST_REQUIRES` if they are already defined in `setup.py` or
`setup.cfg`.
Platform-specific variants also available:<br/>
`CIBW_TEST_EXTRAS_MACOS` | `CIBW_TEST_EXTRAS_WINDOWS` | `CIBW_TEST_EXTRAS_LINUX`
#### Examples
```yaml
# will cause the wheel to be installed with `pip install <wheel_file>[test,qt]`
CIBW_TEST_EXTRAS: test,qt
```
## Other
### `CIBW_BUILD_VERBOSITY` {: #build-verbosity}
> Increase/decrease the output of pip wheel
An number from 1 to 3 to increase the level of verbosity (corresponding to invoking pip with `-v`, `-vv`, and `-vvv`), between -1 and -3 (`-q`, `-qq`, and `-qqq`), or just 0 (default verbosity). These flags are useful while debugging a build when the output of the actual build invoked by `pip wheel` is required.
Platform-specific variants also available:<br/>
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX`
#### Examples
```yaml
# increase pip debugging output
CIBW_BUILD_VERBOSITY: 1
```
## Command line options
```text
usage: cibuildwheel [-h] [--platform {auto,linux,macos,windows}]
[--output-dir OUTPUT_DIR] [--print-build-identifiers]
[package_dir]
Build wheels for all the platforms.
positional arguments:
package_dir Path to the package that you want wheels for. Must be
a subdirectory of the working directory. When set, the
working directory is still considered the 'project'
and is copied into the Docker container on Linux.
Default: the working directory.
optional arguments:
-h, --help show this help message and exit
--platform {auto,linux,macos,windows}
Platform to build for. For "linux" you need docker
running, on Mac or Linux. For "macos", you need a Mac
machine, and note that this script is going to
automatically install MacPython on your system, so
don't run on your development machine. For "windows",
you need to run in Windows, and it will build and test
for all versions of Python. Default: auto.
--output-dir OUTPUT_DIR
Destination folder for the wheels.
--print-build-identifiers
Print the build identifiers matched by the current
invocation and exit.
```
<style>
.toctree-l3 {
border-left: 10px solid transparent;
}
.options-toc {
display: grid;
grid-auto-columns: fit-content(20%) 1fr;
grid-gap: 16px 32px;
gap: 16px 32px;
font-size: 90%;
margin-bottom: 28px;
margin-top: 28px;
}
.options-toc .header {
grid-column: 1 / 3;
font-weight: bold;
}
.options-toc .header:first-child {
margin-top: 0;
}
.options-toc a.option {
display: block;
margin-bottom: 5px;
}
h3 code {
font-size: 100%;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
// gather the options data
var options = {}
var headers = []
$('.rst-content h3')
.filter(function (i, el) {
return !!$(el).text().match(/(^([A-Z0-9, _]| and )+)¶$/);
})
.each(function (i, el) {
var optionName = $(el).text().replace('¶', '');
var description = $(el).next('blockquote').text()
var header = $(el).prevAll('h2').first().text().replace('¶', '')
var id = el.id;
if (options[header] === undefined) {
options[header] = [];
headers.push(header);
}
console.log(optionName, description, header);
options[header].push({name: optionName, description, id});
});
// write the table of contents
var tocTable = $('.options-toc');
for (var i = 0; i < headers.length; i += 1) {
var header = headers[i];
var headerOptions = options[header];
$('<div class="header">').text(header).appendTo(tocTable);
for (var j = 0; j < headerOptions.length; j += 1) {
var option = headerOptions[j];
var optionNames = option.name.split(', ')
$('<div class="name">')
.append($.map(optionNames, function (name) {
return $('<a class="option">')
.append(
$('<code>').text(name)
)
.attr('href', '#'+option.id)
}
))
.appendTo(tocTable);
$('<div class="description">')
.text(option.description)
.appendTo(tocTable);
}
}
// write the markdown table for the README
var markdown = ''
markdown += '| | Option | Description |\n'
markdown += '|---|--------|-------------|\n'
var prevHeader = null
for (var i = 0; i < headers.length; i += 1) {
var header = headers[i];
var headerOptions = options[header];
for (var j = 0; j < headerOptions.length; j += 1) {
var option = headerOptions[j];
if (j == 0) {
markdown += '| **'+header+'** '
} else {
markdown += '| '
}
var optionNames = option.name.trim().split(', ')
var url = 'https://cibuildwheel.readthedocs.io/en/stable/options/#'+option.id;
var namesMarkdown = $.map(optionNames, function(n) {
return '[`'+n+'`]('+url+') '
}).join(' <br> ')
markdown += '| '+namesMarkdown+' '
markdown += '| '+option.description.trim()+' '
markdown += '|\n'
}
}
console.log('readme options markdown\n', markdown)
});
</script>
+116
View File
@@ -0,0 +1,116 @@
---
title: 'Setup'
---
# GitHub Actions [linux/mac/windows] {: #github-actions}
To build Linux, Mac, and Windows wheels using Github Actions, create a `.github/workflows/build.yml` file in your repo.
> build.yml
```yaml
{% include "../examples/github-minimal.yml" %}
```
Commit this file, and push to Github - either to your default branch, or to a PR branch. The build should start automatically.
For more info on this file, check out the [docs](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions).
[`examples/github-deploy.yml`](https://github.com/joerick/cibuildwheel/blob/master/examples/github-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
# Azure Pipelines [linux/mac/windows] {: #azure-pipelines}
To build Linux, Mac, and Windows wheels on Azure Pipelines, create a `azure-pipelines.yml` file in your repo.
> azure-pipelines.yml
```yaml
{% include "../examples/azure-pipelines-minimal.yml" %}
```
!!! note
To support Python 3.5 on Windows, make sure to specify the use of `{vmImage: 'vs2017-win2016'}` on Windows, to ensure the required toolchain is available.
Commit this file, enable building of your repo on Azure Pipelines, and push.
Wheels will be stored for you and available through the Pipelines interface. For more info on this file, check out the [docs](https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema).
# Travis CI [linux/mac/windows] {: #travis-ci}
To build Linux, Mac, and Windows wheels on Travis CI, create a `.travis.yml` file in your repo.
> .travis.yml
```yaml
{% include "../examples/travis-ci-minimal.yml" %}
```
Note that building Windows Python 2.7 wheels on Travis is unsupported.
Commit this file, enable building of your repo on Travis CI, and push.
Then setup a deployment method by following the [Travis CI deployment docs](https://docs.travis-ci.com/user/deployment/), or see [Delivering to PyPI](deliver-to-pypi.md). For more info on `.travis.yml`, check out the [docs](https://docs.travis-ci.com/).
[`examples/travis-deploy.yml`](https://github.com/joerick/cibuildwheel/blob/master/examples/travis-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
# CircleCI [linux/mac] {: #circleci}
To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo,
> .circleci/config.yml
```yaml
{% include "../examples/circleci-minimal.yml" %}
```
Commit this file, enable building of your repo on CircleCI, and push.
!!! note
CircleCI doesn't enable free macOS containers for open source by default, but you can ask for access. See [here](https://circleci.com/docs/2.0/oss/#overview) for more information.
CircleCI will store the built wheels for you - you can access them from the project console. Check out the CircleCI [docs](https://circleci.com/docs/2.0/configuration-reference/#section=configuration) for more info on this config file.
# AppVeyor [linux/mac/windows] {: #appveyor}
To build Linux, Mac, and Windows wheels on AppVeyor, create an `appveyor.yml` file in your repo.
> appveyor.yml
```yaml
{% include "../examples/appveyor-minimal.yml" %}
```
Commit this file, enable building of your repo on AppVeyor, and push.
AppVeyor will store the built wheels for you - you can access them from the project console. Alternatively, you may want to store them in the same place as the Travis CI build. See [AppVeyor deployment docs](https://www.appveyor.com/docs/deployment/) for more info, or see [Delivering to PyPI](deliver-to-pypi.md) below.
For more info on this config file, check out the [docs](https://www.appveyor.com/docs/).
> ⚠️ Got an error? Check the [FAQ](faq.md).
<script>
document.addEventListener('DOMContentLoaded', function() {
$('.toctree-l2 a, .rst-content h1').each(function(i, el) {
var text = $(el).text()
var match = text.match(/(.*) \[([a-z/]+)\]/);
if (match) {
var iconHTML = $.map(match[2].split('/'), function(ident) {
switch (ident) {
case 'linux':
return '<i class="fa fa-linux" aria-hidden="true"></i>'
case 'windows':
return '<i class="fa fa-windows" aria-hidden="true"></i>'
case 'mac':
return '<i class="fa fa-apple" aria-hidden="true"></i>'
}
}).join(' ');
$(el).append(
$('<div>')
.append(iconHTML)
.css({float: 'right'})
)
$(el).contents()
.filter(function(){ return this.nodeType == 3; }).first()
.replaceWith(match[1]);
}
});
});
</script>
+21
View File
@@ -0,0 +1,21 @@
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu
APPVEYOR_JOB_NAME: "python37-x64-ubuntu"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
APPVEYOR_JOB_NAME: "python37-x64-vs2015"
- APPVEYOR_BUILD_WORKER_IMAGE: macos-mojave
APPVEYOR_JOB_NAME: "python37-x64-macos-mojave"
stack: python 3.7
init:
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
install: python -m pip install cibuildwheel==1.5.3
build_script: python -m cibuildwheel --output-dir wheelhouse
artifacts:
- path: "wheelhouse\\*.whl"
name: Wheels
+35
View File
@@ -0,0 +1,35 @@
jobs:
- job: linux
pool: {vmImage: 'Ubuntu-16.04'}
steps:
- task: UsePythonVersion@0
- bash: |
python3 -m pip install --upgrade pip
pip3 install cibuildwheel==1.5.3
cibuildwheel --output-dir wheelhouse .
- task: PublishBuildArtifacts@1
inputs: {pathtoPublish: 'wheelhouse'}
- job: macos
pool: {vmImage: 'macOS-10.15'}
steps:
- task: UsePythonVersion@0
- bash: |
python3 -m pip install --upgrade pip
pip3 install cibuildwheel==1.5.3
cibuildwheel --output-dir wheelhouse .
- task: PublishBuildArtifacts@1
inputs: {pathtoPublish: 'wheelhouse'}
- job: windows
pool: {vmImage: 'vs2017-win2016'}
steps:
- task: UsePythonVersion@0
- script: choco install vcpython27 -f -y
displayName: Install Visual C++ for Python 2.7
- bash: |
python -m pip install --upgrade pip
pip install cibuildwheel==1.5.3
cibuildwheel --output-dir wheelhouse .
- task: PublishBuildArtifacts@1
inputs: {pathtoPublish: 'wheelhouse'}
+38
View File
@@ -0,0 +1,38 @@
version: 2
jobs:
linux-wheels:
working_directory: ~/linux-wheels
docker:
- image: circleci/python:3.6
steps:
- checkout
- setup_remote_docker
- run:
name: Build the Linux wheels.
command: |
pip3 install --user cibuildwheel==1.5.3
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
osx-wheels:
working_directory: ~/osx-wheels
macos:
xcode: "10.0.0"
steps:
- checkout
- run:
name: Build the OS X wheels.
command: |
pip3 install --user cibuildwheel==1.5.3
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
workflows:
version: 2
all-tests:
jobs:
- linux-wheels
- osx-wheels
+81
View File
@@ -0,0 +1,81 @@
name: Build and upload to PyPI
# Build on every branch push, tag push, and pull request change:
on: [push, pull_request]
# Alternatively, to publish when a (published) GitHub Release is created, use the following:
# on:
# push:
# pull_request:
# release:
# types:
# - published
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
name: Install Python
with:
python-version: '3.7'
- name: Install cibuildwheel
run: |
python -m pip install cibuildwheel==1.5.3
- name: Install Visual C++ for Python 2.7
if: runner.os == 'Windows'
run: |
choco install vcpython27 -f -y
- name: Build wheels
run: |
python -m cibuildwheel --output-dir wheelhouse
- uses: actions/upload-artifact@v2
with:
path: ./wheelhouse/*.whl
build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
name: Install Python
with:
python-version: '3.7'
- name: Build sdist
run: python setup.py sdist
- uses: actions/upload-artifact@v2
with:
path: dist/*.tar.gz
upload_pypi:
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
# upload to PyPI on every tag starting with 'v'
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
# alternatively, to publish when a GitHub Release is created, use the following rule:
# if: github.event_name == 'release' && github.event.action == 'published'
steps:
- uses: actions/download-artifact@v2
with:
name: artifact
path: dist
- uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_password }}
# To test: repository_url: https://test.pypi.org/legacy/
+36
View File
@@ -0,0 +1,36 @@
name: Build
on: [push, pull_request]
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
name: Install Python
with:
python-version: '3.7'
- name: Install cibuildwheel
run: |
python -m pip install cibuildwheel==1.5.3
- name: Install Visual C++ for Python 2.7
if: runner.os == 'Windows'
run: |
choco install vcpython27 -f -y
- name: Build wheels
run: |
python -m cibuildwheel --output-dir wheelhouse
- uses: actions/upload-artifact@v2
with:
path: ./wheelhouse/*.whl
+40
View File
@@ -0,0 +1,40 @@
# As written, this configuration will build your wheels on every
# commit, but will only push to PyPI on tagged commits.
language: python
jobs:
include:
# perform a linux build
- services: docker
# and a mac build
- os: osx
language: shell
# and a windows build
- os: windows
language: shell
before_install:
- choco install python --version 3.8.0
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
# make sure it's on PATH as 'python3'
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
env:
global:
- TWINE_USERNAME=__token__
# Note: TWINE_PASSWORD is set to a PyPI API token in Travis settings
install:
- python3 -m pip install cibuildwheel==1.5.3
script:
# build the wheels, put them into './wheelhouse'
- python3 -m cibuildwheel --output-dir wheelhouse
after_success:
# if the release was tagged, upload them to PyPI
- |
if [[ $TRAVIS_TAG ]]; then
python3 -m pip install twine
python3 -m twine upload wheelhouse/*.whl
fi
+33
View File
@@ -0,0 +1,33 @@
language: python
jobs:
include:
# perform a linux build
- services: docker
# perform a linux ARMv8 build
- services: docker
arch: arm64
# perform a linux PPC64LE build
- services: docker
arch: ppc64le
# perform a linux S390X build
- services: docker
arch: s390x
# and a mac build
- os: osx
language: shell
# and a windows build
- os: windows
language: shell
before_install:
- choco install python --version 3.8.0
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
# make sure it's on PATH as 'python3'
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
install:
- python3 -m pip install cibuildwheel==1.5.3
script:
# build the wheels, put them into './wheelhouse'
- python3 -m cibuildwheel --output-dir wheelhouse
+87
View File
@@ -0,0 +1,87 @@
# In this configuration, the package is tested against multiple versions of python
# on Linux and on one version of Python on Windows. If and only if all tests pass
# will the wheels be built and deployed. Further, deployment is only initiated if
# the current branch is "master", the current commit is tagged, and the current
# repo is yours (e.g. it won't run on a Pull Request). For convenience, a source
# distribution is also created.
language: python
python:
- 3.6
- 3.7
- 3.8
before_install:
- |
if [[ "$TRAVIS_OS_NAME" = windows ]]; then
choco install python --version 3.8.0
export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
# make sure it's on PATH as 'python3'
ln -s /c/Python38/python.exe /c/Python38/python3.exe
fi
install:
- python3 -m pip install pytest
script:
- python3 setup.py install
- pytest
stages:
- test
# Only execute deployment stage on tagged commits, and from your repository
# (e.g. not PRs). Replace with your repo name.
- name: deploy
if: tag IS PRESENT AND repo = joerick/cibuildwheel
# To only build tags that look like vX.Y.Z:
# if: tag =~ ^v\d+\.\d+\.\d+$ AND repo = joerick/cibuildwheel
jobs:
include:
# Optional: run a test on Windows
- os: windows
language: shell
name: Test on Windows
# Deploy source distribution
- stage: deploy
name: Deploy source distribution
install: skip
script: python3 setup.py sdist --formats=gztar
after_success: |
python3 -m pip install twine
python3 -m twine upload --skip-existing dist/*.tar.gz
# Deploy on linux
- stage: deploy
name: Build and deploy Linux wheels
services: docker
install: python3 -m pip install cibuildwheel==1.5.3
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
python3 -m twine upload --skip-existing wheelhouse/*.whl
# Deploy on mac
- stage: deploy
name: Build and deploy macOS wheels
os: osx
language: shell
install: python3 -m pip install cibuildwheel==1.5.3
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
python3 -m twine upload --skip-existing wheelhouse/*.whl
# Deploy on windows
- stage: deploy
name: Build and deploy Windows wheels
os: windows
language: shell
install: python3 -m pip install cibuildwheel==1.5.3
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
python3 -m twine upload --skip-existing wheelhouse/*.whl
env:
global:
- TWINE_USERNAME=__token__
# Note: TWINE_PASSWORD is set to a PyPI API token in Travis settings
+35
View File
@@ -0,0 +1,35 @@
site_name: cibuildwheel
docs_dir: docs
theme:
name: readthedocs
highlightjs: true
hljs_languages:
- yaml
repo_url: https://github.com/joerick/cibuildwheel
extra_css:
- extra.css
extra_javascript:
- extra.js
nav:
- Home: index.md
- setup.md
- options.md
- deliver-to-pypi.md
- cpp_standards.md
- faq.md
- contributing.md
markdown_extensions:
- fenced_code
- toc:
permalink: True
- attr_list
- admonition
- pymdownx.magiclink:
repo_url_shortener: True
plugins:
- importmarkdown
+8
View File
@@ -1,2 +1,10 @@
-e .
-e ./docs/mkdocs_include_markdown_plugin
pytest
mkdocs==1.0.4
pymdown-extensions
pip-tools
requests
click
mypy
typing-extensions
+36 -10
View File
@@ -1,14 +1,40 @@
[bumpversion]
current_version = 0.8.0
commit = True
tag = True
message = Bump version
[flake8]
ignore = E501,W503,E741,E226
application-import-names = cibuildwheel
exclude =
cibuildwheel/resources/,
dist/,
build/,
.git/,
env/,
env2/,
env??/,
.venv/,
site/
[bumpversion:file:setup.py]
[tool:pytest]
junit_family=xunit2
[bumpversion:file:cibuildwheel/__init__.py]
[mypy]
python_version = 3.6
files = cibuildwheel,test
[bumpversion:file:README.md]
search = cibuildwheel=={current_version}
replace = cibuildwheel=={new_version}
warn_unused_configs = True
warn_redundant_casts = True
[mypy-cibuildwheel]
disallow_any_generics = True
disallow_subclassing_any = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
check_untyped_defs = True
disallow_untyped_decorators = True
no_implicit_optional = True
warn_unused_ignores = True
warn_return_any = True
no_implicit_reexport = True
strict_equality = True
[mypy-pytest,setuptools]
ignore_missing_imports = True
+15 -7
View File
@@ -1,30 +1,38 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pathlib import Path
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
this_directory = Path(__file__).parent
long_description = (this_directory / 'README.md').read_text(encoding='utf-8')
setup(
name='cibuildwheel',
version='0.8.0',
install_requires=['bashlex'],
version='1.5.3',
install_requires=['bashlex!=0.13', 'toml'],
description="Build Python wheels on CI with minimal configuration.",
long_description='For readme please see http://github.com/joerick/cibuildwheel',
long_description=long_description,
long_description_content_type='text/markdown',
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='>=3.6',
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 :: 4 - Beta',
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: BSD License',
'Programming Language :: Python :: Implementation :: CPython',
'Topic :: Software Development :: Build Tools',
-12
View File
@@ -1,12 +0,0 @@
import os
from setuptools import setup, Extension
if os.environ.get('CIBUILDWHEEL', '0') != '1':
raise Exception('CIBUILDWHEEL environment variable is not set to 1')
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
-48
View File
@@ -1,48 +0,0 @@
#include <Python.h>
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
-4
View File
@@ -1,4 +0,0 @@
{
"CIBW_TEST_REQUIRES": "nose",
"CIBW_TEST_COMMAND": "nosetests {project}/test"
}
-7
View File
@@ -1,7 +0,0 @@
from setuptools import setup, Extension
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
-48
View File
@@ -1,48 +0,0 @@
#include <Python.h>
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
-8
View File
@@ -1,8 +0,0 @@
from unittest import TestCase
import spam
class TestSpam(TestCase):
def test_system(self):
self.assertEqual(0, spam.system('python -c "exit(0)"'))
self.assertNotEqual(0, spam.system('python -c "exit(1)"'))
-4
View File
@@ -1,4 +0,0 @@
{
"CIBW_BEFORE_BUILD": "{python} -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && {python} -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"",
"CIBW_BEFORE_BUILD_WINDOWS": "{python} -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && {python} -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\""
}
-27
View File
@@ -1,27 +0,0 @@
from setuptools import setup, Extension
import sys, os
if sys.argv[-1] != '--name':
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step
# is the same one as is currently running.
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt'
with open(version_file) as f:
stored_version = f.read()
print('stored_version', stored_version)
print('sys.version', sys.version)
assert stored_version == sys.version
# check that the executable also was written
executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt'
with open(executable_file) as f:
stored_executable = f.read()
print('stored_executable', stored_executable)
print('sys.executable', sys.executable)
# windows/mac are case insensitive
assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower()
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
-48
View File
@@ -1,48 +0,0 @@
#include <Python.h>
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
-2
View File
@@ -1,2 +0,0 @@
3.6.0 (default, Feb 7 2017, 23:55:32)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]
-3
View File
@@ -1,3 +0,0 @@
{
"CIBW_SKIP": "cp26-* cp33-*"
}
-15
View File
@@ -1,15 +0,0 @@
from setuptools import setup, Extension
import sys
if sys.argv[-1] != '--name':
# explode if run on Python 2.6 or Python 3.3 (these should be skipped)
if sys.version_info[0:2] == (2, 6):
raise Exception('Python 2.6 should be skipped')
if sys.version_info[0:2] == (3, 3):
raise Exception('Python 3.3 should be skipped')
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
-48
View File
@@ -1,48 +0,0 @@
#include <Python.h>
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
-2
View File
@@ -1,2 +0,0 @@
3.6.0 (default, Feb 7 2017, 23:55:32)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]
-4
View File
@@ -1,4 +0,0 @@
{
"CIBW_ENVIRONMENT": "CIBW_TEST_VAR=\"a b c\" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3=\"$(echo 'test string 3')\" PATH=$PATH:/opt/cibw_test_path",
"CIBW_ENVIRONMENT_WINDOWS": "CIBW_TEST_VAR=\"a b c\" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3=\"$(echo 'test string 3')\" PATH=\"$PATH;/opt/cibw_test_path\""
}
-24
View File
@@ -1,24 +0,0 @@
from setuptools import setup, Extension
import sys, os
if sys.argv[-1] != '--name':
# explode if environment isn't correct, as set in CIBW_ENVIRONMENT
CIBW_TEST_VAR = os.environ.get('CIBW_TEST_VAR')
CIBW_TEST_VAR_2 = os.environ.get('CIBW_TEST_VAR_2')
PATH = os.environ.get('PATH')
if CIBW_TEST_VAR != 'a b c':
raise Exception('CIBW_TEST_VAR should equal "a b c". It was "%s"' % CIBW_TEST_VAR)
if CIBW_TEST_VAR_2 != '1':
raise Exception('CIBW_TEST_VAR_2 should equal "1". It was "%s"' % CIBW_TEST_VAR_2)
if '/opt/cibw_test_path' not in PATH:
raise Exception('PATH should contain "/opt/cibw_test_path". It was "%s"' % 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'])],
version="0.1.0",
)
-48
View File
@@ -1,48 +0,0 @@
#include <Python.h>
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
-2
View File
@@ -1,2 +0,0 @@
3.6.0 (default, Feb 7 2017, 23:55:32)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]
-4
View File
@@ -1,4 +0,0 @@
{
"CIBW_MANYLINUX1_X86_64_IMAGE": "dockcross/manylinux-x64",
"CIBW_MANYLINUX1_I686_IMAGE": "dockcross/manylinux-x86"
}
-15
View File
@@ -1,15 +0,0 @@
import os, sys
from setuptools import setup, Extension
if sys.argv[-1] != '--name':
# check that we're running in the correct docker image as specified in the
# environment options CIBW_MANYLINUX1_*_IMAGE
if 'linux' in sys.platform and not os.path.exists('/dockcross'):
raise Exception('/dockcross directory not found. Is this test running in the correct docker image?')
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
-48
View File
@@ -1,48 +0,0 @@
#include <Python.h>
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
+1 -3
View File
@@ -1,3 +1 @@
This folder contains repos that are built by cibuildwheel to test cibuildwheel. Confusing, I know.
Basically, if cibuildwheel can build these projects, we're good.
This folder contains integration tests for cibuildwheel.
View File
+43
View File
@@ -0,0 +1,43 @@
import textwrap
import platform
from . import test_projects
from . import utils
basic_project = test_projects.new_c_project(
setup_py_add=textwrap.dedent('''
import os
if os.environ.get("CIBUILDWHEEL", "0") != "1":
raise Exception("CIBUILDWHEEL environment variable is not set to 1")
''')
)
def test(tmp_path):
project_dir = tmp_path / 'project'
basic_project.generate(project_dir)
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir)
# check that the expected wheels are produced
expected_wheels = utils.expected_wheels('spam', '0.1.0')
assert set(actual_wheels) == set(expected_wheels)
def test_build_identifiers(tmp_path):
project_dir = tmp_path / 'project'
basic_project.generate(project_dir)
# check that the number of expected wheels matches the number of build
# identifiers
# after adding CIBW_MANYLINUX_IMAGE to support manylinux2010, there
# can be multiple wheels for each wheel, though, so we need to limit
# the expected wheels
if platform.machine() in ['x86_64', 'i686']:
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
if '-manylinux' not in w or '-manylinux1' in w]
else:
expected_wheels = utils.expected_wheels('spam', '0.1.0')
build_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir)
assert len(expected_wheels) == len(build_identifiers)
+38
View File
@@ -0,0 +1,38 @@
import os
import textwrap
from . import utils
from . import test_projects
project_with_before_build_asserts = test_projects.new_c_project(
setup_py_add=textwrap.dedent(r'''
# assert that the Python version as written to text_info.txt in the CIBW_BEFORE_ALL step
# is the same one as is currently running.
with open("text_info.txt") as f:
stored_text = f.read()
print("## stored text: " + stored_text)
assert stored_text == "sample text 123"
''')
)
def test(tmp_path):
project_dir = tmp_path / 'project'
project_with_before_build_asserts.generate(project_dir)
with open(os.path.join(project_dir, "text_info.txt"), mode='w') as ff:
print("dummy text", file=ff)
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
# write python version information to a temporary file, this is
# checked in setup.py
'CIBW_BEFORE_ALL': '''python -c "import os;open('{project}/text_info.txt', 'w').write('sample text '+os.environ.get('TEST_VAL', ''))"''',
'CIBW_ENVIRONMENT': "TEST_VAL='123'"
})
# also check that we got the right wheels
os.remove(os.path.join(project_dir, "text_info.txt"))
expected_wheels = utils.expected_wheels('spam', '0.1.0')
assert set(actual_wheels) == set(expected_wheels)
+45
View File
@@ -0,0 +1,45 @@
import textwrap
from . import utils
from . import test_projects
project_with_before_build_asserts = test_projects.new_c_project(
setup_py_add=textwrap.dedent(r'''
import sys, os
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step
# is the same one as is currently running.
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt'
with open(version_file) as f:
stored_version = f.read()
print('stored_version', stored_version)
print('sys.version', sys.version)
assert stored_version == sys.version
# check that the executable also was written
executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt'
with open(executable_file) as f:
stored_executable = f.read()
print('stored_executable', stored_executable)
print('sys.executable', sys.executable)
# windows/mac are case insensitive
assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower()
''')
)
def test(tmp_path):
project_dir = tmp_path / 'project'
project_with_before_build_asserts.generate(project_dir)
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
# write python version information to a temporary file, this is
# checked in setup.py
'CIBW_BEFORE_BUILD': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)"''',
'CIBW_BEFORE_BUILD_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)"''',
})
# also check that we got the right wheels
expected_wheels = utils.expected_wheels('spam', '0.1.0')
assert set(actual_wheels) == set(expected_wheels)
+56
View File
@@ -0,0 +1,56 @@
from . import test_projects
from . import utils
before_test_project = test_projects.new_c_project()
before_test_project.files['test/spam_test.py'] = r'''
import sys
import os
from unittest import TestCase
class TestBeforeTest(TestCase):
def test_version(self):
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_TEST step
# is the same one as is currently running.
# because of use symlinks in MacOS run this test is also need
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt'
with open(version_file) as f:
stored_version = f.read()
print('stored_version', stored_version)
print('sys.version', sys.version)
assert stored_version == sys.version
def test_prefix(self):
# check that the prefix also was written
prefix_file = 'c:\\pythonprefix.txt' if sys.platform == 'win32' else '/tmp/pythonprefix.txt'
with open(prefix_file) as f:
stored_prefix = f.read()
print('stored_prefix', stored_prefix)
print('sys.prefix', sys.prefix)
# Works around path-comparison bugs caused by short-paths on Windows e.g.
# vssadm~1 instead of vssadministrator
assert os.stat(stored_prefix) == os.stat(sys.prefix)
'''
def test(tmp_path):
project_dir = tmp_path / 'project'
before_test_project.generate(project_dir)
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
# write python version information to a temporary file, this is
# checked in setup.py
'CIBW_BEFORE_TEST': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonprefix.txt', 'w').write(sys.prefix)"''',
'CIBW_BEFORE_TEST_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonprefix.txt', 'w').write(sys.prefix)"''',
'CIBW_TEST_REQUIRES': 'nose',
# the 'false ||' bit is to ensure this command runs in a shell on
# mac/linux.
'CIBW_TEST_COMMAND': 'false || nosetests {project}/test',
'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test',
})
# also check that we got the right wheels
expected_wheels = utils.expected_wheels('spam', '0.1.0')
assert set(actual_wheels) == set(expected_wheels)
+30
View File
@@ -0,0 +1,30 @@
import textwrap
from . import utils
from . import test_projects
project_with_skip_asserts = test_projects.new_c_project(
setup_py_add=textwrap.dedent(r'''
# explode if run on Python 2.7 or Python 3.7 (these should be skipped)
if sys.version_info[0:2] == (2, 7):
raise Exception("Python 2.7 should not be built")
if sys.version_info[0:2] == (3, 7):
raise Exception("Python 3.7 should be skipped")
''')
)
def test(tmp_path):
project_dir = tmp_path / 'project'
project_with_skip_asserts.generate(project_dir)
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
'CIBW_BUILD': 'cp3?-*',
'CIBW_SKIP': 'cp37-*',
})
# check that we got the right wheels. There should be no 2.7 or 3.7.
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
if ('-cp3' in w) and ('-cp37' not in w)]
assert set(actual_wheels) == set(expected_wheels)
+209
View File
@@ -0,0 +1,209 @@
import os
import jinja2
import pytest
from . import utils
from .test_projects import TestProject
cpp_test_project = TestProject()
cpp_test_project.files['setup.py'] = jinja2.Template(r'''
from setuptools import Extension, setup
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.cpp'], language="c++", extra_compile_args={{ extra_compile_args }})],
version="0.1.0",
)
''')
cpp_test_project.files['spam.cpp'] = jinja2.Template(r'''
#include <Python.h>
{{ spam_cpp_top_level_add }}
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
''')
cpp11_project = cpp_test_project.copy()
cpp11_project.template_context['extra_compile_args'] = (
['/std:c++11'] if utils.platform == 'windows' else ['-std=c++11']
)
cpp11_project.template_context['spam_cpp_top_level_add'] = '#include <array>'
def test_cpp11(tmp_path):
# This test checks that the C++11 standard is supported
project_dir = tmp_path / 'project'
cpp11_project.generate(project_dir)
# VC++ for Python 2.7 does not support modern standards
add_env = {'CIBW_SKIP': 'cp27-win* pp27-win32'}
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
if 'cp27-cp27m-win' not in w and 'pp27-pypy_73-win32' not in w]
assert set(actual_wheels) == set(expected_wheels)
cpp14_project = cpp_test_project.copy()
cpp14_project.template_context['extra_compile_args'] = (
['/std:c++14'] if utils.platform == 'windows' else ['-std=c++14']
)
cpp14_project.template_context['spam_cpp_top_level_add'] = "int a = 100'000;"
def test_cpp14(tmp_path):
# This test checks that the C++14 standard is supported
project_dir = tmp_path / 'project'
cpp14_project.generate(project_dir)
# VC++ for Python 2.7 does not support modern standards
# The manylinux1 docker image does not have a compiler which supports C++11
add_env = {'CIBW_SKIP': 'cp27-win* pp27-win32'}
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
if 'cp27-cp27m-win' not in w
and 'pp27-pypy_73-win32' not in w]
assert set(actual_wheels) == set(expected_wheels)
cpp17_project = cpp_test_project.copy()
# Python and PyPy 2.7 headers use the `register` keyword, which is forbidden in
# the C++17 standard, so we need the -Wno-register or /wd5033 options
cpp17_project.template_context['extra_compile_args'] = (
['/std:c++17', '/wd5033'] if utils.platform == 'windows' else ['-std=c++17', '-Wno-register']
)
cpp17_project.template_context['spam_cpp_top_level_add'] = r'''
#include <utility>
auto a = std::pair(5.0, false);
'''
def test_cpp17(tmp_path):
# This test checks that the C++17 standard is supported
project_dir = tmp_path / 'project'
cpp17_project.generate(project_dir)
if os.environ.get('APPVEYOR_BUILD_WORKER_IMAGE', '') == 'Visual Studio 2015':
pytest.skip('Visual Studio 2015 does not support C++17')
# Pypy's distutils sets the default compiler to 'msvc9compiler', which
# is too old to support cpp17.
add_env = {'CIBW_SKIP': 'cp27-win* pp??-*'}
if utils.platform == 'macos':
add_env['MACOSX_DEPLOYMENT_TARGET'] = '10.13'
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0', macosx_deployment_target='10.13')
if 'cp27-cp27m-win' not in w
and '-pp' not in w]
assert set(actual_wheels) == set(expected_wheels)
def test_cpp17_py27_modern_msvc_workaround(tmp_path):
# This test checks the workaround for building Python 2.7 wheel with MSVC 14
if utils.platform != 'windows':
pytest.skip('the test is only relevant to the Windows build')
if os.environ.get('APPVEYOR_BUILD_WORKER_IMAGE', '') == 'Visual Studio 2015':
pytest.skip('Visual Studio 2015 does not support C++17')
project_dir = tmp_path / 'project'
cpp17_project.generate(project_dir)
# VC++ for Python 2.7 (i.e., MSVC 9) does not support modern standards
# This is a workaround which forces distutils/setupstools to a newer version
# Wheels compiled need a more modern C++ redistributable installed, which is not
# included with Python: see documentation for more info
# DISTUTILS_USE_SDK and MSSdk=1 tell distutils/setuptools that we are adding
# MSVC's compiler, tools, and libraries to PATH ourselves
add_env = {'DISTUTILS_USE_SDK': '1', 'MSSdk': '1'}
# Use existing setuptools code to run Visual Studio's vcvarsall.bat and get the
# necessary environment variables, since running vcvarsall.bat in a subprocess
# does not keep the relevant environment variables
# There are different environment variables for 32-bit/64-bit targets, so we
# need to run cibuildwheel twice, once for 32-bit with `vcvarsall.bat x86, and
# once for 64-bit with `vcvarsall.bat x64`
# In a normal CI setup, just run vcvarsall.bat before running cibuildwheel and set
# DISTUTILS_USE_SDK and MSSdk
import setuptools
def add_vcvars(prev_env, platform):
vcvarsall_env = setuptools.msvc.msvc14_get_vc_env(platform)
env = prev_env.copy()
for vcvar in ['path', 'include', 'lib']:
env[vcvar] = vcvarsall_env[vcvar]
return env
add_env_x86 = add_vcvars(add_env, 'x86')
add_env_x86['CIBW_BUILD'] = '?p27-win32'
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env_x86)
add_env_x64 = add_vcvars(add_env, 'x64')
add_env_x64['CIBW_BUILD'] = 'cp27-win_amd64'
actual_wheels += utils.cibuildwheel_run(project_dir, add_env=add_env_x64)
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
if 'cp27-cp27m-win' in w
or 'pp27-pypy_73-win32' in w]
assert set(actual_wheels) == set(expected_wheels)
+159
View File
@@ -0,0 +1,159 @@
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)
+41
View File
@@ -0,0 +1,41 @@
import platform
import textwrap
import pytest
from . import utils
from . import test_projects
dockcross_only_project = test_projects.new_c_project(
setup_py_add=textwrap.dedent(r'''
import os, sys
# check that we're running in the correct docker image as specified in the
# environment options CIBW_MANYLINUX1_*_IMAGE
if "linux" in sys.platform and not os.path.exists("/dockcross"):
raise Exception(
"/dockcross directory not found. Is this test running in the correct docker image?"
)
''')
)
def test(tmp_path):
if utils.platform != 'linux':
pytest.skip('the test is only relevant to the linux build')
if platform.machine() not in ['x86_64', 'i686']:
pytest.skip('this test is currently only possible on x86_64/i686 due to availability of alternative images')
project_dir = tmp_path / 'project'
dockcross_only_project.generate(project_dir)
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
'CIBW_MANYLINUX_X86_64_IMAGE': 'dockcross/manylinux2010-x64',
'CIBW_MANYLINUX_I686_IMAGE': 'dockcross/manylinux2010-x86',
'CIBW_SKIP': 'pp*',
})
# also check that we got the right wheels built
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
if '-pp' not in w]
assert set(actual_wheels) == set(expected_wheels)
+74
View File
@@ -0,0 +1,74 @@
import os
import pytest
import subprocess
import textwrap
from . import utils
from . import test_projects
project_with_environment_asserts = test_projects.new_c_project(
setup_py_add=textwrap.dedent(r'''
import os
# explode if environment isn't correct, as set in CIBW_ENVIRONMENT
CIBW_TEST_VAR = os.environ.get("CIBW_TEST_VAR")
CIBW_TEST_VAR_2 = os.environ.get("CIBW_TEST_VAR_2")
PATH = os.environ.get("PATH")
if CIBW_TEST_VAR != "a b c":
raise Exception('CIBW_TEST_VAR should equal "a b c". It was "%s"' % CIBW_TEST_VAR)
if CIBW_TEST_VAR_2 != "1":
raise Exception('CIBW_TEST_VAR_2 should equal "1". It was "%s"' % CIBW_TEST_VAR_2)
if "/opt/cibw_test_path" not in PATH:
raise Exception('PATH should contain "/opt/cibw_test_path". It was "%s"' % PATH)
if "$PATH" in PATH:
raise Exception('$PATH should be expanded in PATH. It was "%s"' % PATH)
''')
)
def test(tmp_path):
project_dir = tmp_path / 'project'
project_with_environment_asserts.generate(project_dir)
# write some information into the CIBW_ENVIRONMENT, for expansion and
# insertion into the environment by cibuildwheel. This is checked
# in setup.py
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
'CIBW_ENVIRONMENT': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH=$PATH:/opt/cibw_test_path''',
'CIBW_ENVIRONMENT_WINDOWS': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH="$PATH;/opt/cibw_test_path"''',
})
# also check that we got the right wheels built
expected_wheels = utils.expected_wheels('spam', '0.1.0')
assert set(actual_wheels) == set(expected_wheels)
def test_overridden_path(tmp_path, capfd):
project_dir = tmp_path / 'project'
output_dir = tmp_path / 'output'
project = test_projects.new_c_project()
project.generate(project_dir)
output_dir.mkdir()
# mess up PATH, somehow
with pytest.raises(subprocess.CalledProcessError):
if utils.platform == 'linux':
utils.cibuildwheel_run(project_dir, output_dir=output_dir, add_env={
'CIBW_BEFORE_ALL': 'mkdir new_path && touch new_path/python && chmod +x new_path/python',
'CIBW_ENVIRONMENT': '''PATH="$(pwd)/new_path:$PATH"''',
})
else:
new_path = tmp_path / 'another_bin'
new_path.mkdir()
(new_path / 'python').touch(mode=0o777)
utils.cibuildwheel_run(project_dir, output_dir=output_dir, add_env={
'NEW_PATH': str(new_path),
'CIBW_ENVIRONMENT': f'''PATH="$NEW_PATH{os.pathsep}$PATH"''',
})
assert len(os.listdir(output_dir)) == 0
captured = capfd.readouterr()
assert "python available on PATH doesn't match our installed instance" in captured.err
+71
View File
@@ -0,0 +1,71 @@
import platform
import textwrap
import pytest
from . import utils
from . import test_projects
# TODO: specify these at runtime according to manylinux_image
project_with_manylinux_symbols = test_projects.new_c_project(
spam_c_top_level_add=textwrap.dedent(r'''
#include <malloc.h>
#if !defined(__GLIBC_PREREQ)
#error "Must run on a glibc linux environment"
#endif
#if !__GLIBC_PREREQ(2, 5) /* manylinux1 is glibc 2.5 */
#error "Must run on a glibc >= 2.5 linux environment"
#endif
'''),
spam_c_function_add=textwrap.dedent(r'''
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 17) /* manylinux2014 is glibc 2.17 */
// secure_getenv is only available in manylinux2014, ensuring
// that only a manylinux2014 wheel is produced
secure_getenv("NON_EXISTING_ENV_VARIABLE");
#elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10) /* manylinux2010 is glibc 2.12 */
// malloc_info is only available on manylinux2010+
malloc_info(0, stdout);
#endif
'''),
)
@pytest.mark.parametrize('manylinux_image', ['manylinux1', 'manylinux2010', 'manylinux2014'])
def test(manylinux_image, tmp_path):
if utils.platform != 'linux':
pytest.skip('the docker test is only relevant to the linux build')
elif platform.machine() not in ['x86_64', 'i686']:
if manylinux_image in ['manylinux1', 'manylinux2010']:
pytest.skip("manylinux1 and 2010 doesn't exist for non-x86 architectures")
project_dir = tmp_path / 'project'
project_with_manylinux_symbols.generate(project_dir)
# build the wheels
# CFLAGS environment variable is necessary to fail on 'malloc_info' (on manylinux1) during compilation/linking,
# rather than when dynamically loading the Python
add_env = {
'CIBW_ENVIRONMENT': 'CFLAGS="$CFLAGS -Werror=implicit-function-declaration"',
'CIBW_MANYLINUX_X86_64_IMAGE': manylinux_image,
'CIBW_MANYLINUX_I686_IMAGE': manylinux_image,
'CIBW_MANYLINUX_PYPY_X86_64_IMAGE': manylinux_image,
'CIBW_MANYLINUX_AARCH64_IMAGE': manylinux_image,
'CIBW_MANYLINUX_PPC64LE_IMAGE': manylinux_image,
'CIBW_MANYLINUX_S390X_IMAGE': manylinux_image,
}
if manylinux_image == 'manylinux1':
# We don't have a manylinux1 image for PyPy
add_env['CIBW_SKIP'] = 'pp*'
elif manylinux_image == 'manylinux2014':
# We don't have a manylinux2014 image for PyPy (yet?)
add_env['CIBW_SKIP'] = 'cp27* pp*' # Python 2.7 not available on manylinux2014
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0', manylinux_versions=[manylinux_image])]
if manylinux_image == 'manylinux2014':
expected_wheels = [w for w in expected_wheels if '-cp27' not in w]
if manylinux_image in ['manylinux1', 'manylinux2014']:
expected_wheels = [w for w in expected_wheels if '-pp' not in w]
assert set(actual_wheels) == set(expected_wheels)
+49
View File
@@ -0,0 +1,49 @@
import textwrap
from . import test_projects
from . import utils
basic_project = test_projects.new_c_project(
setup_py_add=textwrap.dedent(
"""
# Will fail if PEP 518 does work
import sys
import requests
if sys.version_info < (3, 6, 0):
assert requests.__version__ == "2.22.0", "Requests found but wrong version ({0})".format(requests.__version__)
else:
assert requests.__version__ == "2.23.0", "Requests found but wrong version ({0})".format(requests.__version__)
# Just making sure environment is still set
import os
if os.environ.get("CIBUILDWHEEL", "0") != "1":
raise Exception("CIBUILDWHEEL environment variable is not set to 1")
"""
)
)
basic_project.files[
"pyproject.toml"
] = """
[build-system]
requires = [
"setuptools >= 42",
"wheel",
"requests==2.22.0; python_version<'3.6'",
"requests==2.23.0; python_version>='3.6'"
]
build-backend = "setuptools.build_meta"
"""
def test_pep518(tmp_path):
project_dir = tmp_path / "project"
basic_project.generate(project_dir)
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir)
# check that the expected wheels are produced
expected_wheels = utils.expected_wheels("spam", "0.1.0")
assert set(actual_wheels) == set(expected_wheels)
+2
View File
@@ -0,0 +1,2 @@
from .base import TestProject # noqa
from .c import new_c_project # noqa
+38
View File
@@ -0,0 +1,38 @@
import importlib
import subprocess
import sys
import tempfile
from argparse import ArgumentParser
from pathlib import Path
def main():
parser = ArgumentParser(
prog="python -m test.test_projects",
description='Generate a test project to check it out'
)
parser.add_argument('PROJECT', help='''
Python path to a project object. E.g. test.test_0_basic.basic_project
''')
options = parser.parse_args()
module, _, name = options.PROJECT.rpartition('.')
project = getattr(importlib.import_module(module), name)
project_dir = Path(tempfile.mkdtemp())
project.generate(project_dir)
print('Project generated at', project_dir)
print()
if sys.platform == 'darwin':
subprocess.check_call(['open', '--', project_dir])
elif sys.platform == 'linux2':
subprocess.check_call(['xdg-open', '--', project_dir])
elif sys.platform == 'win32':
subprocess.check_call(['explorer', project_dir])
if __name__ == '__main__':
main()
+43
View File
@@ -0,0 +1,43 @@
from pathlib import Path
import jinja2
from typing import Union, Dict, Any
FilesDict = Dict[str, Union[str, jinja2.Template]]
TemplateContext = Dict[str, Any]
class TestProject:
'''
An object that represents a project that can be built by cibuildwheel.
Can be manipulated in tests by changing `files` and `template_context`.
Write out to the filesystem using `generate`.
'''
__test__ = False # Have pytest ignore this class on `from .test_projects import TestProject`
files: FilesDict
template_context: TemplateContext
def __init__(self):
self.files = {}
self.template_context = {}
def generate(self, path: Path):
for filename, content in self.files.items():
file_path = path / filename
file_path.parent.mkdir(parents=True, exist_ok=True)
with file_path.open('w', encoding='utf8') as f:
if isinstance(content, jinja2.Template):
content = content.render(self.template_context)
f.write(content)
def copy(self):
other = TestProject()
other.files = self.files.copy()
other.template_context = self.template_context.copy()
return other
+100
View File
@@ -0,0 +1,100 @@
import jinja2
from .base import TestProject
SPAM_C_TEMPLATE = r'''
#include <Python.h>
{{ spam_c_top_level_add }}
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
{{ spam_c_function_add | indent(4) }}
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
'''
SETUP_PY_TEMPLATE = r'''
from setuptools import setup, Extension
{{ setup_py_add }}
setup(
ext_modules=[Extension('spam', sources=['spam.c'])],
{{ setup_py_setup_args_add | indent(4) }}
)
'''
SETUP_CFG_TEMPLATE = r'''
[metadata]
name = spam
version = 0.1.0
{{ setup_cfg_add }}
'''
def new_c_project(*, spam_c_top_level_add='', spam_c_function_add='', setup_py_add='',
setup_py_setup_args_add='', setup_cfg_add=''):
project = TestProject()
project.files.update({
'spam.c': jinja2.Template(SPAM_C_TEMPLATE),
'setup.py': jinja2.Template(SETUP_PY_TEMPLATE),
'setup.cfg': jinja2.Template(SETUP_CFG_TEMPLATE),
})
project.template_context.update({
'spam_c_top_level_add': spam_c_top_level_add,
'spam_c_function_add': spam_c_function_add,
'setup_py_add': setup_py_add,
'setup_py_setup_args_add': setup_py_setup_args_add,
'setup_cfg_add': setup_cfg_add,
})
return project
+34
View File
@@ -0,0 +1,34 @@
import textwrap
from . import utils
from . import test_projects
project_with_ssl_tests = test_projects.new_c_project(
setup_py_add=textwrap.dedent(r'''
import ssl
import sys
if sys.version_info[0] == 2:
from urllib2 import urlopen
else:
from urllib.request import urlopen
if sys.version_info[0:2] == (3, 3):
data = urlopen("https://www.nist.gov")
else:
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
data = urlopen("https://www.nist.gov", context=context)
''')
)
def test(tmp_path):
# this test checks that SSL is working in the build environment using
# some checks in setup.py.
project_dir = tmp_path / 'project'
project_with_ssl_tests.generate(project_dir)
actual_wheels = utils.cibuildwheel_run(project_dir)
expected_wheels = utils.expected_wheels('spam', '0.1.0')
assert set(actual_wheels) == set(expected_wheels)
+54
View File
@@ -0,0 +1,54 @@
from pathlib import Path
import jinja2
from . import utils
from .test_projects import TestProject
from .test_projects.c import SPAM_C_TEMPLATE
subdir_package_project = TestProject()
subdir_package_project.files['src/spam/spam.c'] = jinja2.Template(SPAM_C_TEMPLATE)
subdir_package_project.template_context['spam_c_top_level_add'] = ''
subdir_package_project.template_context['spam_c_function_add'] = ''
subdir_package_project.files['src/spam/setup.py'] = r'''
from setuptools import Extension, setup
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
'''
subdir_package_project.files['src/spam/test/run_tests.py'] = r'''
print('run_tests.py executed!')
'''
subdir_package_project.files['bin/before_build.py'] = r'''
print('before_build.py executed!')
'''
def test(capfd, tmp_path):
project_dir = tmp_path / 'project'
subdir_package_project.generate(project_dir)
package_dir = Path('src', 'spam')
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir, package_dir=package_dir, add_env={
'CIBW_BEFORE_BUILD': 'python {project}/bin/before_build.py',
'CIBW_TEST_COMMAND': 'python {package}/test/run_tests.py',
# this shouldn't depend on the version of python, so build only CPython 3.6
'CIBW_BUILD': 'cp36-*',
})
# check that the expected wheels are produced
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
if 'cp36' in w]
assert set(actual_wheels) == set(expected_wheels)
captured = capfd.readouterr()
assert "before_build.py executed!" in captured.out
assert "run_tests.py executed!" in captured.out

Some files were not shown because too many files have changed in this diff Show More