dgilland / cacheout

A caching library for Python
https://cacheout.readthedocs.io
MIT License
421 stars 44 forks source link

LRU cache get() with default throws KeyError #4

Closed MrCreosote closed 6 years ago

MrCreosote commented 6 years ago

Maybe I'm not understanding the semantics, but this is not what I would expect:

$ ipython
Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import cacheout

In [2]: cacheout.__version__
Out[2]: '0.10.1'

In [3]: c = cacheout.LRUCache()

In [4]: c.get('foo', default='bar')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-4-09ce1ce78da4> in <module>()
----> 1 c.get('foo', default='bar')

~/anaconda3/lib/python3.6/site-packages/cacheout/cache.py in get(self, key, default)
    214         """
    215         with self._lock:
--> 216             return self._get(key, default=default)
    217 
    218     def _get(self, key, default=None):

~/anaconda3/lib/python3.6/site-packages/cacheout/lru.py in _get(self, key, default)
     14     def _get(self, key, default=None):
     15         value = super()._get(key, default=default)
---> 16         self._cache.move_to_end(key)
     17         return value

KeyError: 'foo'

Looking at the traceback, it appears that the move_to_end() call shouldn't occur if the default value was returned, but there's no way to know whether the value returned is the default or just happened to exist in the cache with the same value as the default. Maybe _get() needs to return an is_default bool? Ubuntu 14.04

dgilland commented 6 years ago

Thanks for the bug report!

Released new version, 0.10.2, with the fix: https://pypi.org/project/cacheout/0.10.2/