fix: don't error when a global build-frontend is set on pyodide (#2945)
Since #2609, the pyodide platform required the 'pyodide-build' frontend, but a global build-frontend setting (TOML or CIBW_BUILD_FRONTEND) overrides the platform default, so previously-working configs like build-frontend = "build" failed with a ConfigurationError. Even "default" failed, since it was mapped to "build" before the check. Resolve "default" to the platform default, and warn and use pyodide-build when another frontend is set on pyodide, matching pre-#2609 behavior where the frontend name only affected verbosity flags. Assisted-by: ClaudeCode:claude-opus-4.8
This commit is contained in:
+12
-4
@@ -43,7 +43,7 @@ from packaging.specifiers import SpecifierSet
|
||||
from cibuildwheel import errors
|
||||
from cibuildwheel.architecture import Architecture
|
||||
from cibuildwheel.environment import EnvironmentParseError, ParsedEnvironment, parse_environment
|
||||
from cibuildwheel.frontend import BuildFrontendConfig
|
||||
from cibuildwheel.frontend import BuildFrontendConfig, BuildFrontendName
|
||||
from cibuildwheel.logger import log
|
||||
from cibuildwheel.oci_container import OCIContainerEngineConfig
|
||||
from cibuildwheel.projectfiles import get_requires_python_str, resolve_dependency_groups
|
||||
@@ -850,8 +850,11 @@ class Options:
|
||||
env_plat=False,
|
||||
option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
|
||||
)
|
||||
default_frontend: BuildFrontendName = (
|
||||
"pyodide-build" if self.platform == "pyodide" else "build"
|
||||
)
|
||||
if not build_frontend_str or build_frontend_str == "default":
|
||||
build_frontend = BuildFrontendConfig("build")
|
||||
build_frontend = BuildFrontendConfig(default_frontend)
|
||||
else:
|
||||
try:
|
||||
build_frontend = BuildFrontendConfig.from_config_string(build_frontend_str)
|
||||
@@ -860,8 +863,13 @@ class Options:
|
||||
raise errors.ConfigurationError(msg) from e
|
||||
|
||||
if self.platform == "pyodide" and build_frontend.name != "pyodide-build":
|
||||
msg = "The pyodide platform requires the 'pyodide-build' build frontend"
|
||||
raise errors.ConfigurationError(msg)
|
||||
# pip and uv could become an error, eventually. build -> pyodide-build is
|
||||
# probably fine to keep as a warning
|
||||
log.warning(
|
||||
f"The pyodide platform ignores the {build_frontend.name!r} build "
|
||||
"frontend; using 'pyodide-build' instead"
|
||||
)
|
||||
build_frontend = BuildFrontendConfig("pyodide-build", build_frontend.args)
|
||||
if self.platform != "pyodide" and build_frontend.name == "pyodide-build":
|
||||
msg = "The 'pyodide-build' build frontend is only supported on the pyodide platform"
|
||||
raise errors.ConfigurationError(msg)
|
||||
|
||||
+3
-3
@@ -483,9 +483,9 @@ files (from workspaces) are not supported.
|
||||
|
||||
On Android, the "pip" frontend is not supported.
|
||||
|
||||
On Pyodide, `build-frontend` must be `pyodide-build`, which is the default for that
|
||||
platform. See [Pyodide build frontend support](platforms.md#pyodide-build-frontend) for
|
||||
details.
|
||||
On Pyodide, `pyodide-build` is the default and only supported frontend; setting
|
||||
another frontend produces a warning and uses `pyodide-build` instead. See
|
||||
[Pyodide build frontend support](platforms.md#pyodide-build-frontend) for details.
|
||||
|
||||
You can specify extra arguments to pass to the build frontend using the
|
||||
optional `args` option.
|
||||
|
||||
+1
-1
@@ -190,7 +190,7 @@ The `--libdir` option specifies the directory containing cross-compiled shared l
|
||||
|
||||
### Build frontend support {: #pyodide-build-frontend}
|
||||
|
||||
The pyodide platform builds wheels by shelling out to `pyodide build`, via the `pyodide-build` [`build-frontend`](options.md#build-frontend), which itself is a meta build frontend and passes through commands to pypa/build with specialised handling. This is the only supported frontend for this platform, and is used by default.
|
||||
The pyodide platform builds wheels by shelling out to `pyodide build`, via the `pyodide-build` [`build-frontend`](options.md#build-frontend), which itself is a meta build frontend and passes through commands to pypa/build with specialised handling. This is the only supported frontend for this platform, and is used by default. A global [`build-frontend`](options.md#build-frontend) setting naming another frontend is ignored with a warning on this platform.
|
||||
|
||||
[`build-verbosity`](options.md#build-verbosity) is passed through to `pyodide build` as `-v`/`-vv`. It is capped at `-vv`. `pyodide build` has no `-vvv` flag.
|
||||
|
||||
|
||||
@@ -515,13 +515,33 @@ def test_pyodide_build_frontend_args(tmp_path: Path) -> None:
|
||||
assert build_frontend.args == ["--exports=whole_archive"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"build_frontend_str",
|
||||
["default", "pip", "build", "build[uv]", "uv"],
|
||||
)
|
||||
def test_pyodide_global_build_frontend_coerced(tmp_path: Path, build_frontend_str: str) -> None:
|
||||
"""A global non-pyodide frontend setting is coerced to pyodide-build, not an error."""
|
||||
args = CommandLineArguments.defaults()
|
||||
args.package_dir = tmp_path
|
||||
|
||||
tmp_path.joinpath("pyproject.toml").write_text(
|
||||
textwrap.dedent(
|
||||
f"""\
|
||||
[tool.cibuildwheel]
|
||||
build-frontend = "{build_frontend_str}"
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
options = Options(platform="pyodide", command_line_arguments=args, env={})
|
||||
build_frontend = options.build_options(identifier=None).build_frontend
|
||||
|
||||
assert build_frontend.name == "pyodide-build"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("platform", "build_frontend_str"),
|
||||
[
|
||||
("pyodide", "pip"),
|
||||
("pyodide", "build"),
|
||||
("pyodide", "build[uv]"),
|
||||
("pyodide", "uv"),
|
||||
("linux", "pyodide-build"),
|
||||
("macos", "pyodide-build"),
|
||||
("windows", "pyodide-build"),
|
||||
|
||||
Reference in New Issue
Block a user