Skip to content

Commit 61e9ddc

Browse files
committed
feature: add support for py3-none-{platform} wheels
This extends the mechanism introduced in pypa#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.
1 parent 0bf4f7a commit 61e9ddc

File tree

5 files changed

+75
-28
lines changed

5 files changed

+75
-28
lines changed

cibuildwheel/linux.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from .util import (
1313
BuildSelector,
1414
NonPlatformWheelError,
15-
find_compatible_abi3_wheel,
15+
find_compatible_wheel,
1616
get_build_verbosity_extra_flags,
1717
prepare_command,
1818
read_python_configs,
@@ -177,13 +177,13 @@ def build_on_docker(
177177
)
178178
sys.exit(1)
179179

180-
abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
181-
if abi3_wheel:
180+
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
181+
if compatible_wheel:
182182
log.step_end()
183183
print(
184-
f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
184+
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
185185
)
186-
repaired_wheels = [abi3_wheel]
186+
repaired_wheels = [compatible_wheel]
187187
else:
188188

189189
if build_options.before_build:
@@ -304,7 +304,7 @@ def build_on_docker(
304304
docker.call(["rm", "-rf", venv_dir])
305305

306306
# move repaired wheels to output
307-
if abi3_wheel is None:
307+
if compatible_wheel is None:
308308
docker.call(["mkdir", "-p", container_output_dir])
309309
docker.call(["mv", *repaired_wheels, container_output_dir])
310310
built_wheels.extend(

cibuildwheel/macos.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
call,
2424
detect_ci_provider,
2525
download,
26-
find_compatible_abi3_wheel,
26+
find_compatible_wheel,
2727
get_build_verbosity_extra_flags,
2828
get_pip_version,
2929
install_certifi_script,
@@ -321,13 +321,13 @@ def build(options: Options, tmp_path: Path) -> None:
321321
build_options.build_frontend,
322322
)
323323

324-
abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
325-
if abi3_wheel:
324+
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
325+
if compatible_wheel:
326326
log.step_end()
327327
print(
328-
f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
328+
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
329329
)
330-
repaired_wheel = abi3_wheel
330+
repaired_wheel = compatible_wheel
331331
else:
332332
if build_options.before_build:
333333
log.step("Running before_build...")
@@ -534,7 +534,7 @@ def build(options: Options, tmp_path: Path) -> None:
534534
)
535535

536536
# we're all done here; move it to output (overwrite existing)
537-
if abi3_wheel is None:
537+
if compatible_wheel is None:
538538
try:
539539
(build_options.output_dir / repaired_wheel.name).unlink()
540540
except FileNotFoundError:

cibuildwheel/util.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"MANYLINUX_ARCHS",
5555
"call",
5656
"shell",
57-
"find_compatible_abi3_wheel",
57+
"find_compatible_wheel",
5858
"format_safe",
5959
"prepare_command",
6060
"get_build_verbosity_extra_flags",
@@ -574,23 +574,25 @@ def virtualenv(
574574
T = TypeVar("T", bound=PurePath)
575575

576576

577-
def find_compatible_abi3_wheel(wheels: Sequence[T], identifier: str) -> Optional[T]:
577+
def find_compatible_wheel(wheels: Sequence[T], identifier: str) -> Optional[T]:
578578
"""
579-
Finds an ABI3 wheel in `wheels` compatible with the Python interpreter
579+
Finds a wheel with an abi3 or a none ABI tag in `wheels` compatible with the Python interpreter
580580
specified by `identifier`.
581581
"""
582582

583583
interpreter, platform = identifier.split("-")
584-
if not interpreter.startswith("cp3"):
585-
return None
586584
for wheel in wheels:
587585
_, _, _, tags = parse_wheel_filename(wheel.name)
588586
for tag in tags:
589-
if tag.abi != "abi3":
590-
continue
591-
if not tag.interpreter.startswith("cp3"):
587+
if tag.abi == "abi3":
588+
if not (interpreter.startswith("cp3") and tag.interpreter.startswith("cp3")):
589+
continue
590+
elif tag.abi == "none":
591+
if tag.interpreter[:3] != "py3" and tag.interpreter[:3] != interpreter[:3]:
592+
continue
593+
else:
592594
continue
593-
if int(tag.interpreter[3:]) > int(interpreter[3:]):
595+
if tag.interpreter != "py3" and int(tag.interpreter[3:]) > int(interpreter[3:]):
594596
continue
595597
if platform.startswith(("manylinux", "musllinux", "macosx")):
596598
# Linux, macOS

cibuildwheel/windows.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
NonPlatformWheelError,
2323
call,
2424
download,
25-
find_compatible_abi3_wheel,
25+
find_compatible_wheel,
2626
get_build_verbosity_extra_flags,
2727
get_pip_version,
2828
prepare_command,
@@ -277,13 +277,13 @@ def build(options: Options, tmp_path: Path) -> None:
277277
build_options.build_frontend,
278278
)
279279

280-
abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
281-
if abi3_wheel:
280+
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
281+
if compatible_wheel:
282282
log.step_end()
283283
print(
284-
f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
284+
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
285285
)
286-
repaired_wheel = abi3_wheel
286+
repaired_wheel = compatible_wheel
287287
else:
288288
# run the before_build command
289289
if build_options.before_build:
@@ -418,7 +418,7 @@ def build(options: Options, tmp_path: Path) -> None:
418418
shell(test_command_prepared, cwd="c:\\", env=virtualenv_env)
419419

420420
# we're all done here; move it to output (remove if already exists)
421-
if abi3_wheel is None:
421+
if compatible_wheel is None:
422422
shutil.move(str(repaired_wheel), build_options.output_dir)
423423
built_wheels.append(build_options.output_dir / repaired_wheel.name)
424424

unit_test/utils_test.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
from cibuildwheel.util import format_safe, prepare_command
1+
from pathlib import PurePath
2+
3+
import pytest
4+
5+
from cibuildwheel.util import find_compatible_wheel, format_safe, prepare_command
26

37

48
def test_format_safe():
@@ -46,3 +50,44 @@ def test_prepare_command():
4650
prepare_command("{a}{a,b}{b:.2e}{c}{d%s}{e:3}{f[0]}", a="42", b="3.14159")
4751
== "42{a,b}{b:.2e}{c}{d%s}{e:3}{f[0]}"
4852
)
53+
54+
55+
@pytest.mark.parametrize(
56+
"wheel,identifier",
57+
(
58+
("foo-0.1-cp38-abi3-win_amd64.whl", "cp310-win_amd64"),
59+
("foo-0.1-cp38-abi3-macosx_11_0_x86_64.whl", "cp310-macosx_x86_64"),
60+
("foo-0.1-cp38-abi3-manylinux2014_x86_64.whl", "cp310-manylinux_x86_64"),
61+
("foo-0.1-cp38-abi3-musllinux_1_1_x86_64.whl", "cp310-musllinux_x86_64"),
62+
("foo-0.1-py2.py3-none-win_amd64.whl", "cp310-win_amd64"),
63+
("foo-0.1-py2.py3-none-win_amd64.whl", "pp310-win_amd64"),
64+
("foo-0.1-py38-none-win_amd64.whl", "cp310-win_amd64"),
65+
("foo-0.1-py38-none-win_amd64.whl", "pp310-win_amd64"),
66+
("foo-0.1-cp38-none-win_amd64.whl", "cp310-win_amd64"),
67+
("foo-0.1-pp38-none-win_amd64.whl", "pp310-win_amd64"),
68+
),
69+
)
70+
def test_find_compatible_wheel_found(wheel: str, identifier: str):
71+
wheel_ = PurePath(wheel)
72+
found = find_compatible_wheel([wheel_], identifier)
73+
assert found is wheel_
74+
75+
76+
@pytest.mark.parametrize(
77+
"wheel,identifier",
78+
(
79+
("foo-0.1-cp38-abi3-win_amd64.whl", "cp310-win32"),
80+
("foo-0.1-cp38-abi3-win_amd64.whl", "cp37-win_amd64"),
81+
("foo-0.1-cp38-abi3-macosx_11_0_x86_64.whl", "cp310-macosx_universal2"),
82+
("foo-0.1-cp38-abi3-manylinux2014_x86_64.whl", "cp310-musllinux_x86_64"),
83+
("foo-0.1-cp38-abi3-musllinux_1_1_x86_64.whl", "cp310-manylinux_x86_64"),
84+
("foo-0.1-py2-none-win_amd64.whl", "cp310-win_amd64"),
85+
("foo-0.1-py38-none-win_amd64.whl", "cp37-win_amd64"),
86+
("foo-0.1-py38-none-win_amd64.whl", "pp37-win_amd64"),
87+
("foo-0.1-cp38-none-win_amd64.whl", "cp37-win_amd64"),
88+
("foo-0.1-pp38-none-win_amd64.whl", "pp37-win_amd64"),
89+
("foo-0.1-cp38-cp38-win_amd64.whl", "cp310-win_amd64"),
90+
),
91+
)
92+
def test_find_compatible_wheel_not_found(wheel: str, identifier: str):
93+
assert find_compatible_wheel([PurePath(wheel)], identifier) is None

0 commit comments

Comments
 (0)