Exemplo n.º 1
0
    def traverser(self, data, schema, tree):
        """
        Traverses the dictionary, recursing onto itself if
        it sees appropriate key/value pairs that indicate that
        there is a need for more validation in a branch below us.
        """

        if hasattr(schema, '__validator_leaf__'):
            return schema(data, tree)

        if hasattr(schema, 'must_validate'):  # cherry picking?
            if not len(schema.must_validate):
                reason = "must_validate attribute must not be empty"
                raise SchemaError(data, tree, reason=reason)
            data = sift(data, schema.must_validate)

        schema = self.sanitize_optionals(data, schema, tree)

        for index in range(len(data)):
            self.length_equality(data, schema, index, tree)
            key, value = data[index]
            skey, svalue = schema[index]
            tree.append(key)

            # Validate the key before anything, to prevent recursing
            self.key_leaf(data[index], schema[index], tree)

            # If a dict is a value we need to recurse.
            # XXX Should we check isinstance(value, ndict) ?
            if isinstance(value, dict) and len(value):
                self.traverser(value, svalue, tree)
            else:
                self.value_leaf(data[index], schema[index], tree)
            if tree:
                tree.pop()
Exemplo n.º 2
0
    def traverser(self, data, schema, tree):
        """
        Traverses the dictionary, recursing onto itself if
        it sees appropriate key/value pairs that indicate that
        there is a need for more validation in a branch below us.
        """

        if hasattr(schema, '__validator_leaf__'):
            return schema(data, tree)

        if hasattr(schema, 'must_validate'):  # cherry picking?
            if not len(schema.must_validate):
                reason = "must_validate attribute must not be empty"
                raise SchemaError(data, tree, reason=reason)
            data = sift(data, schema.must_validate)

        schema = self.sanitize_optionals(data, schema, tree)

        for index in range(len(data)):
            self.length_equality(data, schema, index, tree)
            key, value = data[index]
            skey, svalue = schema[index]
            tree.append(key)

            # Validate the key before anything, to prevent recursing
            self.key_leaf(data[index], schema[index], tree)

            # If a dict is a value we need to recurse.
            # XXX Should we check isinstance(value, ndict) ?
            if isinstance(value, dict) and len(value):
                self.traverser(value, svalue, tree)
            else:
                self.value_leaf(data[index], schema[index], tree)
            if tree:
                tree.pop()
Exemplo n.º 3
0
    def traverser(self, data, schema, tree):
        """
        Traverses the dictionary, recursing onto itself if
        it sees appropriate key/value pairs that indicate that
        there is a need for more validation in a branch below us.
        """
        if hasattr(schema, '__validator_leaf__'):
            return schema(data, tree)

        if hasattr(schema, 'must_validate'):  # cherry picking?
            if not len(schema.must_validate):
                reason = "must_validate attribute must not be empty"
                raise SchemaError(data, tree, reason=reason)
            data = sift(data, schema.must_validate)

        schema = self.sanitize_optionals(data, schema, tree)

        validated_indexes = []
        skip_missing_indexes = getattr(schema, 'must_validate', False)

        if len(data) < len(schema):
            # we have missing required items in data, but we don't know
            # which ones so find what may fail:
            data_keys = [v[1] for v in data.values()]
            schema_keys = [v[1] for v in schema.values()]

            def enforce_once(data_keys, schema_key):
                # XXX Go through all the data keys and try and see if they pass
                # validation against the schema. At this point it is impossible
                # to know which data key corresponds to what schema key
                # (because schema keys can be a function/callable) so it is
                # a *very* naive way to try and detect which one might be
                # missing
                for data_key in data_keys:
                    failed = None
                    try:
                        enforce(data_key, schema_key, tree, pair='key')
                        return
                    except Invalid:
                        failed = data_key, schema_key

                    if failed:
                        return failed

            for schema_key in schema_keys:
                failure = enforce_once(data_keys, schema_key)
                if failure:
                    _, failed_schema_key = failure
                    msg = "required key in data is missing: %s" % str(
                        failed_schema_key)
                    raise Invalid(None, tree, reason=msg, pair='key')

        for index in range(len(data)):
            self.length_equality(data, schema, index, tree)
            key, value = data[index]
            skey, svalue = schema[index]
            tree.append(key)

            # Validate the key before anything, to prevent recursing
            self.key_leaf(data[index], schema[index], tree)

            # If a dict is a value we need to recurse.
            # XXX Should we check isinstance(value, ndict) ?
            if isinstance(value, dict) and len(value):
                self.traverser(value, svalue, tree)
            else:
                self.value_leaf(data[index], schema[index], tree)
            if tree:
                tree.pop()

            validated_indexes.append(index)

        # XXX There is a chance we might have missing items from
        # the incoming data that are labeled as required from the schema
        # we should make sure *here* that we account for that and raise
        # the appropriate exception. Since the loop finished and everything
        # seems to have passed, this lack of check will give false positives.
        missing_indexes = set(schema.keys()).difference(validated_indexes)
        if missing_indexes:
            if skip_missing_indexes:
                return
            for i in missing_indexes:
                if not hasattr(schema[i], 'is_optional'):
                    required_key = schema[i][0]
                    tree.append('item[%s]' % i)
                    msg = "required item in schema is missing: %s" % str(
                        required_key)
                    raise Invalid(required_key, tree, reason=msg, pair='key')
Exemplo n.º 4
0
    def traverser(self, data, schema, tree):
        """
        Traverses the dictionary, recursing onto itself if
        it sees appropriate key/value pairs that indicate that
        there is a need for more validation in a branch below us.
        """
        if hasattr(schema, '__validator_leaf__'):
            return schema(data, tree)

        if hasattr(schema, 'must_validate'):  # cherry picking?
            if not len(schema.must_validate):
                reason = "must_validate attribute must not be empty"
                raise SchemaError(data, tree, reason=reason)
            data = sift(data, schema.must_validate)

        schema = self.sanitize_optionals(data, schema, tree)

        validated_indexes = []
        skip_missing_indexes = getattr(schema, 'must_validate', False)

        if len(data) < len(schema):
            # we have missing required items in data, but we don't know
            # which ones so find what may fail:
            data_keys = [v[1] for v in data.values()]
            schema_keys = [v[1] for v in schema.values()]

            def enforce_once(data_keys, schema_key):
                # XXX Go through all the data keys and try and see if they pass
                # validation against the schema. At this point it is impossible
                # to know which data key corresponds to what schema key
                # (because schema keys can be a function/callable) so it is
                # a *very* naive way to try and detect which one might be
                # missing
                for data_key in data_keys:
                    failed = None
                    try:
                        enforce(data_key, schema_key, tree, pair='key')
                        return
                    except Invalid:
                        failed = data_key, schema_key

                    if failed:
                        return failed

            for schema_key in schema_keys:
                failure = enforce_once(data_keys, schema_key)
                if failure:
                    _, failed_schema_key = failure
                    msg = "required key in data is missing: %s" % str(failed_schema_key)
                    raise Invalid(None, tree, reason=msg, pair='key')

        for index in range(len(data)):
            self.length_equality(data, schema, index, tree)
            key, value = data[index]
            skey, svalue = schema[index]
            tree.append(key)

            # Validate the key before anything, to prevent recursing
            self.key_leaf(data[index], schema[index], tree)

            # If a dict is a value we need to recurse.
            # XXX Should we check isinstance(value, ndict) ?
            if isinstance(value, dict) and len(value):
                self.traverser(value, svalue, tree)
            else:
                self.value_leaf(data[index], schema[index], tree)
            if tree:
                tree.pop()

            validated_indexes.append(index)

        # XXX There is a chance we might have missing items from
        # the incoming data that are labeled as required from the schema
        # we should make sure *here* that we account for that and raise
        # the appropriate exception. Since the loop finished and everything
        # seems to have passed, this lack of check will give false positives.
        missing_indexes = set(schema.keys()).difference(validated_indexes)
        if missing_indexes:
            if skip_missing_indexes:
                return
            for i in missing_indexes:
                if not hasattr(schema[i], 'is_optional'):
                    required_key = schema[i][0]
                    tree.append('item[%s]' % i)
                    msg = "required item in schema is missing: %s" % str(required_key)
                    raise Invalid(required_key, tree, reason=msg, pair='key')
Exemplo n.º 5
0
    def test_get_one_item_back(self):

        data = Data({'a': 1, 'b': 2}, {}).normalized()
        result = utils.sift(data, ['b'])
        assert result == {0: ('b', 2)}
Exemplo n.º 6
0
 def test_no_required_items(self):
     data = Data({'a': 1, 'b': 2}, {}).normalized()
     result = utils.sift(data)
     assert result == {}
Exemplo n.º 7
0
    def test_get_one_item_back(self):

        data = Data({"a": 1, "b": 2}, {}).normalized()
        result = utils.sift(data, ["b"])
        assert result == {0: ("b", 2)}
Exemplo n.º 8
0
 def test_no_required_items(self):
     data = Data({"a": 1, "b": 2}, {}).normalized()
     result = utils.sift(data)
     assert result == {}
Exemplo n.º 9
0
 def test_required_item_is_function_with_object(self):
     item = RequiredItem()
     item._object = 'a'
     data = Data({'a': 1, 'b': 2}, {}).normalized()
     result = utils.sift(data, [item])
     assert result == {0: ('a', 1)}
Exemplo n.º 10
0
    def test_get_one_item_back(self):

        data = Data({'a': 1, 'b': 2}, {}).normalized()
        result = utils.sift(data, ['b'])
        assert result == {0: ('b', 2)}