classification
Title: lru_cache should support invalidations
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.7
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: jcea, rhettinger, serhiy.storchaka, steven.daprano
Priority: normal Keywords:

Created on 2017-04-24 10:29 by jcea, last changed 2017-04-25 02:44 by rhettinger. This issue is now closed.

Messages (6)
msg292216 - (view) Author: Jesús Cea Avión (jcea) * (Python committer) Date: 2017-04-24 10:29
I think that "functools.lru_cache()" should have the ability to "invalidate" a (possibly cached) value. Something like:

@functools.lru_cache()
def func(param):
  ...

func.invalidate(PARAM) # discard this cached call, or ignore if not cached
msg292226 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2017-04-24 12:06
Perhaps the existing ``cache_clear`` method could take optional arguments?

def cache_clear(self, *args, **kw):
    if not (args or kw):
        # clear the entire cache
    else:
        # clear just the cache entry for *args, **kw
msg292228 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-04-24 12:18
Could cache_clear() clear the entire cache or discard just the cached call without arguments?
msg292229 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-04-24 13:34
This is a duplicate of rejected issue28178.

See also related issue17528, issue18577, issue19859, issue23030, issue26082, and issue28112.
msg292248 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-04-25 01:18
Sorry Jesús, I don't want to add feature creep to the LRU cache.

FWIW, it is very easy to make your own variants from collections.OrderedDict.
msg292251 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-04-25 02:44
If you're interested, here is a starting point for experimenting with any variations you want (invalidate a specific entry, changeable maxsize, pickle/unpickle, expiration of entries after a specific time, inspection of the internal contents, ability to inject known values, testing whether a specific argument tuple is in the cache, logging of cache access, or just about anything you could do with a regular dictionary):

    class LRU(OrderedDict):

        def __init__(self, func, maxsize=128):
            self.maxsize = 128
            self.func = func

        def __call__(self, *args):
            if args in self:
                value = self[args]
                self.move_to_end(args)
                return value
            value = self.func(*args)
            if len(self) >= self.maxsize:
                self.popitem(False)
            self[args] = value
            return value
History
Date User Action Args
2017-04-25 02:44:34rhettingersetmessages: + msg292251
2017-04-25 01:18:20rhettingersetstatus: open -> closed
resolution: rejected
messages: + msg292248

stage: needs patch -> resolved
2017-04-24 13:34:02serhiy.storchakasetassignee: rhettinger
messages: + msg292229
2017-04-24 12:18:41serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg292228
2017-04-24 12:06:57steven.dapranosetnosy: + rhettinger, steven.daprano
messages: + msg292226
components: + Library (Lib)
2017-04-24 10:29:30jceacreate