def METHOD_NAME(key_func, max_age_seconds=DEFAULT_MAX_AGE, max_size=DEFAULT_MAX_SIZE):
    """
    Decorate a function or method to cache results up  to `max_age_seconds`.
    :param key_func: user specified function to execute over the arguments to determine the key.
    :type key_func: callable
    :param max_age_seconds: Maximum number of seconds during which the cached value is valid.
    :type max_age_seconds: int
    :return: Decorating function wrapper.
    :rtype: callable
    """
    if max_age_seconds < 0:
        raise TypeError('Max cache age cannot be a negative number.')
    if max_size < 0:
        raise TypeError('Max cache size cannot be a negative number.')
    if max_age_seconds == 0 or max_size == 0:
        return lambda function: function  # bypass cache overlay.
    def _decorator(user_function):
        """
        Decorate function to be used with `@` syntax.
        :param user_function: Function to decorate with cacheable results
        :type user_function: callable
        :return: A function that looks exactly the same but with cacheable results.
        :rtype: callable
        """
        _cache = LocalMemoryCache(key_func, user_function, max_age_seconds, max_size)
        # The lambda below IS necessary, otherwise update_wrapper fails since the function
        # is an instance method and has no reference to the __module__ namespace.
        wrapper = lambda *args, **kwargs: _cache.get(*args, **kwargs)  # pylint: disable=unnecessary-lambda
        return update_wrapper(wrapper, user_function)
    return _decorator