Python functools._make_key() Examples

The following are 9 code examples of functools._make_key(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module functools , or try the search function .
Example #1
Source File: test_async_utils.py    From paasta with Apache License 2.0 5 votes vote down vote up
def test_async_ttl_cache_dont_overwrite_new_cache_entry():
    """Make sure that we don't overwrite a new cache entry that was placed
    while we were waiting to handle the result of a previously cached future
    """
    range_continue_event = asyncio.Event()
    update_cache_event = asyncio.Event()
    return_values = iter(range(10))

    # Wait until awaiter has had a chance to get the in-flight future out of
    # the cache, then signal to the cache_updater to replace the cached future
    # before returning.  Because cache_updater is signalled first, it will
    # replace the previously cached future before async_ttl_cache decides
    # whether save the result of that future in the cache
    async def range_coroutine():
        await range_continue_event.wait()
        update_cache_event.set()
        return next(return_values)

    range_coroutine_future = asyncio.ensure_future(range_coroutine())
    cache_key = functools._make_key((), {}, typed=False)
    cache = {cache_key: (range_coroutine_future, float("Inf"))}

    cached_range_coroutine = async_ttl_cache(cache=cache, ttl=0)(range_coroutine)

    new_range_coroutine_future = asyncio.ensure_future(range_coroutine())

    async def awaiter():
        range_continue_event.set()
        await cached_range_coroutine()

    async def cache_updater():
        await update_cache_event.wait()
        cache[cache_key] = (new_range_coroutine_future, float("Inf"))

    await asyncio.gather(awaiter(), cache_updater())
    assert cache[cache_key] == (new_range_coroutine_future, float("Inf")) 
Example #2
Source File: test_async_utils.py    From paasta with Apache License 2.0 5 votes vote down vote up
def test_async_ttl_cache_recover_if_cache_entry_removed():
    """Ensure we handle the case where we encounter an exception in the cached
    future but another coroutine awaiting the same future ran first and alraedy
    deleted the cache entry"""
    range_continue_event = asyncio.Event()
    num_awaiters_awaiting = DataHolder(value=0)

    class TestException(Exception):
        pass

    async def range_coroutine():
        await range_continue_event.wait()
        raise TestException

    range_coroutine_future = asyncio.ensure_future(range_coroutine())
    cache_key = functools._make_key((), {}, typed=False)
    cache = {cache_key: (range_coroutine_future, float("Inf"))}

    cached_range_coroutine = async_ttl_cache(cache=cache, ttl=0)(range_coroutine)

    async def awaiter():
        num_awaiters_awaiting.value += 1
        if num_awaiters_awaiting.value == 2:
            range_continue_event.set()

        try:
            await cached_range_coroutine()
        except TestException:
            pass

    # should not raise a KeyError!
    await asyncio.gather(awaiter(), awaiter()) 
Example #3
Source File: caching.py    From easypy with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def __call__(self, func=None, *, validator=None):
        if validator and not func:
            return partial(self.__call__, validator=validator)

        validator = validator and kwargs_resilient(validator)

        @wraps(func)
        def inner(*args, **kwargs):
            key_kwargs = {k: v for k, v in kwargs.items() if k not in self.ignored_keywords}
            key = str(_make_key(
                (func.__module__, func.__qualname__,) + args, key_kwargs,
                typed=False, kwd_mark=("_KWD_MARK_",)))

            try:
                value = self.get(key)
            except KeyError:
                pass
            else:
                if not validator:
                    return value
                validated_value = validator(value, args=args, kwargs=kwargs)
                if validated_value:
                    self.set(key, validated_value)
                    return validated_value
                self.set(key, DELETED)
                return inner(*args, **kwargs)
            ret = func(*args, **kwargs)
            self.set(key, ret)
            return ret
        inner.clear_cache = self.clear
        return inner 
Example #4
Source File: caching.py    From easypy with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def locking_lru_cache(maxsize=128, typed=False):
    """
    DEPRECATED!

    An lru cache decorator with a lock, to prevent concurrent invocations and allow reusing from cache.

    :param maxsize: LRU cache maximum size, defaults to 128
    :type maxsize: number, optional
    :param typed: If typed is set to true, function arguments of different types will be cached separately. defaults to False.
    :type typed: bool, optional
    """

    def deco(func):
        caching_func = lru_cache(maxsize, typed)(func)
        func._main_lock = RLock()
        func._keyed_locks = defaultdict(RLock)

        @wraps(func)
        def inner(*args, **kwargs):
            key = _make_key(args, kwargs, typed=typed)
            with func._main_lock:
                key_lock = func._keyed_locks[key]
            with key_lock:
                return caching_func(*args, **kwargs)

        @wraps(caching_func.cache_clear)
        def clear():
            with func._main_lock:
                return caching_func.cache_clear()

        inner.cache_clear = clear
        return inner

    return deco 
Example #5
Source File: caching.py    From easypy with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def __init__(self, func, **kwargs):
        update_wrapper(self, func)  # this needs to be first to avoid overriding attributes we set
        super().__init__(func=func, cached=True)
        self.func = func
        self.kwargs = kwargs
        self.expiration = kwargs['expiration']
        self.typed = kwargs['typed']
        self.get_ts_func = kwargs['get_ts_func']
        self.log_recalculation = kwargs['log_recalculation']
        self.ignored_keywords = kwargs['ignored_keywords']

        if self.ignored_keywords:
            assert not kwargs['key_func'], "can't specify both `ignored_keywords` AND `key_func`"
            self.ignored_keywords = set(ilistify(self.ignored_keywords))

            def key_func(**kw):
                return tuple(v for k, v in sorted(kw.items()) if k not in self.ignored_keywords)
        else:
            key_func = kwargs['key_func']

        self.NOT_FOUND = object()
        self.NOT_CACHED = self.NOT_FOUND, 0

        self.cache = {}
        self.main_lock = RLock()
        self.keyed_locks = defaultdict(RLock)

        if key_func:
            sig = inspect.signature(func)

            def make_key(args, kwargs):
                bound = sig.bind(*args, **kwargs)
                _apply_defaults(bound)
                return kwargs_resilient(key_func)(**bound.arguments)
        else:
            def make_key(args, kwargs):
                return _make_key(args, kwargs, typed=self.typed)

        self.make_key = make_key 
Example #6
Source File: caching.py    From easypy with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def timecache(expiration=0, typed=False, get_ts_func=time.time, log_recalculation=False, ignored_keywords=None, key_func=None):
    """
    A thread-safe cache decorator with time expiration.

    :param expiration: if a positive number, set an expiration on the cache, defaults to 0
    :type expiration: number, optional
    :param typed: If typed is set to true, function arguments of different types will be cached separately, defaults to False
    :type typed: bool, optional
    :param get_ts_func: The function to be used in order to get the current time, defaults to time.time
    :type get_ts_func: callable, optional
    :param log_recalculation: Whether or not to log cache misses, defaults to False
    :type log_recalculation: bool, optional
    :param ignored_keywords: Arguments to ignore when caculating item key, defaults to None
    :type ignored_keywords: iterable, optional
    :param key_func: The function to use in order to create the item key, defaults to functools._make_key
    :type key_func: callable, optional
    """

    def deco(func):
        return _TimeCache(
            func=func,
            expiration=expiration,
            typed=typed,
            get_ts_func=get_ts_func,
            log_recalculation=log_recalculation,
            ignored_keywords=ignored_keywords,
            key_func=key_func)

    return deco 
Example #7
Source File: async_lru.py    From async_lru with MIT License 5 votes vote down vote up
def _cache_invalidate(wrapped, typed, *args, **kwargs):
    key = _make_key(args, kwargs, typed)

    exists = key in wrapped._cache

    if exists:
        wrapped._cache.pop(key)

    return exists 
Example #8
Source File: test_internals.py    From async_lru with MIT License 5 votes vote down vote up
def test_cache_invalidate_typed():
    wrapped = Wrapped()
    wrapped._cache = {}

    args = (1,)
    kwargs = {'1': 1}

    from_cache = _cache_invalidate(wrapped, True, *args, **kwargs)

    assert not from_cache

    key = _make_key(args, kwargs, True)

    wrapped._cache[key] = 0

    from_cache = _cache_invalidate(wrapped, True, *args, **kwargs)

    assert from_cache

    assert len(wrapped._cache) == 0

    wrapped._cache[key] = 0

    args = (1.0,)

    from_cache = _cache_invalidate(wrapped, True, *args, **kwargs)

    assert not from_cache

    wrapped._cache[key] = 1 
Example #9
Source File: test_internals.py    From async_lru with MIT License 5 votes vote down vote up
def test_cache_invalidate_not_typed():
    wrapped = Wrapped()
    wrapped._cache = {}

    args = (1,)
    kwargs = {'1': 1}

    from_cache = _cache_invalidate(wrapped, False, *args, **kwargs)

    assert not from_cache

    key = _make_key(args, kwargs, False)

    wrapped._cache[key] = 0

    from_cache = _cache_invalidate(wrapped, False, *args, **kwargs)

    assert from_cache

    assert len(wrapped._cache) == 0

    wrapped._cache[key] = 0

    args = (1.0,)

    from_cache = _cache_invalidate(wrapped, False, *args, **kwargs)

    assert from_cache

    assert len(wrapped._cache) == 0