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