classutils.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #
  2. # SPDX-License-Identifier: GPL-2.0-only
  3. #
  4. class ClassRegistryMeta(type):
  5. """Give each ClassRegistry their own registry"""
  6. def __init__(cls, name, bases, attrs):
  7. cls.registry = {}
  8. type.__init__(cls, name, bases, attrs)
  9. class ClassRegistry(type, metaclass=ClassRegistryMeta):
  10. """Maintain a registry of classes, indexed by name.
  11. Note that this implementation requires that the names be unique, as it uses
  12. a dictionary to hold the classes by name.
  13. The name in the registry can be overridden via the 'name' attribute of the
  14. class, and the 'priority' attribute controls priority. The prioritized()
  15. method returns the registered classes in priority order.
  16. Subclasses of ClassRegistry may define an 'implemented' property to exert
  17. control over whether the class will be added to the registry (e.g. to keep
  18. abstract base classes out of the registry)."""
  19. priority = 0
  20. def __init__(cls, name, bases, attrs):
  21. super(ClassRegistry, cls).__init__(name, bases, attrs)
  22. try:
  23. if not cls.implemented:
  24. return
  25. except AttributeError:
  26. pass
  27. try:
  28. cls.name
  29. except AttributeError:
  30. cls.name = name
  31. cls.registry[cls.name] = cls
  32. @classmethod
  33. def prioritized(tcls):
  34. return sorted(list(tcls.registry.values()),
  35. key=lambda v: (v.priority, v.name), reverse=True)
  36. def unregister(cls):
  37. for key in cls.registry.keys():
  38. if cls.registry[key] is cls:
  39. del cls.registry[key]