Skip to content
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
13 changes: 7 additions & 6 deletions fastjsonschema/ref_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def _ensure_walked(self, uri, schema):
normalized = normalize(uri) if uri else ''
if normalized in self._walked_uris:
return
self.walk(schema)
self.walk(schema, rewrite_refs=False)
self._walked_uris.add(normalized)

def get_uri(self):
Expand All @@ -178,7 +178,7 @@ def get_scope_name(self):
name = name.lower().rstrip('_')
return name

def walk(self, node: dict, depth=0):
def walk(self, node: dict, depth=0, rewrite_refs=True):
"""
Walk thru schema and dereferencing ``id`` and ``$ref`` instances
"""
Expand All @@ -190,15 +190,16 @@ def walk(self, node: dict, depth=0):
if isinstance(node, bool):
pass
elif '$ref' in node and isinstance(node['$ref'], str):
ref = node['$ref']
node['$ref'] = urlparse.urljoin(self.resolution_scope, ref)
if rewrite_refs:
ref = node['$ref']
node['$ref'] = urlparse.urljoin(self.resolution_scope, ref)
elif ('$id' in node or 'id' in node) and isinstance(get_id(node), str):
with self.in_scope(get_id(node)):
self.store[normalize(self.resolution_scope)] = node
for _, item in node.items():
if isinstance(item, dict):
self.walk(item, depth + 1)
self.walk(item, depth + 1, rewrite_refs)
else:
for _, item in node.items():
if isinstance(item, dict):
self.walk(item, depth + 1)
self.walk(item, depth + 1, rewrite_refs)
21 changes: 21 additions & 0 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,24 @@ def test_swap_handlers():
}
validator2 = compile({"$ref": "sch://schema"}, handlers={"sch": repo2.__getitem__})
assert validator2("hello world") is not None


def test_relative_ref_in_remote_schema_is_resolved_once():
repo = {
'schemas/main.json': {
'definitions': {
'object': {
'type': 'object',
'properties': {'value': {'$ref': 'main.json#/definitions/string'}},
},
'string': {'type': 'string'},
},
},
}

validator = compile(
{'$ref': 'schemas/main.json#/definitions/object'},
handlers={'': repo.__getitem__},
)

assert validator({'value': 'ok'}) == {'value': 'ok'}
Loading