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