def make_ttl_cache_wrapper(inner_func, maxage, maxsize, typed=False):
    """ Use the function signature as a key for a ttl mapping.  Any misses
    will defer to the wrapped function and its result is stored for future
    calls. """

    hits = misses = 0
    cache = TTLMapping(maxsize, maxage)

    def wrapper(*args, **kwargs):
        nonlocal hits, misses
        key = functools._make_key(args, kwargs, typed)
        try:
            result = cache[key]
        except KeyError:
            misses += 1
            result = cache[key] = inner_func(*args, **kwargs)
        else:
            hits += 1
        return result

    def cache_info():
        """ Emulate lru_cache so this is a low touch replacement. """
        return TTLCacheInfo(hits, misses, maxsize, len(cache), maxage)

    def cache_clear():
        """ Clear cache and stats. """
        nonlocal hits, misses
        hits = misses = 0
        cache.clear()

    wrapper.cache_info = cache_info
    wrapper.cache_clear = cache_clear

    return functools.update_wrapper(wrapper, inner_func)
Use the function signature as a key for a ttl mapping.  Any misses
    will defer to the wrapped function and its result is stored for future
    calls.