def METHOD_NAME(self: S, *args: P.args, **kwargs: P.kwargs) -> T:
    if not hasattr(self, cache_attr_name):
        cache: Dict[Hashable, T] = {}
        setattr(self, cache_attr_name, cache)
    else:
        cache = getattr(self, cache_attr_name)
    key = _make_key(args, kwargs)
    if key not in cache:
        result = method(self, *args, **kwargs)
        cache[key] = result
    return cache[key]