LaboratoireMecaniqueLille / crappy

Command and Real-time Acquisition Parallelized in Python
https://crappy.readthedocs.io/en/stable/
GNU General Public License v2.0
78 stars 16 forks source link

Replace metaclasses with `__init_subclass__` method #72

Open WeisLeDocto opened 10 months ago

WeisLeDocto commented 10 months ago

Currently, metaclasses are used in Crappy to ensure that two classes of a same type cannot have the same name. Starting from Python 3.6, PEP 487 introduces the __init_subclass__ method allowing to execute initialization code at the class level when creating a subclass, without requiring a metaclass.

Using this feature, it is possible to keep the name-check functionality while removing all the metaclasses from the repo. Here's a dummy code of a possible implementation:

class Parent:

  subclasses = list()

  def __init_subclass__(cls, **kwargs) -> None:

    super().__init_subclass__()
    if cls.__name__ in cls.subclasses:
      raise TypeError(f"A Class with the name {cls.__name__} is already "
                      f"defined !")
    cls.subclasses.append(cls.__name__)

After implementing this feature, the folders now containing for each object in Crappy its metaclass and base class would then only contain the base class. It would then make sense to move the base classes back with their children, as it was before version 2.0.0. The names of the files containing the base classes should clearly reflect the fact that they're special objects in the repo, for example using dunders. The documentation should also be updated accordingly.

ToDo