Source code for orion.core.utils.singleton

# -*- coding: utf-8 -*-
"""
Singleton helpers and boilerplate
=================================

"""
from abc import ABCMeta

from orion.core.utils import Factory


[docs]class SingletonAlreadyInstantiatedError(ValueError): """Exception to be raised when someone provides arguments to build an object from a already-instantiated `SingletonType` class. """ def __init__(self, name): """Pass the same constant message to ValueError underneath.""" super().__init__( "A singleton instance of (type: {}) has already been instantiated.".format( name ) )
[docs]class SingletonNotInstantiatedError(TypeError): """Exception to be raised when someone try to access an instance of a singleton that has not been instantiated yet """ def __init__(self, name): """Pass the same constant message to TypeError underneath.""" super().__init__("No singleton instance of (type: {}) was created".format(name))
[docs]class SingletonType(type): """Metaclass that implements the singleton pattern for a Python class.""" def __init__(cls, name, bases, dictionary): """Create a class instance variable and initiate it to None object.""" super(SingletonType, cls).__init__(name, bases, dictionary) cls.instance = None
[docs] def __call__(cls, *args, **kwargs): """Create an object if does not already exist, otherwise return what there is.""" if cls.instance is None: try: cls.instance = super(SingletonType, cls).__call__(*args, **kwargs) except TypeError as exception: raise SingletonNotInstantiatedError(cls.__name__) from exception elif args or kwargs: raise SingletonAlreadyInstantiatedError(cls.__name__) return cls.instance
[docs]class AbstractSingletonType(SingletonType, ABCMeta): """This will create singleton base classes, that need to be subclassed and implemented.""" pass
[docs]class SingletonFactory(AbstractSingletonType, Factory): """Wrapping `orion.core.utils.Factory` with `SingletonType`. Keep compatibility with `AbstractSingletonType`.""" pass
[docs]def update_singletons(values=None): """Replace singletons by given values and return previous singleton objects""" if values is None: values = {} # Avoiding circular import problems when importing this module. from orion.core.io.database import Database from orion.core.io.database.ephemeraldb import EphemeralDB from orion.core.io.database.mongodb import MongoDB from orion.core.io.database.pickleddb import PickledDB from orion.storage.base import Storage from orion.storage.legacy import Legacy from orion.storage.track import Track singletons = (Storage, Legacy, Database, MongoDB, PickledDB, EphemeralDB, Track) updated_singletons = {} for singleton in singletons: updated_singletons[singleton] = singleton.instance singleton.instance = values.get(singleton, None) return updated_singletons