<commit_before>from django.db import models
from django.core.exceptions import FieldError


class ModelTracker(object):
    def __init__(self, fields=None):
        self.fields = fields

    def contribute_to_class(self, cls, name):
        self.name = name
        models.signals.class_prepared.connect(self.finalize, sender=cls)

    def finalize(self, sender, **kwargs):
        descriptor = ModelTrackerDescriptor(sender, self.name, self.fields)
        setattr(sender, self.name, descriptor)


class ModelTrackerDescriptor(object):
    def __init__(self, cls, name, fields):
        self.attname = '_%s' % name
        self.fields = fields
        if self.fields is None:
            self.fields = [field.attname for field in cls._meta.local_fields]
        models.signals.post_init.connect(self.initialize, sender=cls)

    def initialize(self, sender, instance, **kwargs):
        tracker = ModelInstanceTracker(instance, self.fields)
        setattr(instance, self.attname, tracker)
        tracker.set_saved_fields()
        self.patch_save(instance)

    def patch_save(self, instance):
        original_save = instance.save
        def save(**kwargs):
            ret = original_save()
            getattr(instance, self.attname).set_saved_fields()
            return ret
        setattr(instance, 'save', save)

    def __get__(self, instance, owner):
        if instance is None:
            return self
        else:
            return getattr(instance, self.attname)


class ModelInstanceTracker(object):
    def __init__(self, instance, fields):
        self.instance = instance
        self.fields = fields

    def set_saved_fields(self):
        self.saved_data = self.current_fields()<commit_msg>Remove unnecessary use of setattr<commit_after>from django.db import models
from django.core.exceptions import FieldError


class ModelTracker(object):
    def __init__(self, fields=None):
        self.fields = fields

    def contribute_to_class(self, cls, name):
        self.name = name
        models.signals.class_prepared.connect(self.finalize, sender=cls)

    def finalize(self, sender, **kwargs):
        descriptor = ModelTrackerDescriptor(sender, self.name, self.fields)
        setattr(sender, self.name, descriptor)


class ModelTrackerDescriptor(object):
    def __init__(self, cls, name, fields):
        self.attname = '_%s' % name
        self.fields = fields
        if self.fields is None:
            self.fields = [field.attname for field in cls._meta.local_fields]
        models.signals.post_init.connect(self.initialize, sender=cls)

    def initialize(self, sender, instance, **kwargs):
        tracker = ModelInstanceTracker(instance, self.fields)
        setattr(instance, self.attname, tracker)
        tracker.set_saved_fields()
        self.patch_save(instance)

    def patch_save(self, instance):
        original_save = instance.save
        def save(**kwargs):
            ret = original_save()
            getattr(instance, self.attname).set_saved_fields()
            return ret
        instance.save = save

    def __get__(self, instance, owner):
        if instance is None:
            return self
        else:
            return getattr(instance, self.attname)


class ModelInstanceTracker(object):
    def __init__(self, instance, fields):
        self.instance = instance
        self.fields = fields

    def set_saved_fields(self):
        self.saved_data = self.current_fields()
{'fraction_non_alphanumeric': 0.09532112757919209, 'fraction_numerical': 0.0, 'mean_word_length': 2.7991169977924946, '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': '1035236', 'n_tokens_mistral': 961, 'n_tokens_neox': 942, 'n_words': 232}