# HG changeset patch # User Houzefa Abbasbhay <houzefa.abba@xcg-consulting.fr> # Date 1676568173 -3600 # Thu Feb 16 18:22:53 2023 +0100 # Branch 13.0 # Node ID da9a0fe039b65f5cfd3d5a5a60eaac2665026a91 # Parent c23bed64ca21f46fe92eb99c5b1c74079f17639f ``jsonschema`` âž” ``fastjsonschema`` diff --git a/NEWS.rst b/NEWS.rst --- a/NEWS.rst +++ b/NEWS.rst @@ -2,9 +2,14 @@ History ******* +13.0.3.2.0 +========== + Export constants from ``.base``. Used by other modules; these exports got removed when I replaced an ``import *`` earlier. +``jsonschema`` âž” ``fastjsonschema``. + 13.0.3.1.0 ========== diff --git a/__manifest__.py b/__manifest__.py --- a/__manifest__.py +++ b/__manifest__.py @@ -21,7 +21,7 @@ { "name": "Converter", "license": "AGPL-3", - "version": "13.0.3.1.0", + "version": "13.0.3.2.0", "category": "Hidden", "author": "XCG Consulting", "website": "https://odoo.consulting/", @@ -29,5 +29,5 @@ "data": [], "installable": True, # These dependencies are in the "requirements" file. - "external_dependencies": {"python": ["jsonschema"]}, + "external_dependencies": {"python": ["fastjsonschema"]}, } diff --git a/model.py b/model.py --- a/model.py +++ b/model.py @@ -34,8 +34,6 @@ ) from .validate import VALIDATION_SKIP, VALIDATION_STRICT, Validator -import jsonschema - _logger = logging.getLogger(__name__) @@ -96,7 +94,7 @@ if self.validation != VALIDATION_SKIP and self._jsonschema is not None: try: self.validator.validate(self._jsonschema, message_data) - except jsonschema.exceptions.ValidationError as exception: + except Exception as exception: _logger.warning("Validation failed", exc_info=1) if self.validation == VALIDATION_STRICT: raise exception diff --git a/requirements b/requirements --- a/requirements +++ b/requirements @@ -1,2 +1,2 @@ # Used by converter module -jsonschema==3.2.0 +fastjsonschema diff --git a/validate.py b/validate.py --- a/validate.py +++ b/validate.py @@ -19,13 +19,12 @@ ############################################################################## import json -import math import os from typing import NoReturn import odoo.addons -import jsonschema +import fastjsonschema VALIDATION_SKIP = "skip" VALIDATION_SOFT = "soft" @@ -47,9 +46,7 @@ self.repository = repository # exemple "https://annonces-legales.fr/xbus/schemas/v1/{}.schema.json" self.default_url_pattern = default_url_pattern - self.schemastore = {} self.validators = {} - self.search_path = "not initialized, please call initialize()" self.initialized = False self.encoding = "UTF-8" @@ -57,57 +54,33 @@ repo_module_basepath = os.path.dirname( getattr(odoo.addons, self.repository_module_name).__file__ ) + + # Read local schema definitions. + schemas = {} schema_search_path = os.path.abspath( os.path.join(repo_module_basepath, self.repository) ) - self.search_path = schema_search_path - - for root, _dirs, files in os.walk(self.search_path): + for root, _dirs, files in os.walk(schema_search_path): for fname in files: fpath = os.path.join(root, fname) if fpath.endswith((".json",)): with open(fpath, "r", encoding=self.encoding) as schema_fd: schema = json.load(schema_fd) if "$id" in schema: - self.schemastore[schema["$id"]] = schema + schemas[schema["$id"]] = schema + + # Prepare validators for each schema. We add an HTTPS handler that + # points back to our schema definition cache built above. + for schema_id, schema in schemas.items(): + self.validators[schema_id] = fastjsonschema.compile( + schema, + handlers={"https": lambda uri: schemas[uri]}, + use_default=False, + ) self.initialized = True - def validate(self, schema_id, doc) -> NoReturn: + def validate(self, schema_id, payload) -> NoReturn: if not self.initialized: raise NotInitialized("please call the initialize() method") - uri = "file://{}/{}.schema.json".format(self.search_path, schema_id) - validator = self.validators.get(uri) - if validator is None: - schema = self.schemastore[ - self.default_url_pattern.format(schema_id) - ] - - resolver = jsonschema.RefResolver(uri, schema, self.schemastore) - - validator = jsonschema.Draft7Validator(schema, resolver=resolver) - self.validators[uri] = validator - - validator.validate(doc) - - -def multiple_of(validator, db, instance, schema): - """Fix rounding which fails when comparing e.g. 66.6 vs 0.01""" - - if not validator.is_type(instance, "number"): - return - - if isinstance(db, float): - quotient = instance / db - failed = not math.isclose(round(quotient), quotient) - else: - failed = instance % db - - if failed: - yield jsonschema.ValidationError( - "%r is not a multiple of %r" % (instance, db) - ) - - -# Fix rounding which fails when comparing e.g. 66.6 vs 0.01 -jsonschema.Draft7Validator.VALIDATORS["multipleOf"] = multiple_of + self.validators[self.default_url_pattern.format(schema_id)](payload)