diff --git a/music21/common/objects.py b/music21/common/objects.py index f0fbe3c08..24a63083b 100644 --- a/music21/common/objects.py +++ b/music21/common/objects.py @@ -159,6 +159,8 @@ def __call__(self) -> int: # ------------------------------------------------------------------------------ +_slotsByClass: dict[type, frozenset[str]] = {} + class SlottedObjectMixin: r''' @@ -223,9 +225,9 @@ def __setstate__(self, state: dict[str, t.Any]) -> None: for slot, value in state.items(): setattr(self, slot, value) - def _getSlotsRecursive(self) -> set[str]: + def _getSlotsRecursive(self) -> frozenset[str]: ''' - Find all slots recursively. + Find all slots recursively. Cached per class. A private attribute so as not to change the contents of inheriting objects private interfaces: @@ -250,10 +252,16 @@ def _getSlotsRecursive(self) -> set[str]: ['_editorial', '_style', 'direction', 'funkiness', 'groovability', 'id', 'independentAngle', 'number', 'type'] ''' + try: + return _slotsByClass[type(self)] + except KeyError: + pass slots: set[str] = set() for cls in self.__class__.mro(): slots.update(getattr(cls, '__slots__', ())) - return slots + frozenSlots = frozenset(slots) + _slotsByClass[type(self)] = frozenSlots + return frozenSlots class EqualSlottedObjectMixin(SlottedObjectMixin): diff --git a/music21/pitch.py b/music21/pitch.py index ea41aa794..6e0782dec 100644 --- a/music21/pitch.py +++ b/music21/pitch.py @@ -1057,13 +1057,8 @@ class Accidental(prebase.ProtoM21Object, style.StyleMixin): # INITIALIZER # - def __init__( # pylint: disable=super-init-not-called - self, - specifier: int|str|float = 'natural', - ) -> None: - # StyleMixin.__init__, inlined for speed; keep in sync - self._style = None - self._editorial = None + def __init__(self, specifier: int|str|float = 'natural') -> None: + super().__init__() # managed by properties self._displayType = 'normal' # normal, always, never, if-absolutely-necessary,