<commit_before>
from . import fields
from .meta import Meta


class MetaSerialiser(type):
    def __new__(mcs, name, bases, attrs):
        # Inherited fields
        attrs['_fields'] = {}

        # Inherit from parents
        try:
            for base in bases[::-1]:
                parent_fields = getattr(base, '_fields', {})
                attrs['_fields'].update(parent_fields)
        except NameError:
            # Can't do this for Serialiser
            pass

        declared_fields = {}
        for field_name, field in attrs.items():
            if isinstance(field, fields.Field):
                declared_fields[field_name] = attrs.pop(field_name)

        attrs['_fields'].update(declared_fields)

        new_class = super(MetaSerialiser, mcs).__new__(mcs, name, bases, attrs)
        meta = getattr(new_class, 'Meta', None)
        new_class._meta = Meta(meta)

        return new_class


class Serialiser(object):
    __metaclass__ = MetaSerialiser

    def object_deflate(self, obj, **kwargs):
        data = {}
        for name, field in self._fields.items():
            field.deflate(name, obj=obj, data=data, **kwargs)
            method = getattr(self, 'deflate_%s' % name, None)
            if method is not None:
                data[name] = method(obj=obj, data=data, **kwargs)
        return data

    def list_deflate(self, obj_list, **kwargs):
        return [
            self.object_deflate(obj, **kwargs)
            for obj in iter(obj_list)
        ]

    def object_inflate(self, data, instance=None, **kwargs):
        obj = {}
        for name, field in self._fields.items():
            if field.readonly:
                continue
            method = getattr(self, 'inflate_%s' % name, None)
            if method is not None:
                obj[name] = method(data=data, obj=obj, instance=instance, **kwargs)
            else:
                field.inflate(name, data, obj, **kwargs)
        return self.restore_object(obj, instance=instance, **kwargs)

    def list_inflate(self, data_list, **kwargs):
        # XXX target object list?
        return [
            self.object_inflate(data, **kwargs)
            for data in data_list
        ]

    def restore_object(self, obj, **kwargs): # pragma: no cover
        raise NotImplementedError<commit_msg>Move tests out of inflate/deflate loop by pre-building list of inflate/deflate methods on init<commit_after>
from . import fields
from .meta import Meta

from functools import partial

class MetaSerialiser(type):
    def __new__(mcs, name, bases, attrs):
        # Inherited fields
        attrs['_fields'] = {}

        # Inherit from parents
        try:
            for base in bases[::-1]:
                parent_fields = getattr(base, '_fields', {})
                attrs['_fields'].update(parent_fields)
        except NameError:
            # Can't do this for Serialiser
            pass

        declared_fields = {}
        for field_name, field in attrs.items():
            if isinstance(field, fields.Field):
                declared_fields[field_name] = attrs.pop(field_name)

        attrs['_fields'].update(declared_fields)

        new_class = super(MetaSerialiser, mcs).__new__(mcs, name, bases, attrs)
        meta = getattr(new_class, 'Meta', None)
        new_class._meta = Meta(meta)

        return new_class


class Serialiser(object):
    __metaclass__ = MetaSerialiser

    def __init__(self):
        # Build list of deflate and inflate methods
        self._deflaters = []
        self._inflaters = []
        def _setter(name, method, obj, data, *args, **kwargs):
            '''Wrapper for deflate_FOO'''
            data[name] = method(obj=obj, data=data, *args, **kwargs)
        def _getter(name, method, data, obj, *args, **kwargs):
            obj[name] = method(data=data, obj=obj, *args, **kwargs)

        for name, field in self._fields.items():
            self._deflaters.append(partial(field.deflate, name))
            method = getattr(self, 'deflate_%s' % name, None)
            if method is not None:
                self._deflaters.append(partial(_setter, name, method))

            if field.readonly:
                continue
            method = getattr(self, 'inflate_%s' % name, None)
            if method:
                self._inflaters.append(partial(_getter, name, method))
            else:
                self._inflaters.append(partial(field.inflate, name))

    def object_deflate(self, obj, **kwargs):
        data = {}
        for method in self._deflaters:
            method(obj=obj, data=data, **kwargs)
        return data

    def list_deflate(self, obj_list, **kwargs):
        return [
            self.object_deflate(obj, **kwargs)
            for obj in iter(obj_list)
        ]

    def object_inflate(self, data, instance=None, **kwargs):
        obj = {}
        for method in self._inflaters:
            method(data=data, obj=obj, instance=instance, **kwargs)
        return self.restore_object(obj, instance=instance, **kwargs)

    def list_inflate(self, data_list, **kwargs):
        # XXX target object list?
        return [
            self.object_inflate(data, **kwargs)
            for data in data_list
        ]

    def restore_object(self, obj, **kwargs): # pragma: no cover
        raise NotImplementedError
{'fraction_non_alphanumeric': 0.10849056603773585, 'fraction_numerical': 0.0003773584905660377, 'mean_word_length': 2.1497326203208558, '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': '303279', 'n_tokens_mistral': 1551, 'n_tokens_neox': 1520, 'n_words': 396}