<commit_before>from operator import itemgetter

import itertools
from typing import Mapping
from collections import OrderedDict
from plenum.common.constants import OP_FIELD_NAME
from plenum.common.messages.fields import FieldValidator

class MessageValidator(FieldValidator):

    # the schema has to be an ordered iterable because the message class
    # can be create with positional arguments __init__(*args)
    schema = ()
    optional = False

    def validate(self, dct):
        self._validate_fields_with_schema(dct, self.schema)
        self._validate_message(dct)

    def _validate_fields_with_schema(self, dct, schema):
        if not isinstance(dct, dict):
            self._raise_invalid_type(dct)
        schema_dct = dict(schema)
        required_fields = filter(lambda x: not x[1].optional, schema)
        required_field_names = map(lambda x: x[0], required_fields)
        missed_required_fields = set(required_field_names) - set(dct)
        if missed_required_fields:
            self._raise_missed_fields(*missed_required_fields)
        for k, v in dct.items():
            if k not in schema_dct:
                self._raise_unknown_fields(k, v)
            validation_error = schema_dct[k].validate(v)
            if validation_error:
                self._raise_invalid_fields(k, v, validation_error)


    def _raise_invalid_type(self, dct):
        raise TypeError("validation error: invalid type {}, dict expected"
                        .format(type(dct)))

    def _validate_message(self, dct):
        return None

    def _raise_missed_fields(self, *fields):
        raise TypeError("validation error: missed fields "
                        "{}".format(', '.join(map(str, fields))))

    def _raise_unknown_fields(self, field, value):
        raise TypeError("validation error: unknown field "
                        "({}={})".format(field, value))

    def _raise_invalid_fields(self, field, value, reason):
        raise TypeError("validation error: {} "
                        "({}={})".format(reason, field, value))

    def _raise_invalid_message(self, reason):
        raise TypeError("validation error: {}".format(reason))


class MessageBase(Mapping, MessageValidator):
    typename = None

    def __init__(self, *args, **kwargs):
        assert not (args and kwargs), \
            '*args, **kwargs cannot be used together'

        if kwargs:
            # op field is not required since there is self.typename
            kwargs.pop(OP_FIELD_NAME, None)

        argsLen = len(args or kwargs)
        assert argsLen == len(self.schema), \
            "number of parameters should be the " \
            "same as a number of fields in schema, but it was {}" \
                .format(argsLen)
<commit_msg>update error message for validation<commit_after>from operator import itemgetter

import itertools
from typing import Mapping
from collections import OrderedDict
from plenum.common.constants import OP_FIELD_NAME
from plenum.common.messages.fields import FieldValidator

class MessageValidator(FieldValidator):

    # the schema has to be an ordered iterable because the message class
    # can be create with positional arguments __init__(*args)
    schema = ()
    optional = False

    def validate(self, dct):
        self._validate_fields_with_schema(dct, self.schema)
        self._validate_message(dct)

    def _validate_fields_with_schema(self, dct, schema):
        if not isinstance(dct, dict):
            self._raise_invalid_type(dct)
        schema_dct = dict(schema)
        required_fields = filter(lambda x: not x[1].optional, schema)
        required_field_names = map(lambda x: x[0], required_fields)
        missed_required_fields = set(required_field_names) - set(dct)
        if missed_required_fields:
            self._raise_missed_fields(*missed_required_fields)
        for k, v in dct.items():
            if k not in schema_dct:
                self._raise_unknown_fields(k, v)
            validation_error = schema_dct[k].validate(v)
            if validation_error:
                self._raise_invalid_fields(k, v, validation_error)


    def _raise_invalid_type(self, dct):
        raise TypeError("validation error: invalid type {}, dict expected"
                        .format(type(dct)))

    def _validate_message(self, dct):
        return None

    def _raise_missed_fields(self, *fields):
        raise TypeError("validation error: missed fields: "
                        "{}".format(', '.join(map(str, fields))))

    def _raise_unknown_fields(self, field, value):
        raise TypeError("validation error: unknown field: "
                        "{}={}".format(field, value))

    def _raise_invalid_fields(self, field, value, reason):
        raise TypeError("validation error: {} "
                        "({}={})".format(reason, field, value))

    def _raise_invalid_message(self, reason):
        raise TypeError("validation error: {}".format(reason))


class MessageBase(Mapping, MessageValidator):
    typename = None

    def __init__(self, *args, **kwargs):
        assert not (args and kwargs), \
            '*args, **kwargs cannot be used together'

        if kwargs:
            # op field is not required since there is self.typename
            kwargs.pop(OP_FIELD_NAME, None)

        argsLen = len(args or kwargs)
        assert argsLen == len(self.schema), \
            "number of parameters should be the " \
            "same as a number of fields in schema, but it was {}" \
                .format(argsLen)

{'fraction_non_alphanumeric': 0.09330922242314647, 'fraction_numerical': 0.0007233273056057866, 'mean_word_length': 2.636423405654175, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '960526', 'n_tokens_mistral': 1528, 'n_tokens_neox': 1490, 'n_words': 432}