'Own lru_cache decorator in python

I can't understand, why my own decorator "lru cache" doens't work.

def cache(max_size: int):
  
    dictionary = OrderedDict()

    def trace(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            cache_key = args + tuple(kwargs.items())
            if (cache_key not in dictionary) and (len(dictionary) < max_size):
                dictionary[cache_key] = func(*args, **kwargs)
            elif (cache_key not in dictionary) and (len(dictionary) == max_size):
                dictionary.popitem(last=False)
                dictionary[cache_key] = func(*args, **kwargs)
            else:
                old_cache = dictionary[cache_key]
                del dictionary[cache_key]
                dictionary[cache_key] = old_cache

            return dictionary[cache_key]

        return wrapper

    return trace

@cache(20)
def binomial(n: int, k: int):
    if k > n:
        return 0
    if k == 0:
        return 1
    return binomial(n - 1, k) + binomial(n - 1, k - 1)

binomial(30, 1)

ERRORS:

Traceback (most recent call last):
  File "main.py", line 33, in <module>
    binomial(30, 1)
  File "main.py", line 13, in wrapper
    dictionary[cache_key] = func(*args, **kwargs)
  File "main.py", line 31, in binomial
    return binomial(n - 1, k) + binomial(n - 1, k - 1)
  ...
  File "main.py", line 13, in wrapper
    dictionary[cache_key] = func(*args, **kwargs)
  File "main.py", line 31, in binomial
    return binomial(n - 1, k) + binomial(n - 1, k - 1)
  File "main.py", line 13, in wrapper
    dictionary[cache_key] = func(*args, **kwargs)
  File "main.py", line 31, in binomial
    return binomial(n - 1, k) + binomial(n - 1, k - 1)
  File "main.py", line 18, in wrapper
    old_cache = dictionary[cache_key]
KeyError: (10, 0)

As I understand, that is just recursive errors, but I can't understand why they appear.

I tried to run this decorator on fibonachi numbers function (fib(10)) with cache capacity of 3, but it return an error. WHY?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source