diff --git a/cibuildwheel/platforms/macos.py b/cibuildwheel/platforms/macos.py index d2df5fb1..7a5fd214 100644 --- a/cibuildwheel/platforms/macos.py +++ b/cibuildwheel/platforms/macos.py @@ -32,7 +32,7 @@ from cibuildwheel.util.cmd import call, shell from cibuildwheel.util.file import CIBW_CACHE_PATH, copy_test_sources, download, move_file from cibuildwheel.util.helpers import prepare_command, unwrap from cibuildwheel.util.packaging import find_compatible_wheel, get_pip_version -from cibuildwheel.venv import constraint_flags, find_uv, virtualenv +from cibuildwheel.venv import constraint_flags, find_uv, target_marker_env, virtualenv @functools.cache @@ -246,6 +246,7 @@ def setup_python( venv_path, dependency_constraint, use_uv=use_uv, + marker_env=target_marker_env(implementation_id=implementation_id), ) venv_bin_path = venv_path / "bin" assert venv_bin_path.exists() diff --git a/cibuildwheel/platforms/windows.py b/cibuildwheel/platforms/windows.py index 3f2c74fc..edb0c997 100644 --- a/cibuildwheel/platforms/windows.py +++ b/cibuildwheel/platforms/windows.py @@ -34,7 +34,7 @@ from cibuildwheel.util.file import ( ) from cibuildwheel.util.helpers import prepare_command, unwrap from cibuildwheel.util.packaging import find_compatible_wheel, get_pip_version -from cibuildwheel.venv import constraint_flags, find_uv, virtualenv +from cibuildwheel.venv import constraint_flags, find_uv, target_marker_env, virtualenv def get_nuget_args( @@ -284,6 +284,7 @@ def setup_python( venv_path, dependency_constraint, use_uv=use_uv, + marker_env=target_marker_env(implementation_id=implementation_id), ) # set up environment variables for run_with_env diff --git a/cibuildwheel/resources/build-platforms.toml b/cibuildwheel/resources/build-platforms.toml index b7ebf6ea..a80685a7 100644 --- a/cibuildwheel/resources/build-platforms.toml +++ b/cibuildwheel/resources/build-platforms.toml @@ -158,12 +158,12 @@ python_configurations = [ { identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.13/python-3.13.13-macos11.pkg" }, { identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.13/python-3.13.13-macos11.pkg" }, { identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.13/python-3.13.13-macos11.pkg" }, - { identifier = "cp314-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, - { identifier = "cp314-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, - { identifier = "cp314-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, - { identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, - { identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, - { identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, + { identifier = "cp314-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg" }, + { identifier = "cp314-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg" }, + { identifier = "cp314-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg" }, + { identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg" }, + { identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg" }, + { identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg" }, { identifier = "cp315-macosx_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, { identifier = "cp315-macosx_arm64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, { identifier = "cp315-macosx_universal2", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, @@ -194,10 +194,10 @@ python_configurations = [ { identifier = "cp312-win_amd64", version = "3.12.10" }, { identifier = "cp313-win32", version = "3.13.13" }, { identifier = "cp313-win_amd64", version = "3.13.13" }, - { identifier = "cp314-win32", version = "3.14.4" }, - { identifier = "cp314t-win32", version = "3.14.4" }, - { identifier = "cp314-win_amd64", version = "3.14.4" }, - { identifier = "cp314t-win_amd64", version = "3.14.4" }, + { identifier = "cp314-win32", version = "3.14.5" }, + { identifier = "cp314t-win32", version = "3.14.5" }, + { identifier = "cp314-win_amd64", version = "3.14.5" }, + { identifier = "cp314t-win_amd64", version = "3.14.5" }, { identifier = "cp315-win32", version = "3.15.0-b1" }, { identifier = "cp315t-win32", version = "3.15.0-b1" }, { identifier = "cp315-win_amd64", version = "3.15.0-b1" }, @@ -207,8 +207,8 @@ python_configurations = [ { identifier = "cp311-win_arm64", version = "3.11.9" }, { identifier = "cp312-win_arm64", version = "3.12.10" }, { identifier = "cp313-win_arm64", version = "3.13.13" }, - { identifier = "cp314-win_arm64", version = "3.14.4" }, - { identifier = "cp314t-win_arm64", version = "3.14.4" }, + { identifier = "cp314-win_arm64", version = "3.14.5" }, + { identifier = "cp314t-win_arm64", version = "3.14.5" }, { identifier = "cp315-win_arm64", version = "3.15.0-b1" }, { identifier = "cp315t-win_arm64", version = "3.15.0-b1" }, { identifier = "pp39-win_amd64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" }, @@ -229,8 +229,8 @@ python_configurations = [ python_configurations = [ { identifier = "cp313-android_arm64_v8a", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.13/python-3.13.13-aarch64-linux-android.tar.gz" }, { identifier = "cp313-android_x86_64", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.13/python-3.13.13-x86_64-linux-android.tar.gz" }, - { identifier = "cp314-android_arm64_v8a", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-aarch64-linux-android.tar.gz" }, - { identifier = "cp314-android_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-x86_64-linux-android.tar.gz" }, + { identifier = "cp314-android_arm64_v8a", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-aarch64-linux-android.tar.gz" }, + { identifier = "cp314-android_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-x86_64-linux-android.tar.gz" }, ] [ios] diff --git a/cibuildwheel/resources/constraints-pyodide312.txt b/cibuildwheel/resources/constraints-pyodide312.txt index 87fd85c5..d74cb73f 100644 --- a/cibuildwheel/resources/constraints-pyodide312.txt +++ b/cibuildwheel/resources/constraints-pyodide312.txt @@ -23,7 +23,7 @@ filelock==3.29.0 # via # python-discovery # virtualenv -idna==3.13 +idna==3.14 # via requests leb128==1.0.9 # via auditwheel-emscripten @@ -64,7 +64,7 @@ pyproject-hooks==1.2.0 # via build python-discovery==1.3.0 # via virtualenv -requests==2.33.1 +requests==2.34.0 # via pyodide-build rich==15.0.0 # via @@ -79,7 +79,7 @@ typing-extensions==4.15.0 # typing-inspection typing-inspection==0.4.2 # via pydantic -urllib3==2.6.3 +urllib3==2.7.0 # via requests virtualenv==21.3.1 # via diff --git a/cibuildwheel/resources/constraints-pyodide313.txt b/cibuildwheel/resources/constraints-pyodide313.txt index 87fd85c5..d74cb73f 100644 --- a/cibuildwheel/resources/constraints-pyodide313.txt +++ b/cibuildwheel/resources/constraints-pyodide313.txt @@ -23,7 +23,7 @@ filelock==3.29.0 # via # python-discovery # virtualenv -idna==3.13 +idna==3.14 # via requests leb128==1.0.9 # via auditwheel-emscripten @@ -64,7 +64,7 @@ pyproject-hooks==1.2.0 # via build python-discovery==1.3.0 # via virtualenv -requests==2.33.1 +requests==2.34.0 # via pyodide-build rich==15.0.0 # via @@ -79,7 +79,7 @@ typing-extensions==4.15.0 # typing-inspection typing-inspection==0.4.2 # via pydantic -urllib3==2.6.3 +urllib3==2.7.0 # via requests virtualenv==21.3.1 # via diff --git a/cibuildwheel/resources/constraints-pyodide314.txt b/cibuildwheel/resources/constraints-pyodide314.txt index 87fd85c5..d74cb73f 100644 --- a/cibuildwheel/resources/constraints-pyodide314.txt +++ b/cibuildwheel/resources/constraints-pyodide314.txt @@ -23,7 +23,7 @@ filelock==3.29.0 # via # python-discovery # virtualenv -idna==3.13 +idna==3.14 # via requests leb128==1.0.9 # via auditwheel-emscripten @@ -64,7 +64,7 @@ pyproject-hooks==1.2.0 # via build python-discovery==1.3.0 # via virtualenv -requests==2.33.1 +requests==2.34.0 # via pyodide-build rich==15.0.0 # via @@ -79,7 +79,7 @@ typing-extensions==4.15.0 # typing-inspection typing-inspection==0.4.2 # via pydantic -urllib3==2.6.3 +urllib3==2.7.0 # via requests virtualenv==21.3.1 # via diff --git a/cibuildwheel/resources/constraints-python310.txt b/cibuildwheel/resources/constraints-python310.txt index 2c5a6389..8a6a3ddb 100644 --- a/cibuildwheel/resources/constraints-python310.txt +++ b/cibuildwheel/resources/constraints-python310.txt @@ -20,7 +20,7 @@ packaging==26.2 # via # build # delocate -pip==26.0.1 +pip==26.1.1 # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via @@ -28,7 +28,7 @@ platformdirs==4.9.6 # virtualenv pyproject-hooks==1.2.0 # via build -python-discovery==1.2.2 +python-discovery==1.3.0 # via virtualenv tomli==2.4.1 # via build @@ -36,7 +36,7 @@ typing-extensions==4.15.0 # via # delocate # virtualenv -virtualenv==21.2.1 +virtualenv==21.3.1 # via -r cibuildwheel/resources/constraints.in zipp==3.23.1 # via importlib-metadata diff --git a/cibuildwheel/resources/constraints-python311.txt b/cibuildwheel/resources/constraints-python311.txt index cd2a6426..e119bfbe 100644 --- a/cibuildwheel/resources/constraints-python311.txt +++ b/cibuildwheel/resources/constraints-python311.txt @@ -18,7 +18,8 @@ packaging==26.2 # via # build # delocate -pip==26.0.1 +pip==26.1.1; implementation_name != "graalpy" or platform_system != "Windows" +pip==26.0.1; implementation_name == "graalpy" and platform_system == "Windows" # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via @@ -26,9 +27,9 @@ platformdirs==4.9.6 # virtualenv pyproject-hooks==1.2.0 # via build -python-discovery==1.2.2 +python-discovery==1.3.0 # via virtualenv typing-extensions==4.15.0 # via delocate -virtualenv==21.2.1 +virtualenv==21.3.1 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints-python312.txt b/cibuildwheel/resources/constraints-python312.txt index cd2a6426..e119bfbe 100644 --- a/cibuildwheel/resources/constraints-python312.txt +++ b/cibuildwheel/resources/constraints-python312.txt @@ -18,7 +18,8 @@ packaging==26.2 # via # build # delocate -pip==26.0.1 +pip==26.1.1; implementation_name != "graalpy" or platform_system != "Windows" +pip==26.0.1; implementation_name == "graalpy" and platform_system == "Windows" # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via @@ -26,9 +27,9 @@ platformdirs==4.9.6 # virtualenv pyproject-hooks==1.2.0 # via build -python-discovery==1.2.2 +python-discovery==1.3.0 # via virtualenv typing-extensions==4.15.0 # via delocate -virtualenv==21.2.1 +virtualenv==21.3.1 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints-python313.txt b/cibuildwheel/resources/constraints-python313.txt index cd2a6426..119f5611 100644 --- a/cibuildwheel/resources/constraints-python313.txt +++ b/cibuildwheel/resources/constraints-python313.txt @@ -18,7 +18,7 @@ packaging==26.2 # via # build # delocate -pip==26.0.1 +pip==26.1.1 # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via @@ -26,9 +26,9 @@ platformdirs==4.9.6 # virtualenv pyproject-hooks==1.2.0 # via build -python-discovery==1.2.2 +python-discovery==1.3.0 # via virtualenv typing-extensions==4.15.0 # via delocate -virtualenv==21.2.1 +virtualenv==21.3.1 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints-python314.txt b/cibuildwheel/resources/constraints-python314.txt index cd2a6426..119f5611 100644 --- a/cibuildwheel/resources/constraints-python314.txt +++ b/cibuildwheel/resources/constraints-python314.txt @@ -18,7 +18,7 @@ packaging==26.2 # via # build # delocate -pip==26.0.1 +pip==26.1.1 # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via @@ -26,9 +26,9 @@ platformdirs==4.9.6 # virtualenv pyproject-hooks==1.2.0 # via build -python-discovery==1.2.2 +python-discovery==1.3.0 # via virtualenv typing-extensions==4.15.0 # via delocate -virtualenv==21.2.1 +virtualenv==21.3.1 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints-python315.txt b/cibuildwheel/resources/constraints-python315.txt index 84bd6213..119f5611 100644 --- a/cibuildwheel/resources/constraints-python315.txt +++ b/cibuildwheel/resources/constraints-python315.txt @@ -18,7 +18,7 @@ packaging==26.2 # via # build # delocate -pip==26.1 +pip==26.1.1 # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via @@ -26,9 +26,9 @@ platformdirs==4.9.6 # virtualenv pyproject-hooks==1.2.0 # via build -python-discovery==1.2.2 +python-discovery==1.3.0 # via virtualenv typing-extensions==4.15.0 # via delocate -virtualenv==21.3.0 +virtualenv==21.3.1 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints-python39.txt b/cibuildwheel/resources/constraints-python39.txt index c98a2d2a..6ccbeb72 100644 --- a/cibuildwheel/resources/constraints-python39.txt +++ b/cibuildwheel/resources/constraints-python39.txt @@ -28,7 +28,7 @@ platformdirs==4.4.0 # virtualenv pyproject-hooks==1.2.0 # via build -python-discovery==1.2.2 +python-discovery==1.3.0 # via virtualenv tomli==2.4.1 # via build @@ -36,7 +36,7 @@ typing-extensions==4.15.0 # via # delocate # virtualenv -virtualenv==21.2.1 +virtualenv==21.3.1 # via -r cibuildwheel/resources/constraints.in zipp==3.23.1 # via importlib-metadata diff --git a/cibuildwheel/resources/constraints.txt b/cibuildwheel/resources/constraints.txt index cd2a6426..119f5611 100644 --- a/cibuildwheel/resources/constraints.txt +++ b/cibuildwheel/resources/constraints.txt @@ -18,7 +18,7 @@ packaging==26.2 # via # build # delocate -pip==26.0.1 +pip==26.1.1 # via -r cibuildwheel/resources/constraints.in platformdirs==4.9.6 # via @@ -26,9 +26,9 @@ platformdirs==4.9.6 # virtualenv pyproject-hooks==1.2.0 # via build -python-discovery==1.2.2 +python-discovery==1.3.0 # via virtualenv typing-extensions==4.15.0 # via delocate -virtualenv==21.2.1 +virtualenv==21.3.1 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/virtualenv.toml b/cibuildwheel/resources/virtualenv.toml index 8d0e9f5b..746bbaa7 100644 --- a/cibuildwheel/resources/virtualenv.toml +++ b/cibuildwheel/resources/virtualenv.toml @@ -1 +1 @@ -default = { version = "21.2.1", url = "https://github.com/pypa/get-virtualenv/releases/download/21.2.1/virtualenv.pyz" } +default = { version = "21.3.1", url = "https://github.com/pypa/get-virtualenv/releases/download/21.3.1/virtualenv.pyz" } diff --git a/cibuildwheel/venv.py b/cibuildwheel/venv.py index dd4fe90a..c03c2923 100644 --- a/cibuildwheel/venv.py +++ b/cibuildwheel/venv.py @@ -6,9 +6,10 @@ import sys import tomllib from collections.abc import Sequence from pathlib import Path -from typing import Final +from typing import Final, cast from filelock import FileLock +from packaging.markers import default_environment from packaging.requirements import InvalidRequirement, Requirement from packaging.version import Version @@ -19,6 +20,24 @@ from cibuildwheel.util.file import CIBW_CACHE_PATH, download _IS_WIN: Final[bool] = sys.platform.startswith("win") +def target_marker_env( + *, + implementation_id: str, +) -> dict[str, str]: + """ + Build a PEP 508 marker environment dict for the target Python, + overriding the host's values with the target implementation info. + """ + env = cast("dict[str, str]", default_environment()) + if implementation_id.startswith("gp"): + env["implementation_name"] = "graalpy" + env["platform_python_implementation"] = "GraalPy" + elif implementation_id.startswith("pp"): + env["implementation_name"] = "pypy" + env["platform_python_implementation"] = "PyPy" + return env + + @functools.cache def _ensure_virtualenv(version: str) -> tuple[Path, Version]: version_parts = version.split(".") @@ -47,6 +66,7 @@ def constraint_flags( def _parse_pip_constraint_for_virtualenv( constraint_path: Path | None, + marker_env: dict[str, str] | None = None, ) -> str: """ Parses the constraints file referenced by `dependency_constraint_flags` and returns a dict where @@ -56,7 +76,12 @@ def _parse_pip_constraint_for_virtualenv( The function does not try to be too smart and just handles basic constraints. If it can't get an exact version, the real constraint will be handled by the {macos|windows}.setup_python function. + If marker_env is provided, marker-bearing constraints are evaluated against it; + otherwise, marker-bearing constraints are skipped. """ + env: dict[str, str] = ( + marker_env if marker_env is not None else cast("dict[str, str]", default_environment()) + ) if constraint_path: assert constraint_path.exists() with constraint_path.open(encoding="utf-8") as constraint_file: @@ -72,11 +97,12 @@ def _parse_pip_constraint_for_virtualenv( if ( package != "pip" or requirement.url is not None - or requirement.marker is not None or len(requirement.extras) != 0 or len(requirement.specifier) != 1 ): continue + if requirement.marker is not None and not requirement.marker.evaluate(env): + continue specifier = next(iter(requirement.specifier)) if specifier.operator != "==": continue @@ -95,6 +121,7 @@ def virtualenv( use_uv: bool, env: dict[str, str] | None = None, pip_version: str | None = None, + marker_env: dict[str, str] | None = None, ) -> dict[str, str]: """ Create a virtual environment. If `use_uv` is True, @@ -114,7 +141,7 @@ def virtualenv( else: virtualenv_app, virtualenv_version = _ensure_virtualenv(version) if pip_version is None: - pip_version = _parse_pip_constraint_for_virtualenv(dependency_constraint) + pip_version = _parse_pip_constraint_for_virtualenv(dependency_constraint, marker_env) additional_flags = [f"--pip={pip_version}", "--no-setuptools"] if virtualenv_version < Version("20.31") or Version(version) < Version("3.9"): additional_flags.append("--no-wheel") diff --git a/docs/working-examples.md b/docs/working-examples.md index 3e9e285d..473b6a1f 100644 --- a/docs/working-examples.md +++ b/docs/working-examples.md @@ -80,8 +80,8 @@ title: Working examples | [sourmash][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] ![pyodide icon][] | Quickly search, compare, and analyze genomic and metagenomic data sets. | | [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson | | [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | Example pybind11 module built with a Python-based build system | -| [abess][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A fast best-subset selection library. It uses cibuildwheel to build a large project with C++ extensions. | | [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library | +| [abess][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A fast best-subset selection library. It uses cibuildwheel to build a large project with C++ extensions. | | [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` | | [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq | | [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing | @@ -191,8 +191,8 @@ title: Working examples [sourmash]: https://github.com/sourmash-bio/sourmash [python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson [pybind11 python_example]: https://github.com/pybind/python_example -[abess]: https://github.com/abess-team/abess [python-snappy]: https://github.com/intake/python-snappy +[abess]: https://github.com/abess-team/abess [Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python [jq.py]: https://github.com/mwilliamson/jq.py [cyvcf2]: https://github.com/brentp/cyvcf2