def descend_instance(self, walk, schema, base, head, meta): one_of = schema.get("oneOf") if one_of.is_undef(): return None valid = [] def is_valid(v, schema): if v.is_undef(): return True else: return not list( walk.merger.validator.iter_errors(v.val, schema)) for i, subschema in enumerate(one_of.val): base_valid = is_valid(base, subschema) head_valid = is_valid(head, subschema) if base_valid and head_valid: valid.append(i) if len(valid) == 0: raise HeadInstanceError( "No element of 'oneOf' validates both base and head") if len(valid) > 1: raise HeadInstanceError("Multiple elements of 'oneOf' validate") i = valid[0] return walk.descend(one_of[i], base, head, meta)
def merge(self, walk, base, head, schema, meta, idRef="id", ignoreId=None, **kwargs): if not walk.is_type(head, "array"): raise HeadInstanceError("Head for an 'arrayMergeById' merge strategy is not an array", head) # nopep8 if base.is_undef(): base = JSONValue([], base.ref) else: if not walk.is_type(base, "array"): raise BaseInstanceError("Base for an 'arrayMergeById' merge strategy is not an array", base) # nopep8 base = JSONValue(list(base.val), base.ref) subschema = schema.get('items') if walk.is_type(subschema, "array"): raise SchemaError("'arrayMergeById' not supported when 'items' is an array", subschema) def iter_index_key_item(jv): for i, item in enumerate(jv): try: key = walk.resolver.resolve_fragment(item.val, idRef) except jsonschema.RefResolutionError: continue yield i, key, item for i, key_1, item_1 in iter_index_key_item(head): for j, key_2, item_2 in iter_index_key_item(head): if j < i: if key_1 == key_2: raise HeadInstanceError("Id '%s' was not unique in head" % (key_1,), item_1) else: break for i, head_key, head_item in iter_index_key_item(head): if head_key == ignoreId: continue matching_j = [] for j, base_key, base_item in iter_index_key_item(base): if base_key == head_key: matching_j.append(j) matched_item = base_item if len(matching_j) == 1: # If there was exactly one match, we replace it with a merged item j = matching_j[0] base[j] = walk.descend(subschema, matched_item, head_item, meta) elif len(matching_j) == 0: # If there wasn't a match, we append a new object base.append(walk.descend(subschema, JSONValue(undef=True), head_item, meta)) else: j = matching_j[1] raise BaseInstanceError("Id '%s' was not unique in base" % (base_key,), base[j]) return base
def merge(self, walk, base, head, schema, meta, idRef="id", ignoreId=None, **kwargs): if not walk.is_type(head, "array"): raise HeadInstanceError("Head for an 'arrayMergeById' merge strategy is not an array") # nopep8 if base.is_undef(): base = JSONValue([], base.ref) else: if not walk.is_type(base, "array"): raise BaseInstanceError("Base for an 'arrayMergeById' merge strategy is not an array") # nopep8 base = JSONValue(list(base.val), base.ref) subschema = schema.get('items') if walk.is_type(subschema, "array"): raise SchemaError("'arrayMergeById' not supported when 'items' is an array") def iter_index_key_item(jv): for i, item in enumerate(jv): try: key = walk.resolver.resolve_fragment(item.val, idRef) except jsonschema.RefResolutionError: continue yield i, key, item for i, key_1, item_1 in iter_index_key_item(head): for j, key_2, item_2 in iter_index_key_item(head): if j < i: if key_1 == key_2: raise HeadInstanceError("Id was not unique") else: break for i, head_key, head_item in iter_index_key_item(head): if head_key == ignoreId: continue key_count = 0 for j, base_key, base_item in iter_index_key_item(base): if base_key == head_key: key_count += 1 # If there was a match, we replace with a merged item base.val[j] = walk.descend(subschema, base_item, head_item, meta).val if key_count == 0: # If there wasn't a match, we append a new object base.val.append(walk.descend(subschema, JSONValue(undef=True), head_item, meta).val) if key_count > 1: raise BaseInstanceError("Id was not unique") return base
def merge(self, walk, base, head, schema, idRef="id", ignoreId=None, **kwargs): if not walk.is_type(head, "array"): raise HeadInstanceError("Head is not an array", head) # nopep8 if base.is_undef(): base = JSONValue([], base.ref) else: if not walk.is_type(base, "array"): raise BaseInstanceError("Base is not an array", base) # nopep8 base = JSONValue(list(base.val), base.ref) subschema = schema.get('items') if walk.is_type(subschema, "array"): raise SchemaError("This strategy is not supported when 'items' is an array", subschema) for i, key_1, item_1 in self.iter_index_key_item(walk, head, idRef): for j, key_2, item_2 in self.iter_index_key_item(walk, head, idRef): if j < i: if key_1 == key_2: raise HeadInstanceError("Id '%s' was not unique in head" % (key_1,), item_1) else: break for i, head_key, head_item in self.iter_index_key_item(walk, head, idRef): if head_key == ignoreId: continue matching_j = [] for j, base_key, base_item in self.iter_index_key_item(walk, base, idRef): if base_key == head_key: matching_j.append(j) matched_item = base_item if len(matching_j) == 1: # If there was exactly one match, we replace it with a merged item j = matching_j[0] base[j] = walk.descend(subschema, matched_item, head_item) elif len(matching_j) == 0: # If there wasn't a match, we append a new object base.append(walk.descend(subschema, JSONValue(undef=True), head_item)) else: j = matching_j[1] raise BaseInstanceError("Id '%s' was not unique in base" % (base_key,), base[j]) return base
def merge(self, walk, base, head, schema, meta, idRef="id", ignoreId=None, **kwargs): if not walk.is_type(head, "array"): raise HeadInstanceError( "Head for an 'arrayMergeById' merge strategy is not an array" ) # nopep8 if base is None: base = [] else: if not walk.is_type(base, "array"): raise BaseInstanceError( "Base for an 'arrayMergeById' merge strategy is not an array" ) # nopep8 base = list(base) subschema = None if schema: subschema = schema.get('items') if walk.is_type(subschema, "array"): raise SchemaError( "'arrayMergeById' not supported when 'items' is an array") for head_item in head: try: head_key = walk.resolver.resolve_fragment(head_item, idRef) except jsonschema.RefResolutionError: # Do nothing if idRef field cannot be found. continue if head_key == ignoreId: continue key_count = 0 for i, base_item in enumerate(base): base_key = walk.resolver.resolve_fragment(base_item, idRef) if base_key == head_key: key_count += 1 # If there was a match, we replace with a merged item base[i] = walk.descend(subschema, base_item, head_item, meta) if key_count == 0: # If there wasn't a match, we append a new object base.append(walk.descend(subschema, None, head_item, meta)) if key_count > 1: raise BaseInstanceError("Id was not unique") return base
def merge(self, walk, base, head, schema, meta, objclass_menu=None, objClass='_default', **kwargs): if not walk.is_type(head, "object"): raise HeadInstanceError( "Head for an 'object' merge strategy is not an object", head) if objclass_menu is None: objclass_menu = {'_default': dict} objcls = objclass_menu.get(objClass) if objcls is None: raise SchemaError("objClass '%s' not recognized" % objClass, schema) if base.is_undef(): base = JSONValue(objcls(), base.ref) else: if not walk.is_type(base, "object"): raise BaseInstanceError( "Base for an 'object' merge strategy is not an object", base) base = JSONValue(objcls(base.val), base.ref) for k, v in head.items(): subschema = JSONValue(undef=True) # get subschema for this element if not schema.is_undef(): p = schema.get('properties') if not p.is_undef(): subschema = p.get(k) if subschema.is_undef(): p = schema.get('patternProperties') if not p.is_undef(): for pattern, s in p.items(): if re.search(pattern, k): subschema = s if subschema.is_undef(): p = schema.get('additionalProperties') # additionalProperties can be boolean in draft 4 if not p.is_undef() and walk.is_type(p, "object"): subschema = p base[k] = walk.descend(subschema, base.get(k), v, meta) return base
def merge(self, walk, base, head, schema, meta, **kwargs): if not walk.is_type(head, "array"): raise HeadInstanceError("Head for an 'append' merge strategy is not an array", head) if base.is_undef(): base = JSONValue([], base.ref) else: if not walk.is_type(base, "array"): raise BaseInstanceError("Base for an 'append' merge strategy is not an array", base) base = JSONValue(list(base.val), base.ref) base.val += head.val return base
def merge(self, walk, base, head, schema, meta, **kwargs): if not walk.is_type(head, "array"): raise HeadInstanceError( "Head for an 'append' merge strategy is not an array") if base is None: base = [] else: if not walk.is_type(base, "array"): raise BaseInstanceError( "Base for an 'append' merge strategy is not an array") base = list(base) base += head return base
def merge(self, walk, base, head, schema, meta, **kwargs): if not walk.is_type(head, "object"): raise HeadInstanceError( "Head for an 'object' merge strategy is not an object") if base is None: base = {} else: if not walk.is_type(base, "object"): raise BaseInstanceError( "Base for an 'object' merge strategy is not an object") base = dict(base) for k, v in head.items(): subschema = None # get subschema for this element if schema is not None: p = schema.get('properties') if p is not None: subschema = p.get(k) if subschema is None: p = schema.get('patternProperties') if p is not None: for pattern, s in p.items(): if re.search(pattern, k): subschema = s if subschema is None: p = schema.get('additionalProperties') if p is not None: subschema = p.get(k) base[k] = walk.descend(subschema, base.get(k), v, meta) return base
def merge(self, walk, base, head, schema, meta, **kwargs): if not walk.is_type(head, "object"): raise HeadInstanceError("Head for an 'object' merge strategy is not an object") if base.is_undef(): base = JSONValue({}, base.ref) else: if not walk.is_type(base, "object"): raise BaseInstanceError("Base for an 'object' merge strategy is not an object") base = JSONValue(dict(base.val), base.ref) for k, v in head.items(): subschema = JSONValue(undef=True) # get subschema for this element if not schema.is_undef(): p = schema.get('properties') if not p.is_undef(): subschema = p.get(k) if subschema.is_undef(): p = schema.get('patternProperties') if not p.is_undef(): for pattern, s in p.items(): if re.search(pattern, k): subschema = s if subschema.is_undef(): p = schema.get('additionalProperties') if not p.is_undef(): subschema = p base.val[k] = walk.descend(subschema, base.get(k), v, meta).val return base