|
8 | 8 |
|
9 | 9 | import pkg_resources |
10 | 10 | import yaml |
11 | | -from jsonschema import Draft7Validator, RefResolver |
| 11 | +from jsonschema import Draft7Validator |
12 | 12 | from jsonschema.exceptions import RefResolutionError, ValidationError |
| 13 | +import referencing |
| 14 | +import referencing.exceptions |
13 | 15 | from nested_lookup import nested_lookup |
14 | 16 |
|
15 | 17 | from .exceptions import InternalError, SpecValidationError |
@@ -56,30 +58,42 @@ def copy_resource(package_name, resource_name, out_path): |
56 | 58 | shutil.copyfileobj(fsrc, fdst) |
57 | 59 |
|
58 | 60 |
|
59 | | -def get_schema_store(schema_search_path): |
60 | | - """Load all the schemas in schema_search_path and return a dict""" |
61 | | - schema_store = {} |
| 61 | +def get_schema_registry(schema_search_path): |
| 62 | + """Load all the schemas in schema_search_path and return a registry""" |
| 63 | + schemas = {} |
62 | 64 | schema_fnames = os.listdir(schema_search_path) |
63 | 65 | for schema_fname in schema_fnames: |
64 | 66 | schema_path = os.path.join(schema_search_path, schema_fname) |
65 | 67 | if schema_path.endswith(".json"): |
66 | 68 | with open(schema_path, "r", encoding="utf-8") as schema_f: |
67 | 69 | schema = json.load(schema_f) |
68 | 70 | if "$id" in schema: |
69 | | - schema_store[schema["$id"]] = schema |
70 | | - return schema_store |
| 71 | + schemas[schema["$id"]] = schema |
| 72 | + |
| 73 | + # Add HTTPS version of JSON Schema for compatibility |
| 74 | + if "http://json-schema.org/draft-07/schema#" in schemas: |
| 75 | + schemas["https://json-schema.org/draft-07/schema#"] = schemas["http://json-schema.org/draft-07/schema#"] |
| 76 | + |
| 77 | + # Create resources with proper specification |
| 78 | + resources = [] |
| 79 | + for uri, schema in schemas.items(): |
| 80 | + try: |
| 81 | + resource = referencing.Resource.from_contents(schema) |
| 82 | + resources.append((uri, resource)) |
| 83 | + except Exception: |
| 84 | + # Fallback for schemas without proper $schema |
| 85 | + resource = referencing.Resource.from_contents(schema, default_specification=referencing.jsonschema.DRAFT7) |
| 86 | + resources.append((uri, resource)) |
| 87 | + |
| 88 | + return referencing.Registry().with_resources(resources) |
71 | 89 |
|
72 | 90 |
|
73 | 91 | def make_validator(schema): |
74 | 92 | schema_search_path = Path(os.path.dirname(os.path.realpath(__file__))).joinpath( |
75 | 93 | "data/schema/" |
76 | 94 | ) |
77 | | - resolver = RefResolver( |
78 | | - base_uri=Draft7Validator.ID_OF(schema), |
79 | | - store=get_schema_store(schema_search_path), |
80 | | - referrer=schema, |
81 | | - ) |
82 | | - return Draft7Validator(schema, resolver=resolver) |
| 95 | + registry = get_schema_registry(schema_search_path) |
| 96 | + return Draft7Validator(schema, registry=registry) |
83 | 97 |
|
84 | 98 |
|
85 | 99 | def make_resource_validator(): |
@@ -379,7 +393,7 @@ def load_resource_spec(resource_spec_file): # pylint: disable=R # noqa: C901 |
379 | 393 | inliner = RefInliner(base_uri, resource_spec) |
380 | 394 | try: |
381 | 395 | inlined = inliner.inline() |
382 | | - except RefResolutionError as e: |
| 396 | + except (RefResolutionError, referencing.exceptions.Unresolvable) as e: |
383 | 397 | LOG.debug("Resource spec validation failed", exc_info=True) |
384 | 398 | raise SpecValidationError(str(e)) from e |
385 | 399 |
|
@@ -444,7 +458,7 @@ def load_hook_spec(hook_spec_file): # pylint: disable=R # noqa: C901 |
444 | 458 | inliner = RefInliner(base_uri, hook_spec) |
445 | 459 | try: |
446 | 460 | inlined = inliner.inline() |
447 | | - except RefResolutionError as e: |
| 461 | + except (RefResolutionError, referencing.exceptions.Unresolvable) as e: |
448 | 462 | LOG.debug("Hook spec validation failed", exc_info=True) |
449 | 463 | raise SpecValidationError(str(e)) from e |
450 | 464 |
|
|
0 commit comments