diff --git a/bin/generate_schema.py b/bin/generate_schema.py index e6c1c07f5..708cc3180 100755 --- a/bin/generate_schema.py +++ b/bin/generate_schema.py @@ -157,7 +157,9 @@ string_table_array = yaml.safe_load( """ - type: string -- patternProperties: +- type: object + additionalProperties: false + patternProperties: .+: oneOf: - type: string @@ -170,7 +172,9 @@ string_table = yaml.safe_load( """ - type: string -- patternProperties: +- type: object + additionalProperties: false + patternProperties: .+: - type: string """ @@ -207,11 +211,12 @@ del non_global_options["skip"] del non_global_options["container-engine"] del non_global_options["test-skip"] -del non_global_options["archs"] overrides["items"]["properties"]["select"]["oneOf"] = string_array overrides["items"]["properties"] |= non_global_options.copy() +del overrides["items"]["properties"]["archs"] + not_linux = non_global_options.copy() del not_linux["environment-pass"] diff --git a/cibuildwheel/resources/cibuildwheel.schema.json b/cibuildwheel/resources/cibuildwheel.schema.json index a02c8a140..58fb31094 100644 --- a/cibuildwheel/resources/cibuildwheel.schema.json +++ b/cibuildwheel/resources/cibuildwheel.schema.json @@ -142,6 +142,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": { "oneOf": [ @@ -214,6 +216,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": [ { @@ -522,6 +526,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": { "oneOf": [ @@ -554,6 +560,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": [ { @@ -712,6 +720,21 @@ "type": "object", "additionalProperties": false, "properties": { + "archs": { + "description": "Change the architectures built on your machine by default.", + "title": "CIBW_ARCHS", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, "before-all": { "description": "Execute a shell command on the build system before any wheels are built.", "title": "CIBW_BEFORE_ALL", @@ -816,6 +839,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": { "oneOf": [ @@ -842,6 +867,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": [ { @@ -999,6 +1026,21 @@ "type": "object", "additionalProperties": false, "properties": { + "archs": { + "description": "Change the architectures built on your machine by default.", + "title": "CIBW_ARCHS", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, "before-all": { "description": "Execute a shell command on the build system before any wheels are built.", "title": "CIBW_BEFORE_ALL", @@ -1103,6 +1145,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": { "oneOf": [ @@ -1135,6 +1179,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": [ { @@ -1212,6 +1258,21 @@ "type": "object", "additionalProperties": false, "properties": { + "archs": { + "description": "Change the architectures built on your machine by default.", + "title": "CIBW_ARCHS", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, "before-all": { "description": "Execute a shell command on the build system before any wheels are built.", "title": "CIBW_BEFORE_ALL", @@ -1316,6 +1377,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": { "oneOf": [ @@ -1348,6 +1411,8 @@ "type": "string" }, { + "type": "object", + "additionalProperties": false, "patternProperties": { ".+": [ { diff --git a/docs/options.md b/docs/options.md index 8df4e8f25..d3f6c73f7 100644 --- a/docs/options.md +++ b/docs/options.md @@ -898,9 +898,7 @@ Platform-specific environment variables are also available:
CIBW_REPAIR_WHEEL_COMMAND: > python scripts/repair_wheel.py -w {dest_dir} {wheel} && python scripts/check_repaired_wheel.py -w {dest_dir} {wheel} - ``` - ```yaml # Use abi3audit to catch issues with Limited API wheels CIBW_REPAIR_WHEEL_COMMAND_LINUX: > auditwheel repair -w {dest_dir} {wheel} && @@ -934,9 +932,7 @@ Platform-specific environment variables are also available:
'python scripts/repair_wheel.py -w {dest_dir} {wheel}', 'python scripts/check_repaired_wheel.py -w {dest_dir} {wheel}', ] - ``` - ```toml # Use abi3audit to catch issues with Limited API wheels [tool.cibuildwheel.linux] repair-wheel-command = [ diff --git a/unit_test/validate_schema_test.py b/unit_test/validate_schema_test.py index 2b75922d5..742049346 100644 --- a/unit_test/validate_schema_test.py +++ b/unit_test/validate_schema_test.py @@ -1,3 +1,6 @@ +from __future__ import annotations + +import re from pathlib import Path import pytest @@ -54,3 +57,47 @@ def test_overrides_no_select(): validator = validate_pyproject.api.Validator() with pytest.raises(validate_pyproject.error_reporting.ValidationError): validator(example) + + +def test_docs_examples(): + """ + Parse out all the configuration examples, build valid TOML out of them, and + make sure they pass. + """ + + expr = re.compile( + r""" +!!! tab examples "pyproject.toml" +\s* +\s*```toml +(.*?)```""", + re.MULTILINE | re.DOTALL, + ) + + txt = DIR.parent.joinpath("docs/options.md").read_text() + + blocks: list[str] = [] + for match in expr.finditer(txt): + lines = (line.strip() for line in match.group(1).strip().splitlines() if line.strip()) + block: list[str] = [] + header = "" + for line in lines: + if line.startswith(("[tool.cibuildwheel", "[[tool.cibuildwheel")): + header = line + elif line.startswith("#"): + if block: + blocks.append("\n".join([header, *block])) + block = [] + elif " = " in line and any(x.startswith(line.partition(" = ")[0]) for x in block): + blocks.append("\n".join([header, *block])) + block = [line] + else: + block.append(line) + blocks.append("\n".join([header, *block])) + + for example_txt in blocks: + print(example_txt) + print() + example = tomllib.loads(example_txt) + validator = validate_pyproject.api.Validator() + assert validator(example) is not None