Total Complexity | 5 |
Total Lines | 47 |
Duplicated Lines | 0 % |
Changes | 0 |
1 | """ |
||
2 | PRIVATE MODULE: do not import (from) it directly. |
||
3 | |||
4 | This module contains functionality for caching functions. |
||
5 | """ |
||
6 | from collections import deque |
||
7 | from functools import lru_cache, update_wrapper |
||
8 | from typing import Callable |
||
9 | |||
10 | |||
11 | class _Wrapper: |
||
12 | """ |
||
13 | A wrapper around a function that needs to be cached. This wrapper allows |
||
14 | for a single point from which cache can be cleared. |
||
15 | """ |
||
16 | instances = deque([]) |
||
17 | |||
18 | def __init__(self, wrapped): |
||
19 | self.wrapped = wrapped |
||
20 | self.instances.append(self) |
||
21 | |||
22 | @lru_cache(typed=True) |
||
23 | def __call__(self, *args, **kwargs): |
||
24 | return self.wrapped(*args, **kwargs) |
||
25 | |||
26 | |||
27 | def cached(decorated: Callable): |
||
28 | """ |
||
29 | Alternative for ``functools.lru_cache``. By decorating a function with |
||
30 | ``cached``, you can clear the cache of that function by calling |
||
31 | ``clear()``. |
||
32 | :param decorated: the decorated function. |
||
33 | :return: a wrapped function. |
||
34 | """ |
||
35 | wrapper = _Wrapper(decorated) |
||
36 | update_wrapper(wrapper=wrapper, wrapped=decorated) |
||
37 | return wrapper |
||
38 | |||
39 | |||
40 | def clear(): |
||
41 | """ |
||
42 | Clear all cache of functions that were cached using ``cached``. |
||
43 | :return: None. |
||
44 | """ |
||
45 | for w in _Wrapper.instances: |
||
46 | w.__call__.cache_clear() |
||
47 |