Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not mock time for TTLCache #477

Open
irusland opened this issue Nov 6, 2022 · 3 comments
Open

Does not mock time for TTLCache #477

irusland opened this issue Nov 6, 2022 · 3 comments

Comments

@irusland
Copy link

irusland commented Nov 6, 2022

Hey, I've recently encountered the problem with freezing the time in TTLCache

Steps to reproduce

import time
from datetime import timedelta

from cachetools import TTLCache
from freezegun import freeze_time

with freeze_time() as frozen_datetime:
    ttl = TTLCache(
        maxsize=10, ttl=1,
        # timer=time.monotonic,  # uncomment this to pass assertion
    )
    ttl.update({'1': 1})
    assert ttl.keys()
    frozen_datetime.tick(timedelta(seconds=10000))
    assert not ttl.keys()

The problem with that is when use reference as a function parameter it caches timer=time.monotonic in defaults so freeze gun does not override it

Is there a way to overcome this?

Ive come up with the solution as overriding the standard ttlcache like so

import time

from cachetools import TTLCache as TTLCacheBase


class TTLCache(TTLCacheBase):
    def __init__(self, maxsize, ttl, timer=None, getsizeof=None):
        if timer is None:
            timer = time.monotonic
        super().__init__(maxsize=maxsize, ttl=ttl, timer=timer, getsizeof=getsizeof)
@irusland irusland changed the title Does not mock time for Does not mock time for TTLCache Nov 6, 2022
@POD666
Copy link

POD666 commented Nov 17, 2022

Same:

In [1]: from freezegun import freeze_time
In [2]: from datetime import datetime, timedelta
In [3]: from cachetools.func import ttl_cache
In [4]: @ttl_cache(ttl=100)
   ...: def now():
   ...:     return datetime.now()
In [5]: import time
In [6]: timer = time.monotonic
In [7]: print(timer())
   ...: print(now())
   ...: with freeze_time(timedelta(days=4), tick=True):
   ...:     print(timer())
   ...:     print(now())
   ...:     print(timer())
61.09706311
2022-11-17 12:51:30.917532
1669027890.946961
2022-11-17 12:51:30.917532
1669027890.947039

@ylhan
Copy link

ylhan commented Sep 26, 2023

+1 I'm running into this too. It's making ttl_cache impossible to test elegantly.

@RonnyPfannschmidt
Copy link

to solve this cachetools would have to stop memoizing pre-patching time functions in the factories

https://github.com/tkem/cachetools/blob/d991ac71b4eb6394be5ec572b835434081393215/src/cachetools/func.py#L107

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants