Memoizing decorator with retries, part 2
Your code is broken:


__forget=False needs to be before **kwargs.
retry is undefined. (But is not used)
MappingProxyType is not hashable, and so you can't memoize it.


To fix the problem with MappingProxyType you can create a hashable dict, which seems kinda hacky, but is better than nothing. The other two are easy fixes.



I don't see why you're using a class,
the only benefit that you get from it is that you can hide implementation details in it.
However self. is an annoyance in your current implementation, in my opinion.

Design wise, I still don't get the name retry_times, let's actually retry that amount rather than try that amount of times.

And I'd split the memoizer away from the retry decorator.
Being able to use say functools.lru_cache would be nice.

And so I'd make the retry aspect a function,
removing where it currently adds to the cache.
changing the while loop to a for loop,
and will removing the cache.
This should get you:

def retry(retry_times=0, suppressed_exceptions=tuple(), capture_exceptions=False):
    def inner(function):
        @functools.wraps(function)
        def wrapper(*args, **kwargs):
            for _ in range(retry_times):
                try:
                    return function(*args, **kwargs)
                except suppressed_exceptions:
                    continue
                except Exception as e:
                    if capture_exceptions:
                        return e
                    raise
            else:
                return function(*args, **kwargs)
        return wrapper
    return inner


And now you can use the retry part without the memoizing part!
After this, I'd just make a generic memoizer, without caching the **kwargs.
Say:

def memoize(fn):
    cache = {}
    @functools.wraps(fn)
    def wrapper(*args, _forget=False):
        key = (args)
        if key not in cache or _forget:
            cache[key] = fn(*args)
        return cache[key]
    return wrapper