Skip to content

Commit 1ea0fab

Browse files
committed
Merge branch 'main' into ios-support
2 parents f29439b + 25f2d3f commit 1ea0fab

31 files changed

+505
-180
lines changed

.github/workflows/release.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
path: dist
3434

3535
- name: Generate artifact attestation for sdist and wheel
36-
uses: actions/attest-build-provenance@520d128f165991a6c774bcb264f323e3d70747f4 # v2.2.0
36+
uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3
3737
with:
3838
subject-path: "dist/cibuildwheel-*"
3939

.pre-commit-config.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ repos:
1414
- id: trailing-whitespace
1515

1616
- repo: https://github.com/astral-sh/ruff-pre-commit
17-
rev: v0.9.7
17+
rev: v0.9.10
1818
hooks:
1919
- id: ruff
2020
args: ["--fix", "--show-fixes"]
@@ -81,7 +81,7 @@ repos:
8181

8282

8383
- repo: https://github.com/python-jsonschema/check-jsonschema
84-
rev: 0.31.2
84+
rev: 0.31.3
8585
hooks:
8686
- id: check-dependabot
8787
- id: check-github-actions

bin/generate_schema.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,24 @@
104104
dependency-versions:
105105
default: pinned
106106
description: Specify how cibuildwheel controls the versions of the tools it uses
107-
type: string
107+
oneOf:
108+
- enum: [pinned, latest]
109+
- type: string
110+
description: Path to a file containing dependency versions, or inline package specifications, starting with "packages:"
111+
not:
112+
enum: [pinned, latest]
113+
- type: object
114+
additionalProperties: false
115+
properties:
116+
file:
117+
type: string
118+
- type: object
119+
additionalProperties: false
120+
properties:
121+
packages:
122+
type: array
123+
items:
124+
type: string
108125
enable:
109126
description: Enable or disable certain builds.
110127
oneOf:

cibuildwheel/linux.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ def build_in_container(
166166
container: OCIContainer,
167167
container_project_path: PurePath,
168168
container_package_dir: PurePath,
169+
local_tmp_dir: Path,
169170
) -> None:
170171
container_output_dir = PurePosixPath("/output")
171172

@@ -199,22 +200,22 @@ def build_in_container(
199200

200201
for config in platform_configs:
201202
log.build_start(config.identifier)
203+
local_identifier_tmp_dir = local_tmp_dir / config.identifier
202204
build_options = options.build_options(config.identifier)
203205
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
204206
use_uv = build_frontend.name == "build[uv]"
205207
pip = ["uv", "pip"] if use_uv else ["pip"]
206208

207-
dependency_constraint_flags: list[PathOrStr] = []
208-
209209
log.step("Setting up build environment...")
210210

211-
if build_options.dependency_constraints:
212-
constraints_file = build_options.dependency_constraints.get_for_python_version(
213-
config.version
214-
)
211+
dependency_constraint_flags: list[PathOrStr] = []
212+
local_constraints_file = build_options.dependency_constraints.get_for_python_version(
213+
version=config.version,
214+
tmp_dir=local_identifier_tmp_dir,
215+
)
216+
if local_constraints_file:
215217
container_constraints_file = PurePosixPath("/constraints.txt")
216-
217-
container.copy_into(constraints_file, container_constraints_file)
218+
container.copy_into(local_constraints_file, container_constraints_file)
218219
dependency_constraint_flags = ["-c", container_constraints_file]
219220

220221
env = container.get_environment()
@@ -426,7 +427,7 @@ def build_in_container(
426427
log.step_end()
427428

428429

429-
def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
430+
def build(options: Options, tmp_path: Path) -> None:
430431
python_configurations = get_python_configurations(
431432
options.globals.build_selector, options.globals.architectures
432433
)
@@ -480,6 +481,7 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
480481
container=container,
481482
container_project_path=container_project_path,
482483
container_package_dir=container_package_dir,
484+
local_tmp_dir=tmp_path,
483485
)
484486

485487
except subprocess.CalledProcessError as error:

cibuildwheel/macos.py

+8-11
Original file line numberDiff line numberDiff line change
@@ -421,12 +421,12 @@ def build(options: Options, tmp_path: Path) -> None:
421421
config_is_arm64 = config.identifier.endswith("arm64")
422422
config_is_universal2 = config.identifier.endswith("universal2")
423423

424-
dependency_constraint_flags: Sequence[PathOrStr] = []
425-
if build_options.dependency_constraints:
426-
dependency_constraint_flags = [
427-
"-c",
428-
build_options.dependency_constraints.get_for_python_version(config.version),
429-
]
424+
constraints_path = build_options.dependency_constraints.get_for_python_version(
425+
version=config.version, tmp_dir=identifier_tmp_dir
426+
)
427+
dependency_constraint_flags: Sequence[PathOrStr] = (
428+
["-c", constraints_path] if constraints_path else []
429+
)
430430

431431
base_python, env = setup_python(
432432
identifier_tmp_dir / "build",
@@ -463,12 +463,9 @@ def build(options: Options, tmp_path: Path) -> None:
463463
build_env = env.copy()
464464
if not use_uv:
465465
build_env["VIRTUALENV_PIP"] = pip_version
466-
if build_options.dependency_constraints:
467-
constraint_path = build_options.dependency_constraints.get_for_python_version(
468-
config.version
469-
)
466+
if constraints_path:
470467
combine_constraints(
471-
build_env, constraint_path, identifier_tmp_dir if use_uv else None
468+
build_env, constraints_path, identifier_tmp_dir if use_uv else None
472469
)
473470

474471
if build_frontend.name == "pip":

cibuildwheel/options.py

+20-12
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class BuildOptions:
9797
repair_command: str
9898
manylinux_images: dict[str, str] | None
9999
musllinux_images: dict[str, str] | None
100-
dependency_constraints: DependencyConstraints | None
100+
dependency_constraints: DependencyConstraints
101101
test_command: str | None
102102
before_test: str | None
103103
test_sources: list[str]
@@ -591,6 +591,10 @@ def __init__(
591591
except FileNotFoundError:
592592
self.pyproject_toml = None
593593

594+
# cache the build options method so repeated calls don't need to
595+
# resolve the options again
596+
self.build_options = functools.cache(self._compute_build_options)
597+
594598
@functools.cached_property
595599
def config_file_path(self) -> Path | None:
596600
args = self.command_line_arguments
@@ -667,9 +671,11 @@ def globals(self) -> GlobalOptions:
667671
allow_empty=allow_empty,
668672
)
669673

670-
def build_options(self, identifier: str | None) -> BuildOptions:
674+
def _compute_build_options(self, identifier: str | None) -> BuildOptions:
671675
"""
672-
Compute BuildOptions for a single run configuration.
676+
Compute BuildOptions for a single run configuration. Normally accessed
677+
through the `build_options` method, which is the same but the result
678+
is cached.
673679
"""
674680

675681
with self.reader.identifier(identifier):
@@ -687,7 +693,6 @@ def build_options(self, identifier: str | None) -> BuildOptions:
687693
"config-settings", option_format=ShlexTableFormat(sep=" ", pair_sep="=")
688694
)
689695

690-
dependency_versions = self.reader.get("dependency-versions")
691696
test_command = self.reader.get("test-command", option_format=ListFormat(sep=" && "))
692697
before_test = self.reader.get("before-test", option_format=ListFormat(sep=" && "))
693698
test_sources = shlex.split(
@@ -733,15 +738,18 @@ def build_options(self, identifier: str | None) -> BuildOptions:
733738
with contextlib.suppress(KeyError):
734739
environment.add(env_var_name, self.env[env_var_name], prepend=True)
735740

736-
if dependency_versions == "pinned":
737-
dependency_constraints: DependencyConstraints | None = (
738-
DependencyConstraints.with_defaults()
741+
dependency_versions_str = self.reader.get(
742+
"dependency-versions",
743+
env_plat=True,
744+
option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
745+
)
746+
try:
747+
dependency_constraints = DependencyConstraints.from_config_string(
748+
dependency_versions_str
739749
)
740-
elif dependency_versions == "latest":
741-
dependency_constraints = None
742-
else:
743-
dependency_versions_path = Path(dependency_versions)
744-
dependency_constraints = DependencyConstraints(dependency_versions_path)
750+
except (ValueError, OSError) as e:
751+
msg = f"Failed to parse dependency versions. {e}"
752+
raise errors.ConfigurationError(msg) from e
745753

746754
if test_extras:
747755
test_extras = f"[{test_extras}]"

cibuildwheel/pyodide.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,12 @@ def build(options: Options, tmp_path: Path) -> None:
265265
built_wheel_dir.mkdir()
266266
repaired_wheel_dir.mkdir()
267267

268-
dependency_constraint_flags: Sequence[PathOrStr] = []
269-
if build_options.dependency_constraints:
270-
constraints_path = build_options.dependency_constraints.get_for_python_version(
271-
config.version, variant="pyodide"
272-
)
273-
dependency_constraint_flags = ["-c", constraints_path]
268+
constraints_path = build_options.dependency_constraints.get_for_python_version(
269+
version=config.version, variant="pyodide", tmp_dir=identifier_tmp_dir
270+
)
271+
dependency_constraint_flags: Sequence[PathOrStr] = (
272+
["-c", constraints_path] if constraints_path else []
273+
)
274274

275275
env = setup_python(
276276
identifier_tmp_dir / "build",
@@ -319,7 +319,7 @@ def build(options: Options, tmp_path: Path) -> None:
319319
)
320320

321321
build_env = env.copy()
322-
if build_options.dependency_constraints:
322+
if constraints_path:
323323
combine_constraints(build_env, constraints_path, identifier_tmp_dir)
324324
build_env["VIRTUALENV_PIP"] = pip_version
325325
call(

cibuildwheel/resources/build-platforms.toml

+6-6
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,10 @@ python_configurations = [
125125
{ identifier = "pp38-macosx_arm64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_arm64.tar.bz2" },
126126
{ identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2" },
127127
{ identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.bz2" },
128-
{ identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.18-macos_x86_64.tar.bz2" },
129-
{ identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.18-macos_arm64.tar.bz2" },
130-
{ identifier = "pp311-macosx_x86_64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.18-macos_x86_64.tar.bz2" },
131-
{ identifier = "pp311-macosx_arm64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.18-macos_arm64.tar.bz2" },
128+
{ identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_x86_64.tar.bz2" },
129+
{ identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_arm64.tar.bz2" },
130+
{ identifier = "pp311-macosx_x86_64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.19-macos_x86_64.tar.bz2" },
131+
{ identifier = "pp311-macosx_arm64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.19-macos_arm64.tar.bz2" },
132132
]
133133

134134
[windows]
@@ -155,8 +155,8 @@ python_configurations = [
155155
{ identifier = "cp313t-win_arm64", version = "3.13.2", arch = "ARM64" },
156156
{ identifier = "pp38-win_amd64", version = "3.8", arch = "64", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-win64.zip" },
157157
{ identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" },
158-
{ identifier = "pp310-win_amd64", version = "3.10", arch = "64", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.18-win64.zip" },
159-
{ identifier = "pp311-win_amd64", version = "3.11", arch = "64", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.18-win64.zip" },
158+
{ identifier = "pp310-win_amd64", version = "3.10", arch = "64", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-win64.zip" },
159+
{ identifier = "pp311-win_amd64", version = "3.11", arch = "64", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.19-win64.zip" },
160160
]
161161

162162
[pyodide]

cibuildwheel/resources/cibuildwheel.schema.json

+39-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,45 @@
233233
"dependency-versions": {
234234
"default": "pinned",
235235
"description": "Specify how cibuildwheel controls the versions of the tools it uses",
236-
"type": "string",
236+
"oneOf": [
237+
{
238+
"enum": [
239+
"pinned",
240+
"latest"
241+
]
242+
},
243+
{
244+
"type": "string",
245+
"description": "Path to a file containing dependency versions, or inline package specifications, starting with \"packages:\"",
246+
"not": {
247+
"enum": [
248+
"pinned",
249+
"latest"
250+
]
251+
}
252+
},
253+
{
254+
"type": "object",
255+
"additionalProperties": false,
256+
"properties": {
257+
"file": {
258+
"type": "string"
259+
}
260+
}
261+
},
262+
{
263+
"type": "object",
264+
"additionalProperties": false,
265+
"properties": {
266+
"packages": {
267+
"type": "array",
268+
"items": {
269+
"type": "string"
270+
}
271+
}
272+
}
273+
}
274+
],
237275
"title": "CIBW_DEPENDENCY_VERSIONS"
238276
},
239277
"enable": {

cibuildwheel/resources/constraints-pyodide312.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ charset-normalizer==3.4.1
1919
# via requests
2020
click==8.1.8
2121
# via typer
22-
cmake==3.31.4
22+
cmake==3.31.6
2323
# via pyodide-build
2424
distlib==0.3.9
2525
# via virtualenv
@@ -87,7 +87,7 @@ shellingham==1.5.4
8787
# via typer
8888
sniffio==1.3.1
8989
# via anyio
90-
typer==0.15.1
90+
typer==0.15.2
9191
# via
9292
# auditwheel-emscripten
9393
# pyodide-build
@@ -102,7 +102,7 @@ unearth==0.17.2
102102
# via pyodide-build
103103
urllib3==2.3.0
104104
# via requests
105-
virtualenv==20.29.2
105+
virtualenv==20.29.3
106106
# via
107107
# build
108108
# pyodide-build

cibuildwheel/resources/constraints-python310.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ tomli==2.2.1
2828
# via build
2929
typing-extensions==4.12.2
3030
# via delocate
31-
virtualenv==20.29.2
31+
virtualenv==20.29.3
3232
# via -r cibuildwheel/resources/constraints.in
3333
zipp==3.21.0
3434
# via importlib-metadata

cibuildwheel/resources/constraints-python311.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ pyproject-hooks==1.2.0
2424
# via build
2525
typing-extensions==4.12.2
2626
# via delocate
27-
virtualenv==20.29.2
27+
virtualenv==20.29.3
2828
# via -r cibuildwheel/resources/constraints.in

cibuildwheel/resources/constraints-python312.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ pyproject-hooks==1.2.0
2424
# via build
2525
typing-extensions==4.12.2
2626
# via delocate
27-
virtualenv==20.29.2
27+
virtualenv==20.29.3
2828
# via -r cibuildwheel/resources/constraints.in

cibuildwheel/resources/constraints-python313.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ pyproject-hooks==1.2.0
2424
# via build
2525
typing-extensions==4.12.2
2626
# via delocate
27-
virtualenv==20.29.2
27+
virtualenv==20.29.3
2828
# via -r cibuildwheel/resources/constraints.in

0 commit comments

Comments
 (0)