Source code for pypet.slots
"""Module containing the superclass having slots"""
[docs]
def get_all_slots(cls):
"""Iterates through a class' (`cls`) mro to get all slots as a set."""
slots_iterator = (getattr(c, "__slots__", ()) for c in cls.__mro__)
# `__slots__` might only be a single string,
# so we need to put the strings into a tuple.
slots_converted = ((slots,) if isinstance(slots, str) else slots for slots in slots_iterator)
all_slots = set()
all_slots.update(*slots_converted)
return all_slots
[docs]
class HasSlots(metaclass=MetaSlotMachine):
"""Top-class that allows mixing of classes with and without slots.
Takes care that instances can still be pickled with the lowest
protocol. Moreover, provides a generic `__dir__` method that
lists all slots.
"""
__slots__ = ("__weakref__",)
[docs]
def __getstate__(self):
if hasattr(self, "__dict__"):
# We don't require that all sub-classes also define slots,
# so they may provide a dictionary
statedict = self.__dict__.copy()
else:
statedict = {}
# Get all slots of potential parent classes
for slot in self.__all_slots__:
try:
value = getattr(self, slot)
statedict[slot] = value
except AttributeError:
pass
# Pop slots that cannot or should not be pickled
statedict.pop("__dict__", None)
statedict.pop("__weakref__", None)
return statedict
[docs]
def __setstate__(self, state):
"""Recalls state for items with slots"""
for key in state:
setattr(self, key, state[key])
[docs]
def __dir__(self):
"""Includes all slots in the `dir` method"""
result = set()
result.update(dir(self.__class__), self.__all_slots__)
if hasattr(self, "__dict__"):
result.update(self.__dict__.keys())
return list(result)