Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
_immutable_ctx.py77 linesDownload Raw Back to dns
1# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license2 3# This implementation of the immutable decorator requires python >=4# 3.7, and is significantly more storage efficient when making classes5# with slots immutable.  It's also faster.6 7import contextvars8import inspect9 10_in__init__ = contextvars.ContextVar("_immutable_in__init__", default=False)11 12 13class _Immutable:14    """Immutable mixin class"""15 16    # We set slots to the empty list to say "we don't have any attributes".17    # We do this so that if we're mixed in with a class with __slots__, we18    # don't cause a __dict__ to be added which would waste space.19 20    __slots__ = ()21 22    def __setattr__(self, name, value):23        if _in__init__.get() is not self:24            raise TypeError("object doesn't support attribute assignment")25        else:26            super().__setattr__(name, value)27 28    def __delattr__(self, name):29        if _in__init__.get() is not self:30            raise TypeError("object doesn't support attribute assignment")31        else:32            super().__delattr__(name)33 34 35def _immutable_init(f):36    def nf(*args, **kwargs):37        previous = _in__init__.set(args[0])38        try:39            # call the actual __init__40            f(*args, **kwargs)41        finally:42            _in__init__.reset(previous)43 44    nf.__signature__ = inspect.signature(f)45    return nf46 47 48def immutable(cls):49    if _Immutable in cls.__mro__:50        # Some ancestor already has the mixin, so just make sure we keep51        # following the __init__ protocol.52        cls.__init__ = _immutable_init(cls.__init__)53        if hasattr(cls, "__setstate__"):54            cls.__setstate__ = _immutable_init(cls.__setstate__)55        ncls = cls56    else:57        # Mixin the Immutable class and follow the __init__ protocol.58        class ncls(_Immutable, cls):59            # We have to do the __slots__ declaration here too!60            __slots__ = ()61 62            @_immutable_init63            def __init__(self, *args, **kwargs):64                super().__init__(*args, **kwargs)65 66            if hasattr(cls, "__setstate__"):67 68                @_immutable_init69                def __setstate__(self, *args, **kwargs):70                    super().__setstate__(*args, **kwargs)71 72        # make ncls have the same name and module as cls73        ncls.__name__ = cls.__name__74        ncls.__qualname__ = cls.__qualname__75        ncls.__module__ = cls.__module__76    return ncls77 
codekingpro/portable-devtools · Team Ai