# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/06_solo.ipynb.

# %% auto 0
__all__ = ['Singleton', 'Empty', 'Module', 'EmptyModule']

# %% ../nbs/06_solo.ipynb 6
#| export


# %% ../nbs/06_solo.ipynb 8
from types import ModuleType
from typing import (Any, )

# %% ../nbs/06_solo.ipynb 10
#| export

# %% ../nbs/06_solo.ipynb 12
#| export

# %% ../nbs/06_solo.ipynb 14
#| export


# %% ../nbs/06_solo.ipynb 16
class Singleton(type):
    _ins = {}
    def __new__(cls, name: str = 'Singleton', bases: tuple = (), namespace: dict = {}, **kwargs):
        insdict = namespace.get('_ins', cls._ins)
        insdict.update(cls._ins)
        namespace.update(_ins=insdict)
        if name not in insdict:
            cls._ins[name] = super().__new__(cls, name, bases, namespace, **kwargs)
        return cls._ins[name]
        
    def __instancecheck__(self, __instance: Any) -> bool: return super().__instancecheck__(__instance)    
    def __subclasscheck__(self, __subclass: type) -> bool: return super().__subclasscheck__(__subclass)
    def __eq__(cls, ins) -> bool:  return isinstance(ins, (cls, cls.__class__))
    def __hash__(cls) -> int: return hash(cls.__name__)
    def __repr__(cls) -> str: return f'<{type(cls).__name__.lower()} {cls.__name__}>'
    def __call__(cls, *args, **kwargs): return cls._ins[cls.__name__]

    
class Empty(Singleton): ...
class Module(ModuleType, metaclass=Empty): ...
class EmptyModule(ModuleType, metaclass=Singleton): ... 
