True! Sorry for not mentioning it
this is the entire implementation of it
from __future__ import annotations
from functools import partial
from dataclasses import dataclass
from typing import overload
from typing import runtime_checkable
from typing import Protocol
from typing import Any
_traits_registry = set()
_impl_registry: dict[str, dict[str, "Trait"]] = {}
_base_trait = None
_base_impl = None
def _is_user_created_meth(name: str):
return not (name.startswith("__") & name.endswith("__"))
class _TraitImplementation:
def __give_self(self, func):
def give_self(*args, **kwargs):
return func(*((self.__instance,) + args), **kwargs)
return give_self
def __init__(self, trait, cls, instance):
self.__instance = instance
for i in list(filter(_is_user_created_meth, dir(trait))):
setattr(self, i, self.__give_self(getattr(cls, i)))
def get_trait[T](trait: type[T], instance) -> T:
return getattr(instance, f"_Trait_.{trait.__module__}.{trait.__qualname__}")(instance)
@dataclass
class TraitSkeleton:
name: str
module: str
qualname: str
def convert_trait_to_skeloton[T](trait: type[T]) -> T:
return TraitSkeleton(trait.__name__, trait.__module__, trait.__qualname__)
@overload
def has_trait(trait: "Trait", cls) -> bool:
pass
@overload
def has_trait(trait: TraitSkeleton, cls) -> bool:
pass
def has_trait(trait: TraitSkeleton | "Triat", cls) -> bool:
if not isinstance(trait, TraitSkeleton):
skeleton = trait
else:
skeleton = convert_trait_to_skeloton(triat)
return hasattr(trait, f"_Triat_.{skeleton.module}.{skeleton.name}")
class ImplMeta(type):
def __new__(mcs, name, bases, namespace):
global _base_impl
cls = super().__new__(mcs, name, bases, namespace)
is_base_impl = bases == ()
if is_base_impl:
if _base_impl is not None:
raise TypeError(f"only one base Impl can exsist. deleate {name}")
_base_impl = cls
return cls
inher = bases[0]
if inher is _base_impl:
_impl_registry[cls.__module__] = {cls.__qualname__ : cls}
return cls
class TraitMeta(type):
def __new__(mcs, name, bases, namespace):
global _base_trait
global _impl_registry
global _traits_registry
cls = super().__new__(mcs, name, bases, namespace)
is_trait_cls = bases == ()
if is_trait_cls:
if _base_trait is not None:
raise TypeError("only one base trait can exsist")
_base_trait = cls
return cls
base = bases[0]
if base is _base_trait:
_traits_registry.add(cls)
return cls
elif base in _traits_registry:
non_dunder_meth_trait = list(filter(_is_user_created_meth, dir(base)))
non_dunder_meth_cls = list(filter(_is_user_created_meth, dir(cls)))
for method in non_dunder_meth_trait:
if not method in namespace:
raise TypeError(f"method {method} not in {name}, within the {base.__name__} trait")
# else:
# name_space_sig = signature(namespace[method])
# trait_meth_sig = signature(getattr(base, method))
# implement_rule = False
try:
modified_class = _impl_registry[cls.__module__][cls.__qualname__]
except KeyError:
raise TypeError(f"class {name} is not registerd.")
_Trait_impl_layout = partial(_TraitImplementation, base, cls)
setattr(modified_class, f"_Trait_.{base.__module__}.{base.__qualname__}", _Trait_impl_layout)
_impl_registry[modified_class.__module__][modified_class.__qualname__] = modified_class
return modified_class
class RunTimeMeta(type):
def __new__(mcs, name, bases, namespace):
return super().__new__(mcs, name, bases, namespace)
def __getitem__(self, *traits: list[type[Trait]]):
def dummy_func():
raise TypeError("You are not suppose to run this")
name = "_RunTimeMeta_"
methods = {}
for trait in traits[0]:
methods[f"_Trait_.{trait.__module__}.{trait.__qualname__}"] = dummy_func
name += f".{trait.__module__}.{trait.__qualname__}"
working_cls = type(name, (Protocol,), methods)
return runtime_checkable(working_cls)
class RunTime(metaclass=RunTimeMeta):
pass
class Impl(metaclass=ImplMeta):
pass
class Trait(metaclass=TraitMeta):
pass
def runtime_type_check_traits(instance: Any, traits: RunTime):
okay = isinstance(instance, traits)
if not okay:
def proper_meth(name: str):
return name.startswith("_Trait_")
def format_meth(name: str):
if name[0:17] == "_Trait_.builtins.":
return name.lstrip("_Triat_.builtins.")
return name.lstrip("_Trait_.")
failed_traits = list(filter(proper_meth, dir(traits)))
failed_traits = list(map(format_meth, failed_traits))
raise TypeError(f"{instance} deos not have one of requird traits {failed_traits}")
Any classes that implement Impl is meant to be redefine in some way. So when
Mypy gives a warning for intended behavior, it gets annoying