Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to jsonschema 4.18.0 #123

Closed
wants to merge 6 commits into from
Closed
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
65 changes: 28 additions & 37 deletions libcove/lib/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
import jsonref
import jsonschema.validators
import requests
from referencing import Registry, Resource

try:
from functools import cached_property
except ImportError:
from cached_property import cached_property

from flattentool import unflatten
from jsonschema import FormatChecker, RefResolver
from jsonschema import FormatChecker
from jsonschema._utils import extras_msg, find_additional_properties, uniq
from jsonschema.exceptions import UndefinedTypeCheck, ValidationError

Expand Down Expand Up @@ -822,25 +823,30 @@ def get_schema_validation_errors(
if hasattr(schema_obj, "validator"):
our_validator = schema_obj.validator(validator, format_checker)
else:
if getattr(schema_obj, "extended", None):
resolver = CustomRefResolver(
"",
pkg_schema_obj,
config=getattr(schema_obj, "config", None),
schema_url=schema_obj.schema_host,
schema_file=schema_obj.extended_schema_file,
file_schema_name=schema_obj.schema_name,
)
if hasattr(schema_obj, "registry"):
registry = schema_obj.registry
else:
resolver = CustomRefResolver(
"",
pkg_schema_obj,
config=getattr(schema_obj, "config", None),
schema_url=schema_obj.schema_host,
)
if getattr(schema_obj, "extended", None):
resolver = CustomRefResolver(
"",
pkg_schema_obj,
config=getattr(schema_obj, "config", None),
schema_url=schema_obj.schema_host,
schema_file=schema_obj.extended_schema_file,
file_schema_name=schema_obj.schema_name,
)
else:
resolver = CustomRefResolver(
"",
pkg_schema_obj,
config=getattr(schema_obj, "config", None),
schema_url=schema_obj.schema_host,
)

registry = Registry(retrieve=resolver.retrieve)

our_validator = validator(
pkg_schema_obj, format_checker=format_checker, resolver=resolver
pkg_schema_obj, format_checker=format_checker, registry=registry
)

for e in our_validator.iter_errors(json_data):
Expand Down Expand Up @@ -1165,7 +1171,7 @@ def get_fields_present(*args, **kwargs):
}


class CustomRefResolver(RefResolver):
class CustomRefResolver:
"""This RefResolver is only for use with the jsonschema library"""

def __init__(self, *args, **kw):
Expand All @@ -1178,44 +1184,29 @@ def __init__(self, *args, **kw):
# this is ignored when you supply a file
self.schema_url = kw.pop("schema_url", "")
self.config = kw.pop("config", "")
super().__init__(*args, **kw)

def resolve_remote(self, uri):
def retrieve(self, uri):
schema_name = uri.split("/")[-1]
if self.schema_file and self.file_schema_name == schema_name:
uri = self.schema_file
else:
uri = urljoin(self.schema_url, schema_name)

document = self.store.get(uri)

if document:
return document
if uri.startswith("http"):
# This branch of the if-statement in-lines `RefResolver.resolve_remote()`, but using `get_request()`.
# https://github.com/python-jsonschema/jsonschema/blob/dbc398245a583cb2366795dc529ae042d10c1577/jsonschema/validators.py#L1008-L1023
scheme = urlsplit(uri).scheme

if scheme in self.handlers:
result = self.handlers[scheme](uri)
elif scheme in ["http", "https"]:
# Requests has support for detecting the correct encoding of
# json over http
if scheme in ("http", "https"):
result = get_request(uri, config=self.config).json()
else:
# Otherwise, pass off to urllib and assume utf-8
with urlopen(uri) as url:
result = json.loads(url.read().decode("utf-8"))

if self.cache_remote:
self.store[uri] = result
return result
else:
with open(uri) as schema_file:
result = json.load(schema_file)

add_is_codelist(result)
self.store[uri] = result
return result
return Resource.from_contents(result)


def _get_schema_deprecated_paths(
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
long_description="A data review library",
install_requires=[
"jsonref",
"jsonschema>=4",
"jsonschema>=4.18",
"referencing",
"requests",
"cached-property;python_version<'3.8'",
"flattentool>=0.11.0",
Expand Down
11 changes: 4 additions & 7 deletions tests/lib/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import jsonschema
import pytest
from freezegun import freeze_time
from referencing.exceptions import CannotDetermineSpecification

from libcove.lib.common import (
SchemaJsonMixin,
Expand Down Expand Up @@ -766,7 +767,7 @@ def get_pkg_schema_obj(self):
assert "[Decimal('3.1')] is too short" in validation_error_json


def test_property_that_is_not_json_schema_doesnt_raise_exception(caplog, tmpdir):
def test_property_that_is_not_json_schema_doesnt_raise_exception(tmpdir):
tmpdir.join("test.json").write(
json.dumps({"properties": {"bad_property": "not_a_json_schema"}})
)
Expand All @@ -778,12 +779,8 @@ class DummySchemaObj:
def get_pkg_schema_obj(self):
return {"$ref": "test.json"}

validation_errors = get_schema_validation_errors({}, DummySchemaObj(), "", {}, {})
assert validation_errors == {}
assert (
"A 'properties' object contains a 'bad_property' value that is not a JSON Schema: 'not_a_json_schema'"
in caplog.text
)
with pytest.raises(CannotDetermineSpecification):
get_schema_validation_errors({}, DummySchemaObj(), "", {}, {})


@pytest.mark.parametrize(
Expand Down
Loading