<commit_before>#  -*- coding: utf-8 -*-
#  Representation.py ---
#


from django import forms
from copy import deepcopy
from django.core.exceptions import ValidationError


__all__ = ('Representation',)


class BaseRepresentation(object):
    """ Base class for actual Representation class.

    You shouldn't need to touch this. Always subclass from
    :class:`Representation`.
    """

    def __init__(self):
        """ Create the ``fields`` property.

        ``base_fields`` is left as a backup. You shouldn't modify it.
        """

        self.fields = deepcopy(self.base_fields)

    def validate(self, data=None):
        """ Validate the data

        Check also that no extra properties are present.

        :raises: ValidationError if the data is not valid.
        """

        errors = {}

        # validate each field, one by one
        for name, field in self.fields.items():
            try:
                field.clean(data.get(name))
            except ValidationError, e:
                errors[name] = e.messages

        # check for extra fields
        extras = set(data.keys()) - set(self.fields.keys())
        if extras:
            errors[', '.join(extras)] = ['field(s) not allowed']

        # if errors, raise ValidationError
        if errors:
            raise ValidationError(errors)


def get_declared_fields(bases, attrs):
    """ Find all fields and return them as a dictionary.

    note:: this is function is copied and modified
        from django.forms.get_declared_fields
    """

    def is_field(prop):
        return isinstance(prop, forms.Field) or \
            isinstance(prop, BaseRepresentation)

    fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if is_field(obj)]
    # add fields from base classes:
    for base in bases[::-1]:
        if hasattr(base, 'base_fields'):
            fields = base.base_fields.items() + fields
    return dict(fields)


class RepresentationMeta(type):
    """ Metaclass for Representations.

    This will find all fields defined for a Representation and stick them
    in a dictionary in ``base_fields`` property.
    """

    def __new__(cls, name, bases, attrs):
        attrs['base_fields'] = get_declared_fields(bases, attrs)
        return super(RepresentationMeta, cls).__new__(cls, name, bases, attrs)


class Representation(BaseRepresentation):
    """ Base class for all validation Representations.

    Subclass this for your own Representation. Only two properties are
    required from Representations: ``validate`` method and ``fields`` property.

    seealso:: :class:`BaseRepresentation` for details on methods.
    """

    __metaclass__ = RepresentationMeta


#
#  Representation.py ends here
<commit_msg>catch exceptions in validation if the data is not dict-like<commit_after>#  -*- coding: utf-8 -*-
#  Representation.py ---
#


from django import forms
from copy import deepcopy
from django.core.exceptions import ValidationError


__all__ = ('Representation',)


class BaseRepresentation(object):
    """ Base class for actual Representation class.

    You shouldn't need to touch this. Always subclass from
    :class:`Representation`.
    """

    def __init__(self):
        """ Create the ``fields`` property.

        ``base_fields`` is left as a backup. You shouldn't modify it.
        """

        self.fields = deepcopy(self.base_fields)

    def validate(self, data=None):
        """ Validate the data

        Check also that no extra properties are present.

        :raises: ValidationError if the data is not valid.
        """

        errors = {}

        # validate each field, one by one
        for name, field in self.fields.items():
            try:
                field.clean(data.get(name))
            except ValidationError, e:
                errors[name] = e.messages
            except AttributeError, e:
                raise ValidationError('data should be of type dict but is %s' % (type(data),))

        # check for extra fields
        extras = set(data.keys()) - set(self.fields.keys())
        if extras:
            errors[', '.join(extras)] = ['field(s) not allowed']

        # if errors, raise ValidationError
        if errors:
            raise ValidationError(errors)


def get_declared_fields(bases, attrs):
    """ Find all fields and return them as a dictionary.

    note:: this is function is copied and modified
        from django.forms.get_declared_fields
    """

    def is_field(prop):
        return isinstance(prop, forms.Field) or \
            isinstance(prop, BaseRepresentation)

    fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if is_field(obj)]
    # add fields from base classes:
    for base in bases[::-1]:
        if hasattr(base, 'base_fields'):
            fields = base.base_fields.items() + fields
    return dict(fields)


class RepresentationMeta(type):
    """ Metaclass for Representations.

    This will find all fields defined for a Representation and stick them
    in a dictionary in ``base_fields`` property.
    """

    def __new__(cls, name, bases, attrs):
        attrs['base_fields'] = get_declared_fields(bases, attrs)
        return super(RepresentationMeta, cls).__new__(cls, name, bases, attrs)


class Representation(BaseRepresentation):
    """ Base class for all validation Representations.

    Subclass this for your own Representation. Only two properties are
    required from Representations: ``validate`` method and ``fields`` property.

    seealso:: :class:`BaseRepresentation` for details on methods.
    """

    __metaclass__ = RepresentationMeta


#
#  Representation.py ends here

{'fraction_non_alphanumeric': 0.09977084435043188, 'fraction_numerical': 0.0007050943063634761, 'mean_word_length': 2.6892067620286086, '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': '3688041', 'n_tokens_mistral': 1566, 'n_tokens_neox': 1507, 'n_words': 519}