|
7 | 7 | from pathlib import Path |
8 | 8 |
|
9 | 9 | import pkg_resources |
| 10 | +import referencing |
| 11 | +import referencing.exceptions |
10 | 12 | import yaml |
11 | | -from jsonschema import Draft7Validator, RefResolver |
12 | | -from jsonschema.exceptions import RefResolutionError, ValidationError |
| 13 | +from jsonschema import Draft7Validator |
| 14 | +from jsonschema.exceptions import ( # pylint: disable=no-name-in-module |
| 15 | + RefResolutionError, |
| 16 | + ValidationError, |
| 17 | +) |
13 | 18 | from nested_lookup import nested_lookup |
14 | 19 |
|
15 | 20 | from .exceptions import InternalError, SpecValidationError |
@@ -56,30 +61,52 @@ def copy_resource(package_name, resource_name, out_path): |
56 | 61 | shutil.copyfileobj(fsrc, fdst) |
57 | 62 |
|
58 | 63 |
|
59 | | -def get_schema_store(schema_search_path): |
60 | | - """Load all the schemas in schema_search_path and return a dict""" |
61 | | - schema_store = {} |
| 64 | +def get_schema_registry(schema_search_path): |
| 65 | + """Load all the schemas in schema_search_path and return a registry""" |
| 66 | + schemas = {} |
62 | 67 | schema_fnames = os.listdir(schema_search_path) |
63 | 68 | for schema_fname in schema_fnames: |
64 | 69 | schema_path = os.path.join(schema_search_path, schema_fname) |
65 | 70 | if schema_path.endswith(".json"): |
66 | 71 | with open(schema_path, "r", encoding="utf-8") as schema_f: |
67 | 72 | schema = json.load(schema_f) |
68 | 73 | if "$id" in schema: |
69 | | - schema_store[schema["$id"]] = schema |
70 | | - return schema_store |
| 74 | + schemas[schema["$id"]] = schema |
| 75 | + |
| 76 | + # Add HTTPS version of JSON Schema for compatibility |
| 77 | + if "http://json-schema.org/draft-07/schema#" in schemas: |
| 78 | + schemas["https://json-schema.org/draft-07/schema#"] = schemas[ |
| 79 | + "http://json-schema.org/draft-07/schema#" |
| 80 | + ] |
| 81 | + |
| 82 | + # Create resources with proper specification |
| 83 | + resources = [] |
| 84 | + for uri, schema in schemas.items(): |
| 85 | + try: |
| 86 | + resource = referencing.Resource.from_contents( |
| 87 | + schema, default_specification=referencing.jsonschema.DRAFT7 |
| 88 | + ) |
| 89 | + resources.append((uri, resource)) |
| 90 | + except ( |
| 91 | + ValueError, |
| 92 | + TypeError, |
| 93 | + KeyError, |
| 94 | + ): # pylint: disable=broad-exception-caught |
| 95 | + # Fallback for schemas without proper $schema |
| 96 | + resource = referencing.Resource.from_contents( |
| 97 | + schema, default_specification=referencing.jsonschema.DRAFT7 |
| 98 | + ) |
| 99 | + resources.append((uri, resource)) |
| 100 | + |
| 101 | + return referencing.Registry().with_resources(resources) |
71 | 102 |
|
72 | 103 |
|
73 | 104 | def make_validator(schema): |
74 | 105 | schema_search_path = Path(os.path.dirname(os.path.realpath(__file__))).joinpath( |
75 | 106 | "data/schema/" |
76 | 107 | ) |
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) |
| 108 | + registry = get_schema_registry(schema_search_path) |
| 109 | + return Draft7Validator(schema, registry=registry) |
83 | 110 |
|
84 | 111 |
|
85 | 112 | def make_resource_validator(): |
@@ -379,7 +406,7 @@ def load_resource_spec(resource_spec_file): # pylint: disable=R # noqa: C901 |
379 | 406 | inliner = RefInliner(base_uri, resource_spec) |
380 | 407 | try: |
381 | 408 | inlined = inliner.inline() |
382 | | - except RefResolutionError as e: |
| 409 | + except (RefResolutionError, referencing.exceptions.Unresolvable) as e: |
383 | 410 | LOG.debug("Resource spec validation failed", exc_info=True) |
384 | 411 | raise SpecValidationError(str(e)) from e |
385 | 412 |
|
@@ -444,7 +471,7 @@ def load_hook_spec(hook_spec_file): # pylint: disable=R # noqa: C901 |
444 | 471 | inliner = RefInliner(base_uri, hook_spec) |
445 | 472 | try: |
446 | 473 | inlined = inliner.inline() |
447 | | - except RefResolutionError as e: |
| 474 | + except (RefResolutionError, referencing.exceptions.Unresolvable) as e: |
448 | 475 | LOG.debug("Hook spec validation failed", exc_info=True) |
449 | 476 | raise SpecValidationError(str(e)) from e |
450 | 477 |
|
|
0 commit comments