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", 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) 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, 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, 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 test_append_undef(self): v = JSONValue([]) v.append(JSONValue(undef=True)) self.assertEqual([], v.val)