feature: add support for py3-none-{platform} wheels
This extends the mechanism introduced in #1091 for `abi3` wheels. Most of the mentions to `abi3` have been removed and replaced by a more generic `compatible_wheel`. This allows to build a wheel `foo-0.1-py3-none-win_amd64.whl` only once and still test with every configured python.
This commit is contained in:
@@ -12,7 +12,7 @@ from .typing import OrderedDict, PathOrStr, assert_never
|
|||||||
from .util import (
|
from .util import (
|
||||||
BuildSelector,
|
BuildSelector,
|
||||||
NonPlatformWheelError,
|
NonPlatformWheelError,
|
||||||
find_compatible_abi3_wheel,
|
find_compatible_wheel,
|
||||||
get_build_verbosity_extra_flags,
|
get_build_verbosity_extra_flags,
|
||||||
prepare_command,
|
prepare_command,
|
||||||
read_python_configs,
|
read_python_configs,
|
||||||
@@ -177,13 +177,13 @@ def build_on_docker(
|
|||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
|
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||||
if abi3_wheel:
|
if compatible_wheel:
|
||||||
log.step_end()
|
log.step_end()
|
||||||
print(
|
print(
|
||||||
f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
|
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
|
||||||
)
|
)
|
||||||
repaired_wheels = [abi3_wheel]
|
repaired_wheels = [compatible_wheel]
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if build_options.before_build:
|
if build_options.before_build:
|
||||||
@@ -304,7 +304,7 @@ def build_on_docker(
|
|||||||
docker.call(["rm", "-rf", venv_dir])
|
docker.call(["rm", "-rf", venv_dir])
|
||||||
|
|
||||||
# move repaired wheels to output
|
# move repaired wheels to output
|
||||||
if abi3_wheel is None:
|
if compatible_wheel is None:
|
||||||
docker.call(["mkdir", "-p", container_output_dir])
|
docker.call(["mkdir", "-p", container_output_dir])
|
||||||
docker.call(["mv", *repaired_wheels, container_output_dir])
|
docker.call(["mv", *repaired_wheels, container_output_dir])
|
||||||
built_wheels.extend(
|
built_wheels.extend(
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ from .util import (
|
|||||||
call,
|
call,
|
||||||
detect_ci_provider,
|
detect_ci_provider,
|
||||||
download,
|
download,
|
||||||
find_compatible_abi3_wheel,
|
find_compatible_wheel,
|
||||||
get_build_verbosity_extra_flags,
|
get_build_verbosity_extra_flags,
|
||||||
get_pip_version,
|
get_pip_version,
|
||||||
install_certifi_script,
|
install_certifi_script,
|
||||||
@@ -321,13 +321,13 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
build_options.build_frontend,
|
build_options.build_frontend,
|
||||||
)
|
)
|
||||||
|
|
||||||
abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
|
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||||
if abi3_wheel:
|
if compatible_wheel:
|
||||||
log.step_end()
|
log.step_end()
|
||||||
print(
|
print(
|
||||||
f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
|
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
|
||||||
)
|
)
|
||||||
repaired_wheel = abi3_wheel
|
repaired_wheel = compatible_wheel
|
||||||
else:
|
else:
|
||||||
if build_options.before_build:
|
if build_options.before_build:
|
||||||
log.step("Running before_build...")
|
log.step("Running before_build...")
|
||||||
@@ -534,7 +534,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# we're all done here; move it to output (overwrite existing)
|
# we're all done here; move it to output (overwrite existing)
|
||||||
if abi3_wheel is None:
|
if compatible_wheel is None:
|
||||||
try:
|
try:
|
||||||
(build_options.output_dir / repaired_wheel.name).unlink()
|
(build_options.output_dir / repaired_wheel.name).unlink()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
|
|||||||
+11
-9
@@ -54,7 +54,7 @@ __all__ = [
|
|||||||
"MANYLINUX_ARCHS",
|
"MANYLINUX_ARCHS",
|
||||||
"call",
|
"call",
|
||||||
"shell",
|
"shell",
|
||||||
"find_compatible_abi3_wheel",
|
"find_compatible_wheel",
|
||||||
"format_safe",
|
"format_safe",
|
||||||
"prepare_command",
|
"prepare_command",
|
||||||
"get_build_verbosity_extra_flags",
|
"get_build_verbosity_extra_flags",
|
||||||
@@ -574,23 +574,25 @@ def virtualenv(
|
|||||||
T = TypeVar("T", bound=PurePath)
|
T = TypeVar("T", bound=PurePath)
|
||||||
|
|
||||||
|
|
||||||
def find_compatible_abi3_wheel(wheels: Sequence[T], identifier: str) -> Optional[T]:
|
def find_compatible_wheel(wheels: Sequence[T], identifier: str) -> Optional[T]:
|
||||||
"""
|
"""
|
||||||
Finds an ABI3 wheel in `wheels` compatible with the Python interpreter
|
Finds a wheel with an abi3 or a none ABI tag in `wheels` compatible with the Python interpreter
|
||||||
specified by `identifier`.
|
specified by `identifier`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
interpreter, platform = identifier.split("-")
|
interpreter, platform = identifier.split("-")
|
||||||
if not interpreter.startswith("cp3"):
|
|
||||||
return None
|
|
||||||
for wheel in wheels:
|
for wheel in wheels:
|
||||||
_, _, _, tags = parse_wheel_filename(wheel.name)
|
_, _, _, tags = parse_wheel_filename(wheel.name)
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
if tag.abi != "abi3":
|
if tag.abi == "abi3":
|
||||||
|
if not (interpreter.startswith("cp3") and tag.interpreter.startswith("cp3")):
|
||||||
|
continue
|
||||||
|
elif tag.abi == "none":
|
||||||
|
if tag.interpreter[:3] != "py3":
|
||||||
|
continue
|
||||||
|
else:
|
||||||
continue
|
continue
|
||||||
if not tag.interpreter.startswith("cp3"):
|
if tag.interpreter != "py3" and int(tag.interpreter[3:]) > int(interpreter[3:]):
|
||||||
continue
|
|
||||||
if int(tag.interpreter[3:]) > int(interpreter[3:]):
|
|
||||||
continue
|
continue
|
||||||
if platform.startswith(("manylinux", "musllinux", "macosx")):
|
if platform.startswith(("manylinux", "musllinux", "macosx")):
|
||||||
# Linux, macOS
|
# Linux, macOS
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ from .util import (
|
|||||||
NonPlatformWheelError,
|
NonPlatformWheelError,
|
||||||
call,
|
call,
|
||||||
download,
|
download,
|
||||||
find_compatible_abi3_wheel,
|
find_compatible_wheel,
|
||||||
get_build_verbosity_extra_flags,
|
get_build_verbosity_extra_flags,
|
||||||
get_pip_version,
|
get_pip_version,
|
||||||
prepare_command,
|
prepare_command,
|
||||||
@@ -277,13 +277,13 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
build_options.build_frontend,
|
build_options.build_frontend,
|
||||||
)
|
)
|
||||||
|
|
||||||
abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
|
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||||
if abi3_wheel:
|
if compatible_wheel:
|
||||||
log.step_end()
|
log.step_end()
|
||||||
print(
|
print(
|
||||||
f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
|
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
|
||||||
)
|
)
|
||||||
repaired_wheel = abi3_wheel
|
repaired_wheel = compatible_wheel
|
||||||
else:
|
else:
|
||||||
# run the before_build command
|
# run the before_build command
|
||||||
if build_options.before_build:
|
if build_options.before_build:
|
||||||
@@ -418,7 +418,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
shell(test_command_prepared, cwd="c:\\", env=virtualenv_env)
|
shell(test_command_prepared, cwd="c:\\", env=virtualenv_env)
|
||||||
|
|
||||||
# we're all done here; move it to output (remove if already exists)
|
# we're all done here; move it to output (remove if already exists)
|
||||||
if abi3_wheel is None:
|
if compatible_wheel is None:
|
||||||
shutil.move(str(repaired_wheel), build_options.output_dir)
|
shutil.move(str(repaired_wheel), build_options.output_dir)
|
||||||
built_wheels.append(build_options.output_dir / repaired_wheel.name)
|
built_wheels.append(build_options.output_dir / repaired_wheel.name)
|
||||||
|
|
||||||
|
|||||||
+43
-1
@@ -1,4 +1,8 @@
|
|||||||
from cibuildwheel.util import format_safe, prepare_command
|
from pathlib import PurePath
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from cibuildwheel.util import find_compatible_wheel, format_safe, prepare_command
|
||||||
|
|
||||||
|
|
||||||
def test_format_safe():
|
def test_format_safe():
|
||||||
@@ -46,3 +50,41 @@ def test_prepare_command():
|
|||||||
prepare_command("{a}{a,b}{b:.2e}{c}{d%s}{e:3}{f[0]}", a="42", b="3.14159")
|
prepare_command("{a}{a,b}{b:.2e}{c}{d%s}{e:3}{f[0]}", a="42", b="3.14159")
|
||||||
== "42{a,b}{b:.2e}{c}{d%s}{e:3}{f[0]}"
|
== "42{a,b}{b:.2e}{c}{d%s}{e:3}{f[0]}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"wheel,identifier",
|
||||||
|
(
|
||||||
|
("foo-0.1-cp38-abi3-win_amd64.whl", "cp310-win_amd64"),
|
||||||
|
("foo-0.1-cp38-abi3-macosx_11_0_x86_64.whl", "cp310-macosx_x86_64"),
|
||||||
|
("foo-0.1-cp38-abi3-manylinux2014_x86_64.whl", "cp310-manylinux_x86_64"),
|
||||||
|
("foo-0.1-cp38-abi3-musllinux_1_1_x86_64.whl", "cp310-musllinux_x86_64"),
|
||||||
|
("foo-0.1-py2.py3-none-win_amd64.whl", "cp310-win_amd64"),
|
||||||
|
("foo-0.1-py2.py3-none-win_amd64.whl", "pp310-win_amd64"),
|
||||||
|
("foo-0.1-py3-none-win_amd64.whl", "cp310-win_amd64"),
|
||||||
|
("foo-0.1-py38-none-win_amd64.whl", "cp310-win_amd64"),
|
||||||
|
("foo-0.1-py38-none-win_amd64.whl", "pp310-win_amd64"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_find_compatible_wheel_found(wheel: str, identifier: str):
|
||||||
|
wheel_ = PurePath(wheel)
|
||||||
|
found = find_compatible_wheel([wheel_], identifier)
|
||||||
|
assert found is wheel_
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"wheel,identifier",
|
||||||
|
(
|
||||||
|
("foo-0.1-cp38-abi3-win_amd64.whl", "cp310-win32"),
|
||||||
|
("foo-0.1-cp38-abi3-win_amd64.whl", "cp37-win_amd64"),
|
||||||
|
("foo-0.1-cp38-abi3-macosx_11_0_x86_64.whl", "cp310-macosx_universal2"),
|
||||||
|
("foo-0.1-cp38-abi3-manylinux2014_x86_64.whl", "cp310-musllinux_x86_64"),
|
||||||
|
("foo-0.1-cp38-abi3-musllinux_1_1_x86_64.whl", "cp310-manylinux_x86_64"),
|
||||||
|
("foo-0.1-py2-none-win_amd64.whl", "cp310-win_amd64"),
|
||||||
|
("foo-0.1-py38-none-win_amd64.whl", "cp37-win_amd64"),
|
||||||
|
("foo-0.1-py38-none-win_amd64.whl", "pp37-win_amd64"),
|
||||||
|
("foo-0.1-cp38-cp38-win_amd64.whl", "cp310-win_amd64"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_find_compatible_wheel_not_found(wheel: str, identifier: str):
|
||||||
|
assert find_compatible_wheel([PurePath(wheel)], identifier) is None
|
||||||
|
|||||||
Reference in New Issue
Block a user