Drop Python 2.7

This commit is contained in:
mayeut
2021-05-07 11:54:27 -04:00
committed by Henry Schreiner
parent bf31d18fbb
commit 3e22cd9a41
28 changed files with 145 additions and 506 deletions
+3 -5
View File
@@ -24,22 +24,20 @@ What does it do?
| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | manylinux x86_64 | manylinux i686 | manylinux aarch64 | manylinux ppc64le | manylinux s390x |
|---|---|---|---|---|---|---|---|---|---|
| CPython 2.7 | ✅ | | ✅¹ | ✅¹ | ✅ | ✅ | | | |
| CPython 3.6 | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.7 | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.8 | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| PyPy 2.7 v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
| PyPy 3.6 v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
| PyPy 3.7 (beta) v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
<sup>¹ Only using a workaround with a newer compiler; Microsoft removed the 2008 compiler for Python 2.7 in April 2021.</sup><br>
- Builds manylinux, macOS 10.9+, and Windows wheels for CPython and PyPy
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, and GitLab CI
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
- Runs your library's tests against the wheel-installed version of your library
See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.x/) if you need to build unsupported versions of Python, such as Python 2.
Usage
-----
@@ -98,7 +96,7 @@ jobs:
path: ./wheelhouse/*.whl
```
For more information, including building on Python 2, PyPI deployment, and the use of other CI services or the dedicated GitHub Action, check out the [documentation](https://cibuildwheel.readthedocs.org) and the [examples](https://github.com/joerick/cibuildwheel/tree/master/examples).
For more information, including PyPI deployment, and the use of other CI services or the dedicated GitHub Action, check out the [documentation](https://cibuildwheel.readthedocs.org) and the [examples](https://github.com/joerick/cibuildwheel/tree/master/examples).
Options
-------
+5 -6
View File
@@ -17,7 +17,7 @@ os.chdir("..")
# regenerate the constraints files
os.environ["CUSTOM_COMPILE_COMMAND"] = "bin/update_dependencies.py"
PYTHON_VERSIONS = ["27", "36", "37", "38", "39"]
PYTHON_VERSIONS = ["36", "37", "38", "39"]
if "--no-docker" in sys.argv:
for python_version in PYTHON_VERSIONS:
@@ -32,8 +32,7 @@ if "--no-docker" in sys.argv:
check=True,
)
else:
# latest manylinux2010 image with cpython 2.7 support
image_runner = "quay.io/pypa/manylinux2010_x86_64:2021-02-06-3d322a5"
image_runner = "quay.io/pypa/manylinux2010_x86_64:latest"
subprocess.run(["docker", "pull", image_runner], check=True)
for python_version in PYTHON_VERSIONS:
abi_flags = "" if int(python_version) >= 38 else "m"
@@ -77,9 +76,9 @@ class Image(NamedTuple):
images = [
Image("manylinux1", "x86_64", "quay.io/pypa/manylinux1_x86_64", None),
Image("manylinux1", "i686", "quay.io/pypa/manylinux1_i686", None),
# Images for manylinux2010 are pinned to the latest tag supporting cp27
Image("manylinux2010", "x86_64", "quay.io/pypa/manylinux2010_x86_64", "2021-02-06-3d322a5"),
Image("manylinux2010", "i686", "quay.io/pypa/manylinux2010_i686", "2021-02-06-3d322a5"),
# 2010 images
Image("manylinux2010", "x86_64", "quay.io/pypa/manylinux2010_x86_64", None),
Image("manylinux2010", "i686", "quay.io/pypa/manylinux2010_i686", None),
Image("manylinux2010", "pypy_x86_64", "pypywheels/manylinux2010-pypy_x86_64", None),
# 2014 images
Image("manylinux2014", "x86_64", "quay.io/pypa/manylinux2014_x86_64", None),
+1 -2
View File
@@ -124,8 +124,7 @@ def build(options: BuildOptions) -> None:
dependency_constraint_flags: List[PathOrStr] = []
if config.identifier.startswith("pp"):
# Patch PyPy to make sure headers get installed into a venv
patch_version = "_27" if config.version == "2.7" else ""
patch_path = resources_dir / f"pypy_venv{patch_version}.patch"
patch_path = resources_dir / "pypy_venv.patch"
patch_docker_path = PurePath("/pypy_venv.patch")
docker.copy_into(patch_path, patch_docker_path)
try:
+5 -6
View File
@@ -141,7 +141,7 @@ def install_cpython(version: str, url: str) -> Path:
# if this version of python isn't installed, get it from python.org and install
python_package_identifier = f"org.python.Python.PythonFramework-{version}"
python_executable = "python3" if version[0] == "3" else "python"
python_executable = "python3"
installation_bin_path = Path(f"/Library/Frameworks/Python.framework/Versions/{version}/bin")
if python_package_identifier not in installed_system_packages:
@@ -151,7 +151,7 @@ def install_cpython(version: str, url: str) -> Path:
call(["sudo", "installer", "-pkg", "/tmp/Python.pkg", "-target", "/"])
call(["sudo", str(installation_bin_path / python_executable), str(install_certifi_script)])
pip_executable = "pip3" if version[0] == "3" else "pip"
pip_executable = "pip3"
make_symlinks(installation_bin_path, python_executable, pip_executable)
return installation_bin_path
@@ -168,13 +168,12 @@ def install_pypy(version: str, url: str) -> Path:
download(url, downloaded_tar_bz2)
call(["tar", "-C", "/tmp", "-xf", downloaded_tar_bz2])
# Patch PyPy to make sure headers get installed into a venv
patch_version = "_27" if version == "2.7" else ""
patch_path = resources_dir / f"pypy_venv{patch_version}.patch"
patch_path = resources_dir / "pypy_venv.patch"
call(["patch", "--force", "-p1", "-d", installation_path, "-i", patch_path])
installation_bin_path = installation_path / "bin"
python_executable = "pypy3" if version[0] == "3" else "pypy"
pip_executable = "pip3" if version[0] == "3" else "pip"
python_executable = "pypy3"
pip_executable = "pip3"
make_symlinks(installation_bin_path, python_executable, pip_executable)
return installation_bin_path
@@ -1,18 +1,13 @@
[linux]
python_configurations = [
{ identifier = "cp27-manylinux_x86_64", version = "2.7", path_str = "/opt/python/cp27-cp27m" },
{ identifier = "cp27-manylinux_x86_64", version = "2.7", path_str = "/opt/python/cp27-cp27mu" },
{ identifier = "cp36-manylinux_x86_64", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_x86_64", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_x86_64", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-manylinux_x86_64", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp27-manylinux_i686", version = "2.7", path_str = "/opt/python/cp27-cp27m" },
{ identifier = "cp27-manylinux_i686", version = "2.7", path_str = "/opt/python/cp27-cp27mu" },
{ identifier = "cp36-manylinux_i686", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_i686", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_i686", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-manylinux_i686", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "pp27-manylinux_x86_64", version = "2.7", path_str = "/opt/python/pp27-pypy_73" },
{ identifier = "pp36-manylinux_x86_64", version = "3.6", path_str = "/opt/python/pp36-pypy36_pp73" },
{ identifier = "pp37-manylinux_x86_64", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
{ identifier = "cp36-manylinux_aarch64", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
@@ -31,22 +26,18 @@ python_configurations = [
[macos]
python_configurations = [
{ identifier = "cp27-macosx_x86_64", version = "2.7", url = "https://www.python.org/ftp/python/2.7.18/python-2.7.18-macosx10.9.pkg" },
{ identifier = "cp36-macosx_x86_64", version = "3.6", url = "https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.9.pkg" },
{ identifier = "cp37-macosx_x86_64", version = "3.7", url = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-macosx10.9.pkg" },
{ identifier = "cp38-macosx_x86_64", version = "3.8", url = "https://www.python.org/ftp/python/3.8.9/python-3.8.9-macosx10.9.pkg" },
{ identifier = "cp39-macosx_x86_64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" },
{ identifier = "cp39-macosx_arm64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" },
{ identifier = "cp39-macosx_universal2", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" },
{ identifier = "pp27-macosx_x86_64", version = "2.7", url = "https://downloads.python.org/pypy/pypy2.7-v7.3.3-osx64.tar.bz2" },
{ identifier = "pp36-macosx_x86_64", version = "3.6", url = "https://downloads.python.org/pypy/pypy3.6-v7.3.3-osx64.tar.bz2" },
{ identifier = "pp37-macosx_x86_64", version = "3.7", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.3-osx64.tar.bz2" },
]
[windows]
python_configurations = [
{ identifier = "cp27-win32", version = "2.7.18", arch = "32" },
{ identifier = "cp27-win_amd64", version = "2.7.18", arch = "64" },
{ identifier = "cp36-win32", version = "3.6.8", arch = "32" },
{ identifier = "cp36-win_amd64", version = "3.6.8", arch = "64" },
{ identifier = "cp37-win32", version = "3.7.9", arch = "32" },
@@ -55,7 +46,6 @@ python_configurations = [
{ identifier = "cp38-win_amd64", version = "3.8.9", arch = "64" },
{ identifier = "cp39-win32", version = "3.9.4", arch = "32" },
{ identifier = "cp39-win_amd64", version = "3.9.4", arch = "64" },
{ identifier = "pp27-win32", version = "2.7", arch = "32", url = "https://downloads.python.org/pypy/pypy2.7-v7.3.3-win32.zip" },
{ identifier = "pp36-win32", version = "3.6", arch = "32", url = "https://downloads.python.org/pypy/pypy3.6-v7.3.3-win32.zip" },
{ identifier = "pp37-win32", version = "3.7", arch = "32", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.3-win32.zip" },
]
@@ -1,55 +0,0 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# bin/update_dependencies.py
#
appdirs==1.4.4
# via virtualenv
configparser==4.0.2
# via importlib-metadata
contextlib2==0.6.0.post1
# via
# importlib-metadata
# importlib-resources
delocate==0.8.2
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.1
# via virtualenv
filelock==3.0.12
# via virtualenv
importlib-metadata==2.1.1
# via virtualenv
importlib-resources==3.3.1
# via virtualenv
pathlib2==2.3.5
# via
# importlib-metadata
# importlib-resources
# virtualenv
scandir==1.10.0
# via pathlib2
singledispatch==3.6.1
# via importlib-resources
six==1.15.0
# via
# pathlib2
# virtualenv
typing==3.7.4.3
# via importlib-resources
virtualenv==20.4.3
# via -r cibuildwheel/resources/constraints.in
wheel==0.36.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.3.4
# via -r cibuildwheel/resources/constraints.in
setuptools==44.1.1
# via -r cibuildwheel/resources/constraints.in
@@ -24,9 +24,6 @@ STAT_0o775 = (
| stat.S_IXOTH
)
if sys.version_info[0] == 2:
FileNotFoundError = OSError
def main():
openssl_dir, openssl_cafile = os.path.split(ssl.get_default_verify_paths().openssl_cafile)
@@ -1,12 +1,12 @@
[x86_64]
manylinux1 = quay.io/pypa/manylinux1_x86_64:2021-04-05-14df3a6
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2021-02-06-3d322a5
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2021-04-05-b4fd19d
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2021-04-05-b4fd19d
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2021-04-05-b4fd19d
[i686]
manylinux1 = quay.io/pypa/manylinux1_i686:2021-04-05-14df3a6
manylinux2010 = quay.io/pypa/manylinux2010_i686:2021-02-06-3d322a5
manylinux2010 = quay.io/pypa/manylinux2010_i686:2021-04-05-b4fd19d
manylinux2014 = quay.io/pypa/manylinux2014_i686:2021-04-05-b4fd19d
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2021-04-05-b4fd19d
-27
View File
@@ -1,27 +0,0 @@
--- a/lib-python/2.7/sysconfig.py
+++ b/lib-python/2.7/sysconfig.py
@@ -553,9 +553,6 @@ def get_config_vars(*args):
if type_ == imp.C_EXTENSION:
_CONFIG_VARS['SOABI'] = suffix.split('.')[1]
break
- _CONFIG_VARS['INCLUDEPY'] = os.path.join(_CONFIG_VARS['prefix'],
- 'include')
-
if args:
vals = []
for name in args:
--- a/lib_pypy/_sysconfigdata.py
+++ b/lib_pypy/_sysconfigdata.py
@@ -1,5 +1,11 @@
-import imp
+import imp, os
+
+mybase = os.path.dirname(os.path.dirname(__file__))
build_time_vars = {
"SO": [s[0] for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION][0]
}
+
+build_time_vars['LIBDIR'] = os.path.join(mybase, 'lib')
+build_time_vars['INCLUDEPY'] = os.path.join(mybase, 'include')
+
+1 -1
View File
@@ -163,7 +163,7 @@ class DependencyConstraints:
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
# ./constraints.txt is the base, look for ./constraints-python36.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)
+2 -12
View File
@@ -22,8 +22,6 @@ from .util import (
read_python_configs,
)
IS_RUNNING_ON_AZURE = Path("C:\\hostedtoolcache").exists()
def call(
args: Sequence[PathOrStr], env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None
@@ -40,7 +38,7 @@ def shell(command: str, env: Optional[Dict[str, str]] = None, cwd: Optional[str]
def get_nuget_args(version: str, arch: str) -> List[str]:
python_name = "python" if version[0] == "3" else "python2"
python_name = "python"
if arch == "32":
python_name += "x86"
return [
@@ -75,13 +73,6 @@ def get_python_configurations(
"64": Architecture.AMD64,
}
# Only supported with custom compiler, since MS removed the 2008 compiler download
custom_compiler = os.environ.get("DISTUTILS_USE_SDK") and os.environ.get("MSSdk")
if not custom_compiler:
python_configurations = [
c for c in python_configurations if not c.version.startswith("2.7")
]
# skip builds as required
python_configurations = [
c
@@ -116,8 +107,7 @@ def install_pypy(version: str, arch: str, url: str) -> Path:
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)
(installation_path / "python.exe").symlink_to(installation_path / "pypy3.exe")
return installation_path
-3
View File
@@ -71,7 +71,6 @@ This has been moved to using docker, so you only need the following instructions
The dependency update script in the next section requires multiple python versions installed. One way to do this is to use `pyenv`:
```bash
pyenv install 2.7.18
pyenv install 3.6.11
pyenv install 3.7.8
# Optionally add 3.8 and make it the local version;
@@ -81,8 +80,6 @@ pyenv install 3.7.8
Then, you need to make the required virtual environments:
```bash
$(pyenv prefix 2.7.18)/bin/python -m pip install virtualenv
$(pyenv prefix 2.7.18)/bin/python -m virtualenv env27
$(pyenv prefix 3.6.11)/bin/python -m venv env36
$(pyenv prefix 3.7.8)/bin/python -m venv env37
```
-46
View File
@@ -5,10 +5,6 @@ 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
@@ -27,45 +23,3 @@ To get C++17 support, Xcode 9.3+ is needed, requiring at least macOS 10.13 on th
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
In previous years, Microsoft distributed a compiler toolchain called 'Visual C++ for Python 2.7', which was a distribution of MSVC 2008 that was created to make it easier to build Python 2.7 extensions on Windows, because it was fully compatible with the toolchain that built Python 2.7.
This toolchain does not support modern C++ standards (i.e., C++11 and later). And it is hard to find this toolchain these days, since Microsoft removed the download for the required Visual Studio 2008 needed to build a native extension in April, 2021. So, by default, cibuildwheel does not attempt to build Python 2.7 extensions on Windows.
There is an optional workaround, 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
```
+5 -30
View File
@@ -14,6 +14,10 @@ If your wheel didn't compile, check the list below for some debugging tips.
- MacOS: calling cibuildwheel from a python3 script and getting a `ModuleNotFoundError`? Due to a (fixed) [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.
### Building Python 2.7 / PyPy2 wheels
See the [cibuildwheel verison 1 docs](https://cibuildwheel.readthedocs.io/en/1.x/) for information about building Python 2.7 or PyPy2 wheels. There are lots of tricks and workaround there that are no longer required for Python 3 in cibuildwheel 2.
### 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:
@@ -136,35 +140,6 @@ Here's an example GitHub Actions workflow with a job that builds for Apple Silic
{% include "../examples/github-apple-silicon.yml" %}
```
### Windows and Python 2.7
Building 2.7 extensions on Windows is difficult, because the VS 2008 compiler that was used for the original Python compilation was discontinued in 2018, and has since been removed from Microsoft's downloads. Most people choose to not build Windows 2.7 wheels, or to override the compiler to something more modern.
To override, you need to have a modern compiler toolchain activated, and set `DISTUTILS_USE_SDK=1` and `MSSdk=1`. For example, on GitHub Actions, you would add these steps:
```yaml
- name: Prepare compiler environment for Windows
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Set Windows environment variables
if: runner.os == 'Windows'
shell: bash
run: |
echo "DISTUTILS_USE_SDK=1" >> $GITHUB_ENV
echo "MSSdk=1" >> $GITHUB_ENV
# invoke cibuildwheel...
```
cibuildwheel will not try to build 2.7 on Windows unless it detects that the above two variables are set. Note that changing to a more modern compiler will mean your wheel picks up a runtime dependency to a different [Visual C++ Redistributable][]. You also need to be [a bit careful][] in designing your extension; some major binding tools like pybind11 do this for you.
More on setting a custom Windows toolchain in our docs on modern C++ standards [here](cpp_standards.md#windows-and-python-27).
[Visual C++ Redistributable]: https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0
[a bit careful]: https://pybind11.readthedocs.io/en/stable/faq.html#working-with-ancient-visual-studio-2008-builds-on-windows
### Building packages with optional C extensions
@@ -206,7 +181,7 @@ python3 -m twine upload wheelhouse/*.whl
### 'ImportError: DLL load failed: The specific module could not be found' error on Windows
Visual Studio and MSVC link the compiled binary wheels to the Microsoft Visual C++ Runtime. Normally, these are included with Python, but when compiling with a newer version of Visual Studio, it is possible users will run into problems on systems that do not have these runtime libraries installed. The solution is to ask users to download the corresponding Visual C++ Redistributable from the [Microsoft website](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) and install it. Since a Python installation normally includes these VC++ Redistributable files for [the version of the MSVC compiler used to compile Python](https://wiki.python.org/moin/WindowsCompilers), this is typically only a problem when compiling a Python 2.7 C extension with a newer compiler, e.g. to support a modern C++ standard (see [the section on modern C++ standards for Python 2.7](cpp_standards.md#windows-and-python-27) for more details).
Visual Studio and MSVC link the compiled binary wheels to the Microsoft Visual C++ Runtime. Normally, these are included with Python, but when compiling with a newer version of Visual Studio, it is possible users will run into problems on systems that do not have these runtime libraries installed. The solution is to ask users to download the corresponding Visual C++ Redistributable from the [Microsoft website](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) and install it. Since a Python installation normally includes these VC++ Redistributable files for [the version of the MSVC compiler used to compile Python](https://wiki.python.org/moin/WindowsCompilers), this is typically only a problem when compiling a Python C extension with a newer compiler.
Additionally, Visual Studio 2019 started linking to an even newer DLL, `VCRUNTIME140_1.dll`, besides the `VCRUNTIME140.dll` that is included with recent Python versions (starting from Python 3.5; see [here](https://wiki.python.org/moin/WindowsCompilers) for more details on the corresponding Visual Studio & MSVC versions used to compile the different Python versions). To avoid this extra dependency on `VCRUNTIME140_1.dll`, the [`/d2FH4-` flag](https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/) can be added to the MSVC invocations (check out [this issue](https://github.com/joerick/cibuildwheel/issues/423) for details and references).
+15 -20
View File
@@ -120,12 +120,10 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
| | macOS | Windows | Manylinux Intel | Manylinux Other |
|--------------|---------------------------------------------------------------------|-------------------------------|-----------------------------------------------|----------------------------------------------------------------------------|
| Python 2.7 | cp27-macosx_x86_64 | cp27-win_amd64<br/>cp27-win32 | cp27-manylinux_x86_64<br/>cp27-manylinux_i686 | |
| Python 3.6 | cp36-macosx_x86_64 | cp36-win_amd64<br/>cp36-win32 | cp36-manylinux_x86_64<br/>cp36-manylinux_i686 | cp36-manylinux_aarch64<br/>cp36-manylinux_ppc64le<br/>cp36-manylinux_s390x |
| Python 3.7 | cp37-macosx_x86_64 | cp37-win_amd64<br/>cp37-win32 | cp37-manylinux_x86_64<br/>cp37-manylinux_i686 | cp37-manylinux_aarch64<br/>cp37-manylinux_ppc64le<br/>cp37-manylinux_s390x |
| Python 3.8 | cp38-macosx_x86_64 | cp38-win_amd64<br/>cp38-win32 | cp38-manylinux_x86_64<br/>cp38-manylinux_i686 | cp38-manylinux_aarch64<br/>cp38-manylinux_ppc64le<br/>cp38-manylinux_s390x |
| Python 3.9 | cp39-macosx_x86_64<br/>cp39-macosx_universal2<br/>cp39-macosx_arm64 | cp39-win_amd64<br/>cp39-win32 | cp39-manylinux_x86_64<br/>cp39-manylinux_i686 | cp39-manylinux_aarch64<br/>cp39-manylinux_ppc64le<br/>cp39-manylinux_s390x |
| PyPy2.7 v7.3 | pp27-macosx_x86_64 | pp27-win32 | pp27-manylinux_x86_64 | |
| PyPy3.6 v7.3 | pp36-macosx_x86_64 | pp36-win32 | pp36-manylinux_x86_64 | |
| PyPy3.7 v7.3 | pp37-macosx_x86_64 | pp37-win32 | pp37-manylinux_x86_64 | |
@@ -133,28 +131,30 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
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/3.7, respectively macOS 10.7 and 10.13 or higher is required.
For CPython, the minimally supported macOS version is 10.9; for PyPy 3.6/3.7, macOS 10.13 or higher is required.
See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.x/) for past end of life versions of Python, and PyPy2.7.
#### Examples
```yaml
# Only build on Python 3.6
# Only build on CPython 3.6
CIBW_BUILD: cp36-*
# Skip building on Python 2.7 on the Mac
CIBW_SKIP: cp27-macosx_x86_64
# Skip building on CPython 3.6 on the Mac
CIBW_SKIP: cp36-macosx_x86_64
# Skip building on Python 3.8 on the Mac
# Skip building on CPython 3.8 on the Mac
CIBW_SKIP: cp38-macosx_x86_64
# Skip building on Python 2.7 on all platforms
CIBW_SKIP: cp27-*
# Skip building on CPython 3.6 on all platforms
CIBW_SKIP: cp36-*
# Skip Python 2.7 on Windows
CIBW_SKIP: cp27-win*
# Skip CPython 3.6 on Windows
CIBW_SKIP: cp36-win*
# Skip Python 2.7 on 32-bit Windows
CIBW_SKIP: cp27-win32
# Skip CPython 3.6 on 32-bit Windows
CIBW_SKIP: cp36-win32
# Skip CPython 3.6 and CPython 3.7
CIBW_SKIP: cp36-* cp37-*
@@ -162,13 +162,9 @@ CIBW_SKIP: cp36-* cp37-*
# Skip Python 3.6 on Linux
CIBW_SKIP: cp36-manylinux*
# Only build on Python 3 (ready for 3.10 when it comes) and skip 32-bit builds
CIBW_BUILD: {cp,pp}3*-*
# Skip 32-bit builds
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*
```
@@ -489,7 +485,6 @@ Set an alternative Docker image to be used for building [manylinux](https://gith
The value of this option can either be set to `manylinux1`, `manylinux2010`, `manylinux2014` or `manylinux_2_24` 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. For PyPy, only the official `manylinux2010` image is currently available. For architectures other
than x86 (x86\_64 and i686) `manylinux2014` or `manylinux_2_24` must be used, because the first version of the manylinux specification that supports additional architectures is `manylinux2014`.
Note that `manylinux2014`/`manylinux_2_24` don't support builds with Python 2.7 - when building with `manylinux2014`/`manylinux_2_24`, skip Python 2.7 using `CIBW_SKIP` (see example below).
If setting a custom Docker image, you'll need to make sure it 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 compatible to the relevant standard to produce valid manylinux1/manylinux2010/manylinux2014/manylinux_2_24 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/), [PEP 599](https://www.python.org/dev/peps/pep-0599/) and [PEP 600](https://www.python.org/dev/peps/pep-0600/) for more details).
@@ -544,7 +539,7 @@ here and it will be used instead.
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-python37.txt` on Python 3.7, or fallback to
`./constraints.txt` if that's not found.
Platform-specific variants also available:<br/>
-2
View File
@@ -123,8 +123,6 @@ To build Linux, Mac, and Windows wheels on Travis CI, create a `.travis.yml` fil
{% include "../examples/travis-ci-minimal.yml" %}
```
Note that building Windows Python 2.7 wheels on Travis is unsupported unless using a newer compiler [via a workaround](cpp_standards.md).
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/).
+5 -5
View File
@@ -5,11 +5,11 @@ from . import test_projects, utils
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")
# explode if run on PyPyor Python 3.7 (these should be skipped)
if sys.implementation.name != "cpython":
raise Exception("Only CPython shall be built")
if sys.version_info[0:2] == (3, 7):
raise Exception("Python 3.7 should be skipped")
raise Exception("CPython 3.7 should be skipped")
"""
)
)
@@ -28,7 +28,7 @@ def test(tmp_path):
},
)
# check that we got the right wheels. There should be no 2.7 or 3.7.
# check that we got the right wheels. There should be no PyPy 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)
]
+14 -105
View File
@@ -36,38 +36,18 @@ spam_system(PyObject *self, PyObject *args)
}
/* 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)
PyMODINIT_FUNC PyInit_spam(void)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT, "spam", "Example module", -1, module_methods,
};
return PyModule_Create(&moduledef);
}
"""
@@ -87,15 +67,8 @@ def test_cpp11(tmp_path):
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
]
actual_wheels = utils.cibuildwheel_run(project_dir)
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0")]
assert set(actual_wheels) == set(expected_wheels)
@@ -113,27 +86,17 @@ def test_cpp14(tmp_path):
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
]
actual_wheels = utils.cibuildwheel_run(project_dir)
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0")]
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["extra_compile_args"] = [
"/std:c++17" if utils.platform == "windows" else "-std=c++17"
]
cpp17_project.template_context[
"spam_cpp_top_level_add"
] = r"""
@@ -153,7 +116,7 @@ def test_cpp17(tmp_path):
# Pypy's distutils sets the default compiler to 'msvc9compiler', which
# is too old to support cpp17.
add_env = {"CIBW_SKIP": "cp27-win* pp??-*"}
add_env = {"CIBW_SKIP": "pp??-*"}
if utils.platform == "macos":
add_env["MACOSX_DEPLOYMENT_TARGET"] = "10.13"
@@ -162,61 +125,7 @@ def test_cpp17(tmp_path):
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", exclude_27=False)
if "cp27-cp27m-win" in w or "pp27-pypy_73-win32" in w
if "-pp" not in w
]
assert set(actual_wheels) == set(expected_wheels)
+14 -31
View File
@@ -47,31 +47,28 @@ def get_versions_from_constraint_file(constraint_file):
}
@pytest.mark.parametrize("python_version", ["2.7", "3.6", "3.8", "3.9"])
@pytest.mark.parametrize("python_version", ["3.6", "3.8", "3.9"])
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")
if utils.platform == "windows" and python_version == "2.7":
pytest.skip("Windows requires a workaround")
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.6":
if python_version == "3.6":
constraint_filename = "constraints-python36.txt"
build_pattern = "[cp]p36-*"
elif python_version == "3.7":
constraint_filename = "constraints-python37.txt"
build_pattern = "[cp]p37-*"
elif python_version == "3.8":
constraint_filename = "constraints-python38.txt"
build_pattern = "[cp]p38-*"
else:
constraint_filename = "constraints.txt"
build_pattern = "[cp]p38-*"
build_pattern = "[cp]p39-*"
constraint_file = cibuildwheel.util.resources_dir / constraint_filename
constraint_versions = get_versions_from_constraint_file(constraint_file)
@@ -92,11 +89,7 @@ def test_pinned_versions(tmp_path, python_version):
)
# 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.6":
if 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
]
@@ -104,26 +97,26 @@ def test_pinned_versions(tmp_path, python_version):
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp38" in w or "-pp38" in w
]
elif python_version == "3.9":
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp39" in w or "-pp39" 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):
def test_dependency_constraints_file(tmp_path):
if utils.platform == "linux":
pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead")
if utils.platform == "windows" and python_version == "2.7":
pytest.skip("Windows + Travis CI requires a workaround")
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",
"setuptools": "53.0.0",
"wheel": "0.34.2",
"virtualenv": "20.0.10",
}
@@ -154,22 +147,12 @@ def test_dependency_constraints_file(tmp_path, python_version):
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
]
expected_wheels = utils.expected_wheels("spam", "0.1.0")
assert set(actual_wheels) == set(expected_wheels)
+2 -4
View File
@@ -37,14 +37,12 @@ def test(tmp_path):
add_env={
"CIBW_MANYLINUX_X86_64_IMAGE": "dockcross/manylinux2010-x64",
"CIBW_MANYLINUX_I686_IMAGE": "dockcross/manylinux2010-x86",
"CIBW_SKIP": "pp* cp27-* cp39-*",
"CIBW_SKIP": "pp* cp39-*",
},
)
# 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 and "-cp39-" not in w and "-cp27-" not in w
w for w in utils.expected_wheels("spam", "0.1.0") if "-pp" not in w and "-cp39-" not in w
]
assert set(actual_wheels) == set(expected_wheels)
+3 -7
View File
@@ -65,20 +65,16 @@ def test(manylinux_image, tmp_path):
"CIBW_MANYLINUX_PPC64LE_IMAGE": manylinux_image,
"CIBW_MANYLINUX_S390X_IMAGE": manylinux_image,
}
if manylinux_image == "manylinux1":
if manylinux_image in {"manylinux1", "manylinux2014", "manylinux_2_24"}:
# We don't have a manylinux1 image for PyPy
# We don't have a manylinux2014 / manylinux_2_24 image for PyPy (yet?)
add_env["CIBW_SKIP"] = "pp*"
elif manylinux_image in {"manylinux2014", "manylinux_2_24"}:
# We don't have a manylinux2014 / 'manylinux_2_24' image for PyPy (yet?)
# Python 2.7 not available on manylinux2014 / 'manylinux_2_24'
add_env["CIBW_SKIP"] = "cp27* pp*"
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 in {"manylinux2014", "manylinux_2_24"}:
expected_wheels = [w for w in expected_wheels if "-cp27" not in w]
if manylinux_image in {"manylinux1", "manylinux2014", "manylinux_2_24"}:
expected_wheels = [w for w in expected_wheels if "-pp" not in w]
assert set(actual_wheels) == set(expected_wheels)
+2 -6
View File
@@ -8,10 +8,7 @@ basic_project = test_projects.new_c_project(
"""
# Will fail if PEP 518 does work
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__)
assert requests.__version__ == "2.23.0", "Requests found but wrong version ({0})".format(requests.__version__)
# Just making sure environment is still set
import os
@@ -29,8 +26,7 @@ requires = [
"setuptools >= 42",
"setuptools_scm[toml]>=4.1.2",
"wheel",
"requests==2.22.0; python_version<'3.6'",
"requests==2.23.0; python_version>='3.6'"
"requests==2.23.0"
]
build-backend = "setuptools.build_meta"
+5 -25
View File
@@ -24,38 +24,18 @@ spam_system(PyObject *self, PyObject *args)
}
/* 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)
PyMODINIT_FUNC PyInit_spam(void)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT, "spam", "Example module", -1, module_methods,
};
return PyModule_Create(&moduledef);
}
"""
+1 -4
View File
@@ -7,10 +7,7 @@ project_with_ssl_tests = test_projects.new_c_project(
r"""
import ssl
if sys.version_info[0] == 2:
from urllib2 import urlopen
else:
from urllib.request import urlopen
from urllib.request import urlopen
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
data = urlopen("https://www.nist.gov", context=context)
+1 -2
View File
@@ -52,8 +52,7 @@ class TestSpam(TestCase):
# sys.prefix is different from sys.base_prefix when running a virtualenv
# See https://docs.python.org/3/library/venv.html, which virtualenv seems
# to honor in recent releases
# Python 2 doesn't have sys.base_prefix by default
if not hasattr(sys, 'base_prefix') or sys.prefix == sys.base_prefix:
if sys.prefix == sys.base_prefix:
self.fail("Not running in a virtualenv")
self.assertTrue(path_contains(sys.prefix, sys.executable))
+5 -28
View File
@@ -6,11 +6,9 @@ This file is added to the PYTHONPATH in the test runner at bin/run_test.py.
import os
import platform as pm
import shutil
import subprocess
import sys
from contextlib import contextmanager
from tempfile import mkdtemp
from tempfile import TemporaryDirectory
platform: str
@@ -26,17 +24,6 @@ else:
raise Exception("Unsupported platform")
# Python 2 does not have a tempfile.TemporaryDirectory context manager
@contextmanager
def TemporaryDirectoryIfNone(path):
_path = path or mkdtemp()
try:
yield _path
finally:
if path is None:
shutil.rmtree(_path)
def cibuildwheel_get_build_identifiers(project_path, env=None):
"""
Returns the list of build identifiers that cibuildwheel will try to build
@@ -76,21 +63,21 @@ def cibuildwheel_run(project_path, package_dir=".", env=None, add_env=None, outp
if add_env is not None:
env.update(add_env)
with TemporaryDirectoryIfNone(output_dir) as _output_dir:
with TemporaryDirectory() as tmp_output_dir:
subprocess.run(
[
sys.executable,
"-m",
"cibuildwheel",
"--output-dir",
str(_output_dir),
str(output_dir or tmp_output_dir),
str(package_dir),
],
env=env,
cwd=project_path,
check=True,
)
wheels = os.listdir(_output_dir)
wheels = os.listdir(output_dir or tmp_output_dir)
return wheels
@@ -113,8 +100,6 @@ def expected_wheels(
manylinux_versions=None,
macosx_deployment_target="10.9",
machine_arch=None,
*,
exclude_27=platform == "windows",
):
"""
Returns a list of expected wheels from a run of cibuildwheel.
@@ -136,10 +121,7 @@ def expected_wheels(
python_abi_tags = ["cp36-cp36m", "cp37-cp37m", "cp38-cp38", "cp39-cp39"]
if machine_arch in ["x86_64", "AMD64", "x86"]:
python_abi_tags += ["cp27-cp27m", "pp27-pypy_73", "pp36-pypy36_pp73", "pp37-pypy37_pp73"]
if platform == "linux":
python_abi_tags.append("cp27-cp27mu") # python 2.7 has 2 different ABI on manylinux
python_abi_tags += ["pp36-pypy36_pp73", "pp37-pypy37_pp73"]
if platform == "macos" and get_macos_version() >= (10, 16):
# 10.16 is sometimes reported as the macOS version on macOS 11.
@@ -193,11 +175,6 @@ def expected_wheels(
for platform_tag in platform_tags:
wheels.append(f"{package_name}-{package_version}-{python_abi_tag}-{platform_tag}.whl")
# Travis on Windows does not support using the default Python 2.7 compiler,
# so we support skipping here.
if exclude_27:
wheels = [w for w in wheels if "-cp27-" not in w and "-pp2" not in w]
return wheels
+54 -56
View File
@@ -4,65 +4,67 @@ from cibuildwheel.util import BuildSelector
def test_build():
build_selector = BuildSelector(build_config="cp3?-* *-manylinux1*", skip_config="")
build_selector = BuildSelector(build_config="cp3?-* *-manylinux*", skip_config="")
assert build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert build_selector("cp27-manylinux1_i686")
assert build_selector("cp36-manylinux1_i686")
assert build_selector("cp37-manylinux1_i686")
assert not build_selector("cp27-macosx_10_6_intel")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert build_selector("pp36-manylinux_x86_64")
assert build_selector("pp37-manylinux_x86_64")
assert build_selector("cp36-manylinux_i686")
assert build_selector("cp37-manylinux_i686")
assert build_selector("cp36-macosx_10_6_intel")
assert build_selector("cp37-macosx_10_6_intel")
assert not build_selector("cp27-win32")
assert not build_selector("pp36-macosx_10_6_intel")
assert not build_selector("pp37-macosx_10_6_intel")
assert build_selector("cp36-win32")
assert build_selector("cp37-win32")
assert not build_selector("cp27-win_amd64")
assert not build_selector("pp36-win32")
assert not build_selector("pp37-win32")
assert build_selector("cp36-win_amd64")
assert build_selector("cp37-win_amd64")
assert not build_selector("pp36-win_amd64")
assert not build_selector("pp37-win_amd64")
def test_skip():
build_selector = BuildSelector(
build_config="*", skip_config="cp27-* cp3?-manylinux1_i686 cp36-win* *-win32"
build_config="*", skip_config="pp36-* cp3?-manylinux_i686 cp36-win* *-win32"
)
assert not build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert not build_selector("cp27-manylinux1_i686")
assert not build_selector("cp36-manylinux1_i686")
assert not build_selector("cp37-manylinux1_i686")
assert not build_selector("cp27-macosx_10_6_intel")
assert not build_selector("pp36-manylinux_x86_64")
assert build_selector("pp37-manylinux_x86_64")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert not build_selector("cp36-manylinux_i686")
assert not build_selector("cp37-manylinux_i686")
assert not build_selector("pp36-macosx_10_6_intel")
assert build_selector("pp37-macosx_10_6_intel")
assert build_selector("cp36-macosx_10_6_intel")
assert build_selector("cp37-macosx_10_6_intel")
assert not build_selector("cp27-win32")
assert not build_selector("cp36-win32")
assert not build_selector("cp37-win32")
assert not build_selector("cp27-win_amd64")
assert not build_selector("cp36-win_amd64")
assert build_selector("cp37-win_amd64")
def test_build_and_skip():
build_selector = BuildSelector(
build_config="cp36-* cp37-macosx* *-manylinux1*", skip_config="cp27-* cp37-manylinux1_i686"
build_config="cp36-* cp37-macosx* *-manylinux*", skip_config="pp37-* cp37-manylinux_i686"
)
assert not build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert not build_selector("cp27-manylinux1_i686")
assert build_selector("cp36-manylinux1_i686")
assert not build_selector("cp37-manylinux1_i686")
assert not build_selector("cp27-macosx_10_6_intel")
assert not build_selector("pp37-manylinux_x86_64")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert not build_selector("pp37-manylinux_i686")
assert build_selector("cp36-manylinux_i686")
assert not build_selector("cp37-manylinux_i686")
assert not build_selector("pp37-macosx_10_6_intel")
assert build_selector("cp36-macosx_10_6_intel")
assert build_selector("cp37-macosx_10_6_intel")
assert not build_selector("cp27-win32")
assert not build_selector("pp37-win32")
assert build_selector("cp36-win32")
assert not build_selector("cp37-win32")
assert not build_selector("cp27-win_amd64")
assert not build_selector("pp37-win_amd64")
assert build_selector("cp36-win_amd64")
assert not build_selector("cp37-win_amd64")
@@ -70,49 +72,45 @@ def test_build_and_skip():
def test_build_braces():
build_selector = BuildSelector(build_config="cp{36,37}*", skip_config="")
assert not build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert not build_selector("cp38-manylinux1_x86_64")
assert not build_selector("cp39-manylinux1_x86_64")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert not build_selector("cp38-manylinux_x86_64")
assert not build_selector("cp39-manylinux_x86_64")
def test_build_limited_python():
build_selector = BuildSelector(
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6")
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.7")
)
assert not build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert not build_selector("cp27-manylinux1_i686")
assert build_selector("cp36-manylinux1_i686")
assert build_selector("cp37-manylinux1_i686")
assert not build_selector("cp27-win32")
assert build_selector("cp36-win32")
assert not build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert build_selector("cp38-manylinux_x86_64")
assert not build_selector("cp36-manylinux_i686")
assert build_selector("cp37-manylinux_i686")
assert build_selector("cp38-manylinux_i686")
assert not build_selector("cp36-win32")
assert build_selector("cp37-win32")
assert not build_selector("pp27-win32")
assert build_selector("pp36-win32")
assert build_selector("cp38-win32")
assert not build_selector("pp36-win32")
assert build_selector("pp37-win32")
def test_build_limited_python_partial():
build_selector = BuildSelector(
build_config="*",
skip_config="",
requires_python=SpecifierSet(">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"),
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6, !=3.7.*")
)
assert build_selector("cp27-manylinux1_x86_64")
assert not build_selector("cp35-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp36-manylinux_x86_64")
assert not build_selector("cp37-manylinux_x86_64")
assert build_selector("cp38-manylinux_x86_64")
assert build_selector("cp39-manylinux_x86_64")
def test_build_limited_python_patch():
build_selector = BuildSelector(
build_config="*", skip_config="", requires_python=SpecifierSet(">=2.7.9")
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6.8")
)
assert build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
-3
View File
@@ -19,6 +19,3 @@ def test_defaults():
assert dependency_constraints.get_for_python_version("3.6").samefile(
resources_dir / "constraints-python36.txt"
)
assert dependency_constraints.get_for_python_version("2.7").samefile(
resources_dir / "constraints-python27.txt"
)