Skip to content

Commit 33ef215

Browse files
author
Peter Amstutz
committed
Refactor resolve_all into smaller methods.
1 parent da10eec commit 33ef215

File tree

2 files changed

+76
-56
lines changed

2 files changed

+76
-56
lines changed

schema_salad/ref_resolver.py

+76-55
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,77 @@ def resolve_ref(self, ref, base_url=None):
318318
except TypeError:
319319
return obj, metadata
320320

321+
def _resolve_idmap(self, document, loader):
322+
# Convert fields with mapSubject into lists
323+
# use mapPredicate if the mapped value isn't a dict.
324+
for idmapField in loader.idmap:
325+
if (idmapField in document and isinstance(document[idmapField], dict) and
326+
"$import" not in document[idmapField] and
327+
"$include" not in document[idmapField]):
328+
ls = []
329+
for k, v in document[idmapField].items():
330+
if not isinstance(v, dict):
331+
if idmapField in loader.mapPredicate:
332+
v = {loader.mapPredicate[idmapField]: v}
333+
else:
334+
raise validate.ValidationException(
335+
"mapSubject '%s' value '%s' is not a dict and does not have a mapPredicate", k, v)
336+
v[loader.idmap[idmapField]] = k
337+
ls.append(v)
338+
document[idmapField] = ls
339+
340+
def _resolve_identifier(self, document, loader, base_url):
341+
# Expand identifier field (usually 'id') to resolve scope
342+
for identifer in loader.identifiers:
343+
if identifer in document:
344+
if isinstance(document[identifer], basestring):
345+
document[identifer] = loader.expand_url(
346+
document[identifer], base_url, scoped=True)
347+
if document[identifer] not in loader.idx or isinstance(loader.idx[document[identifer]], basestring):
348+
loader.idx[document[identifer]] = document
349+
base_url = document[identifer]
350+
else:
351+
raise validate.ValidationException(
352+
"identifier field '%s' must be a string" % (document[identifer]))
353+
return base_url
354+
355+
def _resolve_identity(self, document, loader, base_url):
356+
# Resolve scope for identity fields (fields where the value is the
357+
# identity of a standalone node, such as enum symbols)
358+
for identifer in loader.identity_links:
359+
if identifer in document and isinstance(document[identifer], list):
360+
for n, v in enumerate(document[identifer]):
361+
if isinstance(document[identifer][n], basestring):
362+
document[identifer][n] = loader.expand_url(
363+
document[identifer][n], base_url, scoped=True)
364+
if document[identifer][n] not in loader.idx:
365+
loader.idx[document[identifer][
366+
n]] = document[identifer][n]
367+
368+
def _normalize_fields(self, document, loader):
369+
# Normalize fields which are prefixed or full URIn to vocabulary terms
370+
for d in document:
371+
d2 = loader.expand_url(d, "", scoped=False, vocab_term=True)
372+
if d != d2:
373+
document[d2] = document[d]
374+
del document[d]
375+
376+
def _resolve_uris(self, document, loader, base_url):
377+
# Resolve remaining URLs based on document base
378+
for d in loader.url_fields:
379+
if d in document:
380+
if isinstance(document[d], basestring):
381+
document[d] = loader.expand_url(
382+
document[d], base_url, scoped=False, vocab_term=(d in loader.vocab_fields))
383+
elif isinstance(document[d], list):
384+
document[d] = [
385+
loader.expand_url(
386+
url, base_url, scoped=False,
387+
vocab_term=(d in loader.vocab_fields))
388+
if isinstance(url, (str, unicode))
389+
else url for url in document[d]]
390+
391+
321392
def resolve_all(self, document, base_url, file_base=None):
322393
# type: (Any, Union[str, unicode], Union[str, unicode]) -> Tuple[Any, Dict[str, Any]]
323394
loader = self
@@ -367,62 +438,12 @@ def resolve_all(self, document, base_url, file_base=None):
367438
metadata, _ = loader.resolve_all(metadata, base_url, file_base)
368439

369440
if isinstance(document, dict):
370-
for idmapField in loader.idmap:
371-
if (idmapField in document and isinstance(document[idmapField], dict) and
372-
"$import" not in document[idmapField] and
373-
"$include" not in document[idmapField]):
374-
ls = []
375-
for k, v in document[idmapField].items():
376-
if not isinstance(v, dict):
377-
if idmapField in loader.mapPredicate:
378-
v = {loader.mapPredicate[idmapField]: v}
379-
else:
380-
raise validate.ValidationException(
381-
"mapSubject '%s' value '%s' is not a dict and does not have a mapPredicate", k, v)
382-
v[loader.idmap[idmapField]] = k
383-
ls.append(v)
384-
document[idmapField] = ls
385-
386-
for identifer in loader.identifiers:
387-
if identifer in document:
388-
if isinstance(document[identifer], basestring):
389-
document[identifer] = loader.expand_url(
390-
document[identifer], base_url, scoped=True)
391-
if document[identifer] not in loader.idx or isinstance(loader.idx[document[identifer]], basestring):
392-
loader.idx[document[identifer]] = document
393-
base_url = document[identifer]
394-
else:
395-
raise validate.ValidationException(
396-
"identifier field '%s' must be a string" % (document[identifer]))
397441

398-
for identifer in loader.identity_links:
399-
if identifer in document and isinstance(document[identifer], list):
400-
for n, v in enumerate(document[identifer]):
401-
if isinstance(document[identifer][n], basestring):
402-
document[identifer][n] = loader.expand_url(
403-
document[identifer][n], base_url, scoped=True)
404-
if document[identifer][n] not in loader.idx:
405-
loader.idx[document[identifer][
406-
n]] = document[identifer][n]
407-
408-
for d in document:
409-
d2 = loader.expand_url(d, "", scoped=False, vocab_term=True)
410-
if d != d2:
411-
document[d2] = document[d]
412-
del document[d]
413-
414-
for d in loader.url_fields:
415-
if d in document:
416-
if isinstance(document[d], basestring):
417-
document[d] = loader.expand_url(
418-
document[d], base_url, scoped=False, vocab_term=(d in loader.vocab_fields))
419-
elif isinstance(document[d], list):
420-
document[d] = [
421-
loader.expand_url(
422-
url, base_url, scoped=False,
423-
vocab_term=(d in loader.vocab_fields))
424-
if isinstance(url, (str, unicode))
425-
else url for url in document[d]]
442+
self._resolve_idmap(document, loader)
443+
base_url = self._resolve_identifier(document, loader, base_url)
444+
self._resolve_identity(document, loader, base_url)
445+
self._normalize_fields(document, loader)
446+
self._resolve_uris(document, loader, base_url)
426447

427448
try:
428449
for key, val in document.items():

schema_salad/schema.py

-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ def load_and_validate(document_loader, avsc_names, document, strict):
190190
else:
191191
data, metadata = document_loader.resolve_ref(document)
192192

193-
document_loader.validate_links(data)
194193
validate_doc(avsc_names, data, document_loader, strict)
195194
return data, metadata
196195

0 commit comments

Comments
 (0)