Source code for pyccel.utilities.metaclasses

#------------------------------------------------------------------------------------------#
# This file is part of Pyccel which is released under MIT License. See the LICENSE file or #
# go to https://github.com/pyccel/pyccel/blob/devel/LICENSE for full license details.      #
#------------------------------------------------------------------------------------------#
""" Module containing metaclasses which are useful for the rest of pyccel
"""
from inspect import signature

__all__ = (
    'Singleton',
    'ArgumentSingleton',
)


[docs] class ArgumentSingleton(type): """ Metaclass indicating that there is only one instance of the parametrised class. Metaclass indicating that there is only one instance of the class for any given set of arguments. Parameters ---------- name : str The name of the class. bases : tuple[class,...] A tuple of the superclasses of the class. dct : dict A dictionary of the class attributes. """ def __init__(cls, name, bases, dct): cls._instances = {} # Trick inspect.signature into seeing the signature of # cls.__init__ so numpydoc checks the correct signature cls.__signature__ = signature(cls.__init__) super().__init__(name, bases, dct) def __call__(cls, *args, **kwargs): index = (*args, *sorted(kwargs.items())) existing_instance = cls._instances.get(index, None) if existing_instance is None: new_instance = super().__call__(*args, **kwargs) cls._instances[index] = new_instance return new_instance else: return existing_instance
[docs] class Singleton(type): """ Metaclass indicating that there is only one instance of the class. A metaclass which ensures that only one instance of the class is ever created. Trying to create a second instance will result in accessing the first. Parameters ---------- name : str The name of the class. bases : tuple[class,...] A tuple of the superclasses of the class. dct : dict A dictionary of the class attributes. """ def __init__(cls, name, bases, dct): cls._instance = None # Trick inspect.signature into seeing the signature of # cls.__init__ so numpydoc checks the correct signature cls.__signature__ = signature(cls.__init__) super().__init__(name, bases, dct) def __call__(cls): existing_instance = cls._instance if existing_instance is None: new_instance = super().__call__() cls._instance = new_instance return new_instance else: return existing_instance