Coverage for src/configuraptor/singleton.py: 100%
13 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-11-07 15:36 +0100
« prev ^ index » next coverage.py v7.2.7, created at 2023-11-07 15:36 +0100
1"""
2Singleton mixin/metaclass.
3"""
5import typing
8class SingletonMeta(type):
9 """
10 Every instance of a singleton shares the same object underneath.
12 Can be used as a metaclass:
13 Example:
14 class AbstractConfig(metaclass=Singleton):
16 Source: https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python
17 """
19 _instances: typing.ClassVar[dict[typing.Type[typing.Any], typing.Type[typing.Any]]] = {}
21 def __call__(self, *args: typing.Any, **kwargs: typing.Any) -> typing.Type[typing.Any]:
22 """
23 When a class is instantiated (e.g. `AbstractConfig()`), __call__ is called. This overrides the default behavior.
24 """
25 if self not in self._instances:
26 self._instances[self] = super(SingletonMeta, self).__call__(*args, **kwargs)
28 return self._instances[self]
30 @staticmethod
31 def clear(instance: "Singleton" = None) -> None:
32 """
33 Use to remove old instances.
35 (otherwise e.g. pytest will crash)
36 """
37 if instance:
38 SingletonMeta._instances.pop(instance.__class__, None)
39 else:
40 SingletonMeta._instances.clear()
43class Singleton(metaclass=SingletonMeta):
44 """
45 Mixin to make a class a singleton.
46 """