<commit_before>##
# Copyright (c) 2008-2010 Sprymix Inc.
# All rights reserved.
#
# See LICENSE for details.
##


import abc
import collections


class ImmutableMeta(type):
    def __new__(mcls, name, bases, dct):
        if '_shadowed_methods_' in dct:
            shadowed = dct['_shadowed_methods_']
            del dct['_shadowed_methods_']

            for method in shadowed:
                def meth(self, *args, _allow_mutation_=False, **kwargs):
                    if not _allow_mutation_:
                        raise TypeError('%r is immutable' % self.__class__.__name__)
                    return super()[method](*args, **kwargs)
                meth.__name__ = method

                dct[method] = meth

        return super().__new__(mcls, name, bases, dct)


class frozendict(dict, metaclass=ImmutableMeta):
    """Immutable dict (like ``frozenset`` for ``set``.)"""

    _shadowed_methods_ = ('__setitem__', '__delitem__', 'update', 'clear',
                          'pop', 'popitem', 'setdefault')

    def __reduce_ex__(self, protocol):
        return type(self), (dict(self),)

    def __repr__(self):
        return '%s(%s)' % (self.__class__.__name__, super().__repr__())<commit_msg>utils.datastructures.immutables: Make frozendict hasheable<commit_after>##
# Copyright (c) 2008-2010 Sprymix Inc.
# All rights reserved.
#
# See LICENSE for details.
##


import abc
import collections


class ImmutableMeta(type):
    def __new__(mcls, name, bases, dct):
        if '_shadowed_methods_' in dct:
            shadowed = dct['_shadowed_methods_']
            del dct['_shadowed_methods_']

            for method in shadowed:
                def meth(self, *args, _allow_mutation_=False, **kwargs):
                    if not _allow_mutation_:
                        raise TypeError('%r is immutable' % self.__class__.__name__)
                    return super()[method](*args, **kwargs)
                meth.__name__ = method

                dct[method] = meth

        return super().__new__(mcls, name, bases, dct)


class frozendict(dict, metaclass=ImmutableMeta):
    """Immutable dict (like ``frozenset`` for ``set``.)"""

    _shadowed_methods_ = ('__setitem__', '__delitem__', 'update', 'clear',
                          'pop', 'popitem', 'setdefault')

    def __reduce_ex__(self, protocol):
        return type(self), (dict(self),)

    def __repr__(self):
        return '%s(%s)' % (self.__class__.__name__, super().__repr__())

    __eq__ = dict.__eq__

    def __hash__(self):
        return hash(frozenset(self.items()))
{'fraction_non_alphanumeric': 0.129347401328644, 'fraction_numerical': 0.0062524423602969914, 'mean_word_length': 2.4924965893587996, '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': '7142456', 'n_tokens_mistral': 817, 'n_tokens_neox': 766, 'n_words': 188}