from dataclasses import dataclass, field from typing import Any, Generic, TypeVar, TypeVarTuple, Union, Unpack T = TypeVar("T") L = TypeVarTuple("L") ID = int @dataclass class Cache(Generic[*L, T]): cached: list[T] = field(default_factory=list) lookups: dict[type[Union[*L]], dict[Union[*L], ID]] = field(default_factory=dict) def __getitem__(self, key: Union[*L]) -> T: id = self.lookups[type(key)][key] return self.cached[id] def __setitem__(self, keys: tuple[Unpack[L]], value: T) -> None: print(type(keys), keys) id = len(self.cached) self.cached.append(value) for key in keys: self.lookups.setdefault(type(key), {}) self.lookups[type(key)][key] = id if __name__ == "__main__": c = Cache[int, str, str]() print(c) c[0, None] = "a" print(c)