From 7dde75d805cea1ca76b08f44b90e8c6055db2c56 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 17 Sep 2024 12:53:29 +0200 Subject: [PATCH] osbuild: experimentally switch to fastjsonschema Just a quick draft to see what it would take to move to fastjson schema. --- osbuild/meta.py | 32 +++++++++++++++++--------------- requirements.txt | 2 +- setup.py | 2 +- test/mod/test_meta.py | 8 ++++---- tox.ini | 2 +- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/osbuild/meta.py b/osbuild/meta.py index 99dcee01d..c8c1a1080 100644 --- a/osbuild/meta.py +++ b/osbuild/meta.py @@ -31,7 +31,7 @@ from collections import deque from typing import Any, Deque, Dict, List, Optional, Sequence, Set, Tuple, Union -import jsonschema +import fastjsonschema from .util import osrelease @@ -55,8 +55,8 @@ def __init__(self, message: str): @classmethod def from_exception(cls, ex): - err = cls(ex.message) - err.path = ex.absolute_path + err = cls(str(ex)) + #err.path = ex.absolute_path return err @property @@ -217,9 +217,11 @@ class Schema: """ def __init__(self, schema: Optional[Dict], name: Optional[str] = None): + if schema: + schema["schema"] = "http://json-schema.org/draft-04/schema" self.data = schema self.name = name - self._validator: Optional[jsonschema.Draft4Validator] = None + self._validator: Optional[fastjsonschema.CodeGeneratorDraft04] = None def check(self) -> ValidationResult: """Validate the `schema` data itself""" @@ -243,10 +245,8 @@ def check(self) -> ValidationResult: return res try: - Validator = jsonschema.Draft4Validator - Validator.check_schema(self.data) - self._validator = Validator(self.data) - except jsonschema.exceptions.SchemaError as err: + self._validator = fastjsonschema.compile(self.data) + except fastjsonschema.JsonSchemaDefinitionException as err: res += ValidationError.from_exception(err) return res @@ -266,8 +266,10 @@ def validate(self, target) -> ValidationResult: if not self._validator: raise RuntimeError("Trying to validate without validator.") - for error in self._validator.iter_errors(target): - res += ValidationError.from_exception(error) + try: + self._validator(target) + except fastjsonschema.JsonSchemaException as e: + res += ValidationError.from_exception(e) return res @@ -278,11 +280,11 @@ def __bool__(self): META_JSON_SCHEMA = { "type": "object", "additionalProperties": False, - "propertyNames": { - "not": { - "const": "description", - }, - }, + #"propertyNames": { + # "not": { + # "const": "description", + # }, + #}, "required": ["summary", "description"], "anyOf": [ { diff --git a/requirements.txt b/requirements.txt index 598596ead..1d2528c73 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -jsonschema +fastjsonschema pytest diff --git a/setup.py b/setup.py index 95c474752..b3c22fd78 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ packages=["osbuild", "osbuild.formats", "osbuild.util","osbuild.solver"], license='Apache-2.0', install_requires=[ - "jsonschema", + "fastjsonschema", ], entry_points={ "console_scripts": [ diff --git a/test/mod/test_meta.py b/test/mod/test_meta.py index 419199a6d..20c038bd4 100644 --- a/test/mod/test_meta.py +++ b/test/mod/test_meta.py @@ -323,20 +323,20 @@ def test_load_from_json_prefered(tmp_path): ( # no description {"summary": "some", "schema": {}}, - "'description' is a required property", + "data must contain ['description'] properties", ), ( # no summary {"description": ["yes"], "schema": {}}, - "'summary' is a required property", + "data must contain ['summary'] properties", ), ( # schema{,_2} missing {"summary": "some", "description": ["many", "strings"]}, - " is not valid", + "data cannot be validated by any definition" ), ( # capabilities of wrong type {"summary": "some", "description": ["many", "strings"], "schema": {}, "capabilities": [1, "cap1"]}, - " is not of type 'string'", + " must be string" ), ]) def test_meta_json_validation_schema(test_input, expected_err): diff --git a/tox.ini b/tox.ini index e8ad9922c..0c5927d4c 100644 --- a/tox.ini +++ b/tox.ini @@ -14,7 +14,7 @@ description = "run osbuild unit tests" deps = pytest pytest-xdist - jsonschema + fastjsonschema mako iniparse pyyaml