blob: 08bb66b3652ac891b4a929f9dffea4f00a28348b [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: GPL-2.0-only
3#
Patrick Williamsc0f7c042017-02-23 20:41:17 -06004
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):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012 """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
Patrick Williamsc124f4f2015-09-15 14:41:29 -050025 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):
Patrick Williamsc0f7c042017-02-23 20:41:17 -060041 return sorted(list(tcls.registry.values()),
Brad Bishop6e60e8b2018-02-01 10:27:11 -050042 key=lambda v: (v.priority, v.name), reverse=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050043
44 def unregister(cls):
45 for key in cls.registry.keys():
46 if cls.registry[key] is cls:
47 del cls.registry[key]