Skip to content

types.type_arg

TypeArg

A type argument that can be used to annotate a type. This is used to provide additional information neccessary to convert a type.

Source code in /home/runner/work/arc/arc/arc/types/type_arg.py
class TypeArg:
    """A type argument that can be used to annotate a type.
    This is used to provide additional information neccessary to convert a type."""

    __slots__: tuple[str, ...]

    def __repr__(self) -> str:
        values = ", ".join(
            [f"{member}={repr(getattr(self, member))}" for member in self.__slots__]
        )
        return f"{type(self).__name__}({values})"

    def __setattr__(self, __name: str, __value: t.Any) -> None:
        raise TypeError(f"{type(self)} is readonly")

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, TypeArg):
            return NotImplemented
        return all(
            getattr(self, attr) == getattr(other, attr) for attr in self.__slots__
        )

    def __iter__(self) -> t.Iterator[t.Tuple[str, t.Any]]:
        for slot in self.__slots__:
            yield slot, getattr(self, slot)

    def __or__(self, other: TypeArg) -> TypeArg:
        merged: dict[str, t.Any] = {}

        for (attr, value), (_, other_value) in zip(self, other):
            if isdefault(other_value):
                merged[attr] = value
            else:
                merged[attr] = other_value

        return type(self)(**merged)

    def __hash__(self) -> int:
        return id(self)

    def __init_subclass__(cls) -> None:
        init: t.Callable[..., None] = getattr(cls, "__init__")
        setattr: t.Callable[..., None] = cls.__setattr__

        def __init__(self: object, *args: t.Any, **kwargs: t.Any) -> None:
            cls.__setattr__ = object.__setattr__  # type: ignore
            init(self, *args, **kwargs)
            cls.__setattr__ = setattr  # type: ignore

        cls.__init__ = __init__  # type: ignore

    def dict(self, unwrap_defaults: bool = True) -> dict[str, t.Any]:

        return {
            attr: unwrap(getattr(self, attr))
            if unwrap_defaults
            else getattr(self, attr)
            for attr in self.__slots__
        }

    @staticmethod
    def ensure(arg: T | None, name: str) -> T:
        if not arg:
            raise errors.TypeArgError(f"{name} requires a type argument")

        return arg