diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 650577c9d..7f0a6e77d 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -8,8 +8,6 @@ from pathlib import Path, PurePath, PurePosixPath from typing import assert_never -from packaging.version import Version - from . import errors from .architecture import Architecture from .frontend import BuildFrontendConfig, get_build_frontend_extra_flags @@ -351,10 +349,7 @@ def build_in_container( container.call(["uv", "venv", venv_dir, "--python", python_bin / "python"], env=env) else: # Use embedded dependencies from virtualenv to ensure determinism - venv_args = ["--no-periodic-update", "--pip=embed"] - # In Python<3.12, setuptools & wheel are installed as well - if Version(config.version) < Version("3.12"): - venv_args.extend(("--setuptools=embed", "--wheel=embed")) + venv_args = ["--no-periodic-update", "--pip=embed", "--no-setuptools", "--no-wheel"] container.call(["python", "-m", "virtualenv", *venv_args, venv_dir], env=env) virtualenv_env = env.copy() diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index bd05f2a99..b27348d7a 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -643,10 +643,12 @@ def build(options: Options, tmp_path: Path) -> None: else: pip_install = functools.partial(call_with_arch, *pip, "install") # Use pip version from the initial env to ensure determinism - venv_args = ["--no-periodic-update", f"--pip={pip_version}"] - # In Python<3.12, setuptools & wheel are installed as well, use virtualenv embedded ones - if Version(config.version) < Version("3.12"): - venv_args.extend(("--setuptools=embed", "--wheel=embed")) + venv_args = [ + "--no-periodic-update", + f"--pip={pip_version}", + "--no-setuptools", + "--no-wheel", + ] call_with_arch("python", "-m", "virtualenv", *venv_args, venv_dir, env=env) virtualenv_env = env.copy() diff --git a/cibuildwheel/resources/constraints-python37.txt b/cibuildwheel/resources/constraints-python37.txt deleted file mode 100644 index 55e33eec5..000000000 --- a/cibuildwheel/resources/constraints-python37.txt +++ /dev/null @@ -1,39 +0,0 @@ -# This file was autogenerated by uv via the following command: -# nox -s update_constraints -altgraph==0.17.4 - # via macholib -build==1.1.1 - # via -r cibuildwheel/resources/constraints.in -delocate==0.12.0 - # via -r cibuildwheel/resources/constraints.in -distlib==0.3.9 - # via virtualenv -filelock==3.12.2 - # via virtualenv -importlib-metadata==6.7.0 - # via - # build - # virtualenv -macholib==1.16.3 - # via delocate -packaging==24.0 - # via - # build - # delocate -pip==24.0 - # via -r cibuildwheel/resources/constraints.in -platformdirs==4.0.0 - # via virtualenv -pyproject-hooks==1.2.0 - # via build -tomli==2.0.1 - # via build -typing-extensions==4.7.1 - # via - # delocate - # importlib-metadata - # platformdirs -virtualenv==20.26.6 - # via -r cibuildwheel/resources/constraints.in -zipp==3.15.0 - # via importlib-metadata diff --git a/cibuildwheel/venv.py b/cibuildwheel/venv.py index 24f2fe5c9..6f7ca400a 100644 --- a/cibuildwheel/venv.py +++ b/cibuildwheel/venv.py @@ -36,10 +36,9 @@ def _ensure_virtualenv(version: str) -> Path: return path -def _parse_constraints_for_virtualenv( - seed_packages: list[str], +def _parse_pip_constraint_for_virtualenv( dependency_constraint_flags: Sequence[PathOrStr], -) -> dict[str, str]: +) -> str: """ Parses the constraints file referenced by `dependency_constraint_flags` and returns a dict where the key is the package name, and the value is the constraint version. @@ -50,8 +49,6 @@ def _parse_constraints_for_virtualenv( {macos|windows}.setup_python function. """ assert len(dependency_constraint_flags) in {0, 2} - # only seed pip if other seed packages do not appear in a constraint file - constraints_dict = {"pip": "embed"} if len(dependency_constraint_flags) == 2: assert dependency_constraint_flags[0] == "-c" constraint_path = Path(dependency_constraint_flags[1]) @@ -67,7 +64,7 @@ def _parse_constraints_for_virtualenv( requirement = Requirement(line) package = requirement.name if ( - package not in seed_packages + package != "pip" or requirement.url is not None or requirement.marker is not None or len(requirement.extras) != 0 @@ -77,10 +74,10 @@ def _parse_constraints_for_virtualenv( specifier = next(iter(requirement.specifier)) if specifier.operator != "==": continue - constraints_dict[package] = specifier.version + return specifier.version except InvalidRequirement: continue - return constraints_dict + return "embed" def virtualenv( @@ -94,7 +91,7 @@ def virtualenv( """ Create a virtual environment. If `use_uv` is True, dependency_constraint_flags are ignored since nothing is installed in the - venv. Otherwise, pip is installed, and setuptools + wheel if Python < 3.12. + venv. Otherwise, pip is installed. """ # virtualenv may fail if this is a symlink. @@ -106,16 +103,8 @@ def virtualenv( call("uv", "venv", venv_path, "--python", python) else: virtualenv_app = _ensure_virtualenv(version) - allowed_seed_packages = ["pip", "setuptools", "wheel"] - constraints = _parse_constraints_for_virtualenv( - allowed_seed_packages, dependency_constraint_flags - ) - additional_flags: list[str] = [] - for package in allowed_seed_packages: - if package in constraints: - additional_flags.append(f"--{package}={constraints[package]}") - else: - additional_flags.append(f"--no-{package}") + pip_constraint = _parse_pip_constraint_for_virtualenv(dependency_constraint_flags) + additional_flags = [f"--pip={pip_constraint}", "--no-setuptools", "--no-wheel"] # Using symlinks to pre-installed seed packages is really the fastest way to get a virtual # environment. The initial cost is a bit higher but reusing is much faster. @@ -123,11 +112,7 @@ def virtualenv( # Requires pip>=19.3 so disabling for "embed" because this means we don't know what's the # version of pip that will end-up installed. # c.f. https://virtualenv.pypa.io/en/latest/cli_interface.html#section-seeder - if ( - not _IS_WIN - and constraints["pip"] != "embed" - and Version(constraints["pip"]) >= Version("19.3") - ): + if not _IS_WIN and pip_constraint != "embed" and Version(pip_constraint) >= Version("19.3"): additional_flags.append("--symlink-app-data") call( diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index bd9a3224c..374b68d71 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -10,7 +10,6 @@ from typing import assert_never from filelock import FileLock -from packaging.version import Version from . import errors from .architecture import Architecture @@ -497,10 +496,12 @@ def build(options: Options, tmp_path: Path) -> None: call("uv", "venv", venv_dir, f"--python={base_python}", env=env) else: # Use pip version from the initial env to ensure determinism - venv_args = ["--no-periodic-update", f"--pip={pip_version}"] - # In Python<3.12, setuptools & wheel are installed as well, use virtualenv embedded ones - if Version(config.version) < Version("3.12"): - venv_args.extend(("--setuptools=embed", "--wheel=embed")) + venv_args = [ + "--no-periodic-update", + f"--pip={pip_version}", + "--no-setuptools", + "--no-wheel", + ] call("python", "-m", "virtualenv", *venv_args, venv_dir, env=env) virtualenv_env = env.copy()