Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/json-schema-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

PCS Draft 2020-12 schemas declare `"format"` keywords. In Python, `Draft202012Validator`
is constructed with `jsonschema.FormatChecker` so those formats are **assertions**, not
annotations.
annotations. The Python package depends on `jsonschema[format-nongpl]` so checkers for
`date-time`, `uri`, `duration`, and `hostname` are registered at import time (bare
`jsonschema` omits them and raises on asserted-format construction).

## Asserted formats

Expand Down
22 changes: 21 additions & 1 deletion python/pcs_core/validate_detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,27 @@
}
)

_FORMAT_CHECKER = FormatChecker(formats=sorted(ASSERTED_FORMATS))

def _build_asserted_format_checker() -> FormatChecker:
"""Build a FormatChecker limited to ASSERTED_FORMATS.

jsonschema only registers optional formats (date-time, uri, …) when the
corresponding format extras are installed. Constructing FormatChecker with
unknown names raises KeyError; fail with an actionable message instead.
"""
available = FormatChecker.checkers
missing = sorted(fmt for fmt in ASSERTED_FORMATS if fmt not in available)
if missing:
raise RuntimeError(
"jsonschema format checkers unavailable for: "
+ ", ".join(missing)
+ ". Install pcs-core dependencies including "
"jsonschema[format-nongpl] (see python/pyproject.toml)."
)
return FormatChecker(formats=sorted(ASSERTED_FORMATS))


_FORMAT_CHECKER = _build_asserted_format_checker()


class DetectionMode(str, Enum):
Expand Down
5 changes: 3 additions & 2 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ readme = "../README.md"
license = { text = "Apache-2.0" }
requires-python = ">=3.11"
dependencies = [
"jsonschema>=4.23.0",
# format-nongpl registers date-time/uri/duration/hostname checkers used as assertions
"jsonschema[format-nongpl]>=4.23.0",
"referencing>=0.35.0,<0.37.0",
]

Expand All @@ -27,7 +28,7 @@ quality = [
# Verifier extras document the Lean/OCI path; Lean assets ship via the
# verifier OCI image or a PCS_BUILD_VERIFIER=1 wheel (see docs/distribution.md).
verifier = [
"jsonschema>=4.23.0",
"jsonschema[format-nongpl]>=4.23.0",
"referencing>=0.35.0,<0.37.0",
]

Expand Down
13 changes: 13 additions & 0 deletions python/requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ jsonschema-specifications==2025.9.1
referencing==0.36.2
rpds-py==0.30.0

# jsonschema[format-nongpl] — required so FormatChecker registers asserted formats
arrow==1.3.0
fqdn==1.5.1
idna==3.10
isoduration==20.11.0
jsonpointer==3.0.0
python-dateutil==2.9.0.post0
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rfc3987-syntax==1.1.0
uri-template==1.3.0
webcolors==24.11.1

# Optional-dev (CI)
pytest==8.3.5
ruff==0.15.9
Expand Down
Loading