Skip to content

Utilities

keyed.constants

Useful constants.

ORIGIN module-attribute

ORIGIN = Direction(0.0, 0.0, 0.0)

Center.

LEFT module-attribute

LEFT = Direction(-1.0, 0.0, 0.0)

Left side.

RIGHT module-attribute

RIGHT = Direction(1.0, 0.0, 0.0)

Right side.

DOWN module-attribute

DOWN = Direction(0.0, -1.0, 0.0)

Bottom side.

UP module-attribute

UP = Direction(0.0, 1.0, 0.0)

Top side.

FRONT module-attribute

FRONT = Direction(0.0, 0.0, 1.0)

Front side.

BACK module-attribute

BACK = Direction(0.0, 0.0, -1.0)

Back side.

DL module-attribute

DL = DOWN + LEFT

Bottom left side.

DR module-attribute

DR = DOWN + RIGHT

Bottom right side.

UL module-attribute

UL = UP + LEFT

Top left side.

UR module-attribute

UR = UP + RIGHT

Top right side.

ALWAYS module-attribute

ALWAYS = -9999999

Basically, this makes sure the animation is in effect far into the past.

This is a weird hack, and I'm not thrilled about it.

EXTRAS_INSTALLED module-attribute

EXTRAS_INSTALLED = find_spec('keyed_extras') is not None

Whether or not keyed-extras is installed.

Direction dataclass

A 3D vector.

Parameters:

Name Type Description Default
x float

X position, typically in the unit square.

0
y float

Y position, typically in the unit square.

0
z float

Z position, typically in the unit square.

0
Source code in src/keyed/constants.py
@dataclass
class Direction:
    """A 3D vector.

    Args:
        x: X position, typically in the unit square.
        y: Y position, typically in the unit square.
        z: Z position, typically in the unit square.
    """

    x: float = 0
    y: float = 0
    z: float = 0

    def __post_init__(self) -> None:
        self.vector = np.array([self.x, self.y, self.z], dtype=np.float64)

    def __add__(self, other: Any) -> Self:
        if isinstance(other, Direction):
            return type(self)(*(self.vector + other.vector))
        elif isinstance(other, (np.ndarray, float, int)):
            return type(self)(*(self.vector + np.array(other)))
        return NotImplemented

    def __radd__(self, other: Any) -> Self:
        return self.__add__(other)

    def __sub__(self, other: Any) -> Self:
        if isinstance(other, Direction):
            return type(self)(*(self.vector - other.vector))
        elif isinstance(other, (np.ndarray, float, int)):
            return type(self)(*(self.vector - np.array(other)))
        return NotImplemented

    def __rsub__(self, other: Any) -> "Direction":
        if isinstance(other, (np.ndarray, float, int)):
            return Direction(*(np.array(other, dtype=np.float64) - self.vector))
        return NotImplemented

    def __mul__(self, other: Any) -> Self:
        if isinstance(other, (int, float)):
            return type(self)(*(self.vector * other))
        return NotImplemented

    def __rmul__(self, other: Any) -> Self:
        return self.__mul__(other)

    def __truediv__(self, other: Any) -> Self:
        if isinstance(other, (int, float)):
            if other == 0:
                raise ValueError("Division by 0.")
            return type(self)(*(self.vector / other))
        return NotImplemented

    def __eq__(self, other: Any) -> bool:
        return np.array_equal(self.vector, other.vector) if isinstance(other, Direction) else False

    def __neg__(self) -> Self:
        return -1 * self

    def __hash__(self) -> int:
        return hash(tuple(self.vector))

    def __getitem__(self, idx: SupportsIndex) -> float:
        return cast(float, self.vector[idx.__index__()])

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}({self.vector[0]}, {self.vector[1]}, {self.vector[2]})"

keyed.types

Types that don't make sense elsewhere.

These are mostly defined to please pyright, because simple hasattr checks weren't enough.

GeometryT module-attribute

GeometryT = BaseGeometry

The base default geometry type.

Cleanable

Bases: Protocol

A Protocol for objects that have a cleanup method.

Source code in src/keyed/types.py
@runtime_checkable
class Cleanable(Protocol):
    """A Protocol for objects that have a cleanup method."""

    def cleanup(self) -> None: ...

HasAlpha

Bases: Protocol

A Protocol for objects that have a (potentially reactive) alpha attribute.

Source code in src/keyed/types.py
@runtime_checkable
class HasAlpha(Protocol):
    """A Protocol for objects that have a (potentially reactive) alpha attribute."""

    alpha: HasValue[float]