fix(schema): default is fine for pyodide too (#2951)
This commit is contained in:
@@ -122,3 +122,4 @@ site/
|
||||
|
||||
# This file should be a symlink or contain "See @AGENTS.md"
|
||||
CLAUDE.md
|
||||
.claude/
|
||||
|
||||
+53
-42
@@ -35,7 +35,7 @@ $defs:
|
||||
- pyodide-prerelease
|
||||
- pypy
|
||||
- pypy-eol
|
||||
description: A Python version or flavor to enable.
|
||||
description: A Python version or flavor to enable.
|
||||
additionalProperties: false
|
||||
description: cibuildwheel's settings.
|
||||
type: object
|
||||
@@ -62,29 +62,7 @@ properties:
|
||||
default: ['*']
|
||||
description: Choose the Python versions to build.
|
||||
type: string_array
|
||||
build-frontend:
|
||||
default: default
|
||||
description: Set the tool to use to build, either "build" (default), "build[uv]", "uv", or "pip"
|
||||
oneOf:
|
||||
- enum: [pip, build, "build[uv]", uv, default]
|
||||
- type: string
|
||||
pattern: '^pip; ?args:'
|
||||
- type: string
|
||||
pattern: '^build; ?args:'
|
||||
- type: string
|
||||
pattern: '^build\\[uv\\]; ?args:'
|
||||
- type: string
|
||||
pattern: '^uv; ?args:'
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
required: [name]
|
||||
properties:
|
||||
name:
|
||||
enum: [pip, build, "build[uv]", uv]
|
||||
args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
build-frontend: {} # filled in by build_frontend_schema below
|
||||
build-verbosity:
|
||||
type: integer
|
||||
minimum: -3
|
||||
@@ -292,6 +270,43 @@ string_table = yaml.safe_load(
|
||||
"""
|
||||
)
|
||||
|
||||
FRONTENDS = ["pip", "build", "build[uv]", "uv"]
|
||||
|
||||
|
||||
def build_frontend_schema(
|
||||
names: list[str], description: str, default: str = "default"
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
A frontend is a name, a "name; args: ..." string, or a table with a name and args.
|
||||
"""
|
||||
# Only the brackets in "build[uv]" need escaping
|
||||
patterns = [name.replace("[", r"\[").replace("]", r"\]") for name in names]
|
||||
return {
|
||||
"default": default,
|
||||
"description": description,
|
||||
"oneOf": [
|
||||
{"enum": [*names, "default"]},
|
||||
*({"type": "string", "pattern": f"^{pattern}; ?args:"} for pattern in patterns),
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["name"],
|
||||
"properties": {
|
||||
"name": {"enum": names},
|
||||
"args": {"type": "array", "items": {"type": "string"}},
|
||||
},
|
||||
},
|
||||
],
|
||||
"title": "CIBW_BUILD_FRONTEND",
|
||||
}
|
||||
|
||||
|
||||
schema["properties"]["build-frontend"] = build_frontend_schema(
|
||||
[*FRONTENDS, "pyodide-build"],
|
||||
'Set the tool to use to build, either "build" (default), "build[uv]", "uv", or "pip"'
|
||||
' ("pyodide-build" for pyodide)',
|
||||
)
|
||||
|
||||
for value in schema["properties"].values():
|
||||
match value:
|
||||
case {"type": "string_array"}:
|
||||
@@ -393,24 +408,20 @@ for os_name, command in [
|
||||
|
||||
del oses["linux"]["properties"]["dependency-versions"]
|
||||
|
||||
oses["pyodide"]["properties"]["build-frontend"] = {
|
||||
**schema["properties"]["build-frontend"],
|
||||
"default": "pyodide-build",
|
||||
"description": 'On the pyodide platform, the build frontend must be "pyodide-build"',
|
||||
"oneOf": [
|
||||
{"enum": ["pyodide-build"]},
|
||||
{"type": "string", "pattern": "^pyodide-build; ?args:"},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["name"],
|
||||
"properties": {
|
||||
"name": {"enum": ["pyodide-build"]},
|
||||
"args": {"type": "array", "items": {"type": "string"}},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
schema["$defs"]["build-frontend-no-pyodide"] = build_frontend_schema(
|
||||
FRONTENDS,
|
||||
'Set the tool to use to build, either "build" (default), "build[uv]", "uv", or "pip"',
|
||||
)
|
||||
|
||||
for os_val in oses.values():
|
||||
os_val["properties"]["build-frontend"] = {"$ref": "#/$defs/build-frontend-no-pyodide"}
|
||||
|
||||
oses["pyodide"]["properties"]["build-frontend"] = build_frontend_schema(
|
||||
["pyodide-build"],
|
||||
'On the pyodide platform, the build frontend must be "pyodide-build"',
|
||||
default="pyodide-build",
|
||||
)
|
||||
|
||||
schema["properties"]["overrides"] = overrides
|
||||
schema["properties"] |= oses
|
||||
|
||||
@@ -18,9 +18,64 @@
|
||||
"pyodide-prerelease",
|
||||
"pypy",
|
||||
"pypy-eol"
|
||||
]
|
||||
],
|
||||
"description": "A Python version or flavor to enable."
|
||||
},
|
||||
"description": "A Python version or flavor to enable."
|
||||
"build-frontend-no-pyodide": {
|
||||
"default": "default",
|
||||
"description": "Set the tool to use to build, either \"build\" (default), \"build[uv]\", \"uv\", or \"pip\"",
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"pip",
|
||||
"build",
|
||||
"build[uv]",
|
||||
"uv",
|
||||
"default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^pip; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^build; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^build\\[uv\\]; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^uv; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"enum": [
|
||||
"pip",
|
||||
"build",
|
||||
"build[uv]",
|
||||
"uv"
|
||||
]
|
||||
},
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_BUILD_FRONTEND"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"description": "cibuildwheel's settings.",
|
||||
@@ -136,7 +191,7 @@
|
||||
},
|
||||
"build-frontend": {
|
||||
"default": "default",
|
||||
"description": "Set the tool to use to build, either \"build\" (default), \"build[uv]\", \"uv\", or \"pip\"",
|
||||
"description": "Set the tool to use to build, either \"build\" (default), \"build[uv]\", \"uv\", or \"pip\" (\"pyodide-build\" for pyodide)",
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
@@ -144,6 +199,7 @@
|
||||
"build",
|
||||
"build[uv]",
|
||||
"uv",
|
||||
"pyodide-build",
|
||||
"default"
|
||||
]
|
||||
},
|
||||
@@ -163,6 +219,10 @@
|
||||
"type": "string",
|
||||
"pattern": "^uv; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^pyodide-build; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -175,7 +235,8 @@
|
||||
"pip",
|
||||
"build",
|
||||
"build[uv]",
|
||||
"uv"
|
||||
"uv",
|
||||
"pyodide-build"
|
||||
]
|
||||
},
|
||||
"args": {
|
||||
@@ -894,7 +955,7 @@
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
"$ref": "#/$defs/build-frontend-no-pyodide"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
@@ -1033,7 +1094,7 @@
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
"$ref": "#/$defs/build-frontend-no-pyodide"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
@@ -1118,7 +1179,7 @@
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
"$ref": "#/$defs/build-frontend-no-pyodide"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
@@ -1208,7 +1269,8 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"pyodide-build"
|
||||
"pyodide-build",
|
||||
"default"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1308,7 +1370,7 @@
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
"$ref": "#/$defs/build-frontend-no-pyodide"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
@@ -1393,7 +1455,7 @@
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
"$ref": "#/$defs/build-frontend-no-pyodide"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
|
||||
@@ -143,6 +143,65 @@ def test_overrides_invalid_inherit_value(validator: validate_pyproject.api.Valid
|
||||
validator(example)
|
||||
|
||||
|
||||
def test_pyodide_build_frontend(validator: validate_pyproject.api.Validator) -> None:
|
||||
"""
|
||||
pyodide-build is accepted anywhere the frontend can be set, as an override
|
||||
or a global value can apply to pyodide builds only.
|
||||
"""
|
||||
example = tomllib.loads(
|
||||
"""
|
||||
[tool.cibuildwheel]
|
||||
build-frontend = "pyodide-build"
|
||||
|
||||
[tool.cibuildwheel.pyodide]
|
||||
build-frontend = { name = "pyodide-build", args = ["--some-arg"] }
|
||||
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "*pyodide*"
|
||||
build-frontend = "pyodide-build; args: --some-arg"
|
||||
"""
|
||||
)
|
||||
|
||||
assert validator(example) is not None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("frontend", ['"uv"', '"build; args: --some-arg"', '{ name = "pip" }'])
|
||||
def test_pyodide_bad_build_frontend(
|
||||
validator: validate_pyproject.api.Validator, frontend: str
|
||||
) -> None:
|
||||
"""
|
||||
The pyodide table only accepts the pyodide-build frontend.
|
||||
"""
|
||||
example = tomllib.loads(
|
||||
f"""
|
||||
[tool.cibuildwheel.pyodide]
|
||||
build-frontend = {frontend}
|
||||
"""
|
||||
)
|
||||
|
||||
with pytest.raises(validate_pyproject.error_reporting.ValidationError):
|
||||
validator(example)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("platform", ["linux", "macos", "windows", "ios", "android"])
|
||||
@pytest.mark.parametrize("frontend", ["pyodide-build", "pyodide-build; args: --some-arg"])
|
||||
def test_bad_pyodide_build_frontend(
|
||||
validator: validate_pyproject.api.Validator, platform: str, frontend: str
|
||||
) -> None:
|
||||
"""
|
||||
Only the pyodide table accepts the pyodide-build frontend.
|
||||
"""
|
||||
example = tomllib.loads(
|
||||
f"""
|
||||
[tool.cibuildwheel.{platform}]
|
||||
build-frontend = "{frontend}"
|
||||
"""
|
||||
)
|
||||
|
||||
with pytest.raises(validate_pyproject.error_reporting.ValidationError):
|
||||
validator(example)
|
||||
|
||||
|
||||
def test_docs_examples(validator: validate_pyproject.api.Validator) -> None:
|
||||
"""
|
||||
Parse out all the configuration examples, build valid TOML out of them, and
|
||||
|
||||
Reference in New Issue
Block a user