CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
_bunch.py105 linesDownload Raw Back to utils
1"""Bunch-related classes."""2 3# Authors: The MNE-Python contributors.4# License: BSD-3-Clause5# Copyright the MNE-Python contributors.6 7from copy import deepcopy8 9###############################################################################10# Create a Bunch class that acts like a struct (mybunch.key = val)11 12 13class Bunch(dict):14    """Dictionary-like object that exposes its keys as attributes."""15 16    def __init__(self, **kwargs):17        dict.__init__(self, kwargs)18        self.__dict__ = self19 20 21###############################################################################22# A protected version that prevents overwriting23 24 25class BunchConst(Bunch):26    """Class to prevent us from re-defining constants (DRY)."""27 28    def __setitem__(self, key, val):  # noqa: D10529        if key != "__dict__" and key in self:30            raise AttributeError(f"Attribute {repr(key)} already set")31        super().__setitem__(key, val)32 33 34###############################################################################35# A version that tweaks the __repr__ of its values based on keys36 37 38class BunchConstNamed(BunchConst):39    """Class to provide nice __repr__ for our integer constants.40 41    Only supports string keys and int or float values.42    """43 44    def __setattr__(self, attr, val):  # noqa: D10545        assert isinstance(attr, str)46        if isinstance(val, int):47            val = NamedInt(attr, val)48        elif isinstance(val, float):49            val = NamedFloat(attr, val)50        else:51            assert isinstance(val, BunchConstNamed), type(val)52        super().__setattr__(attr, val)53 54 55class _Named:56    """Provide shared methods for giving named-representation subclasses."""57 58    def __new__(cls, name, val):  # noqa: D102,D10559        out = _named_subclass(cls).__new__(cls, val)60        out._name = name61        return out62 63    def __str__(self):  # noqa: D10564        return f"{self.__class__.mro()[-2](self)} ({self._name})"65 66    __repr__ = __str__67 68    # see https://stackoverflow.com/a/15774013/217596569    def __copy__(self):  # noqa: D10570        cls = self.__class__71        result = cls.__new__(cls)72        result.__dict__.update(self.__dict__)73        return result74 75    def __deepcopy__(self, memo):  # noqa: D10576        cls = self.__class__77        result = cls.__new__(cls, self._name, self)78        memo[id(self)] = result79        for k, v in self.__dict__.items():80            setattr(result, k, deepcopy(v, memo))81        return result82 83    def __getnewargs__(self):  # noqa: D10584        return self._name, _named_subclass(self)(self)85 86 87def _named_subclass(klass):88    if not isinstance(klass, type):89        klass = klass.__class__90    subklass = klass.mro()[-2]91    assert subklass in (int, float)92    return subklass93 94 95class NamedInt(_Named, int):96    """Int with a name in __repr__."""97 98    pass  # noqa99 100 101class NamedFloat(_Named, float):102    """Float with a name in __repr__."""103 104    pass  # noqa105 
Aluode/PerceptionLabPortable · CoolFace