Skip to content

Refactor RefResolver a bit to fix #102 #103

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

Merged
Merged
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
11 changes: 6 additions & 5 deletions jsonschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,7 @@ def __init__(
):
self.base_uri = base_uri
self.resolution_scope = base_uri
# This attribute is not used, it is for backwards compatibility
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt anyone is using this attribute, but just in case, maybe leave it anyhow to not break any backwards compat.

self.referrer = referrer
self.cache_remote = cache_remote
self.handlers = dict(handlers)
Expand All @@ -1123,6 +1124,7 @@ def __init__(
for id, validator in iteritems(meta_schemas)
)
self.store.update(store)
self.store[base_uri] = referrer

@classmethod
def from_schema(cls, schema, *args, **kwargs):
Expand Down Expand Up @@ -1157,24 +1159,23 @@ def resolving(self, ref):

full_uri = urlparse.urljoin(self.resolution_scope, ref)
uri, fragment = urlparse.urldefrag(full_uri)
if not uri:
uri = self.base_uri

if uri in self.store:
document = self.store[uri]
elif not uri or uri == self.base_uri:
document = self.referrer
else:
try:
document = self.resolve_remote(uri)
except Exception as exc:
raise RefResolutionError(exc)

old_base_uri, old_referrer = self.base_uri, self.referrer
self.base_uri, self.referrer = uri, document
old_base_uri, self.base_uri = self.base_uri, uri
try:
with self.in_scope(uri):
yield self.resolve_fragment(document, fragment)
finally:
self.base_uri, self.referrer = old_base_uri, old_referrer
self.base_uri = old_base_uri

def resolve_fragment(self, document, fragment):
"""
Expand Down
22 changes: 20 additions & 2 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,14 @@ def test_it_resolves_local_refs(self):
with self.resolver.resolving(ref) as resolved:
self.assertEqual(resolved, self.referrer["properties"]["foo"])

def test_it_resolves_local_refs_with_id(self):
schema = {"id": "/bar/schema#", "a": {"foo": "bar"}}
resolver = RefResolver.from_schema(schema)
with resolver.resolving("#/a") as resolved:
self.assertEqual(resolved, schema["a"])
with resolver.resolving("/bar/schema#/a") as resolved:
self.assertEqual(resolved, schema["a"])

def test_it_retrieves_stored_refs(self):
with self.resolver.resolving(self.stored_uri) as resolved:
self.assertIs(resolved, self.stored_schema)
Expand Down Expand Up @@ -893,13 +901,23 @@ def test_it_can_construct_a_base_uri_from_a_schema(self):
schema = {"id" : "foo"}
resolver = RefResolver.from_schema(schema)
self.assertEqual(resolver.base_uri, "foo")
self.assertEqual(resolver.referrer, schema)
with resolver.resolving("") as resolved:
self.assertEqual(resolved, schema)
with resolver.resolving("#") as resolved:
self.assertEqual(resolved, schema)
with resolver.resolving("foo") as resolved:
self.assertEqual(resolved, schema)
with resolver.resolving("foo#") as resolved:
self.assertEqual(resolved, schema)

def test_it_can_construct_a_base_uri_from_a_schema_without_id(self):
schema = {}
resolver = RefResolver.from_schema(schema)
self.assertEqual(resolver.base_uri, "")
self.assertEqual(resolver.referrer, schema)
with resolver.resolving("") as resolved:
self.assertEqual(resolved, schema)
with resolver.resolving("#") as resolved:
self.assertEqual(resolved, schema)

def test_custom_uri_scheme_handlers(self):
schema = {"foo": "bar"}
Expand Down