Beispiel #1
0
    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)
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #9
0
    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
Beispiel #10
0
    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