]> crepu.dev Git - config.git/blame_incremental - djavu-asus/emacs/elpy/rpc-venv/lib/python3.11/site-packages/jedi/cache.py
Reorganización de directorios
[config.git] / djavu-asus / emacs / elpy / rpc-venv / lib / python3.11 / site-packages / jedi / cache.py
... / ...
CommitLineData
1"""
2This caching is very important for speed and memory optimizations. There's
3nothing really spectacular, just some decorators. The following cache types are
4available:
5
6- ``time_cache`` can be used to cache something for just a limited time span,
7 which can be useful if there's user interaction and the user cannot react
8 faster than a certain time.
9
10This module is one of the reasons why |jedi| is not thread-safe. As you can see
11there are global variables, which are holding the cache information. Some of
12these variables are being cleaned after every API usage.
13"""
14import time
15from functools import wraps
16from typing import Any, Dict, Tuple
17
18from jedi import settings
19from parso.cache import parser_cache
20
21_time_caches: Dict[str, Dict[Any, Tuple[float, Any]]] = {}
22
23
24def clear_time_caches(delete_all: bool = False) -> None:
25 """ Jedi caches many things, that should be completed after each completion
26 finishes.
27
28 :param delete_all: Deletes also the cache that is normally not deleted,
29 like parser cache, which is important for faster parsing.
30 """
31 global _time_caches
32
33 if delete_all:
34 for cache in _time_caches.values():
35 cache.clear()
36 parser_cache.clear()
37 else:
38 # normally just kill the expired entries, not all
39 for tc in _time_caches.values():
40 # check time_cache for expired entries
41 for key, (t, value) in list(tc.items()):
42 if t < time.time():
43 # delete expired entries
44 del tc[key]
45
46
47def signature_time_cache(time_add_setting):
48 """
49 This decorator works as follows: Call it with a setting and after that
50 use the function with a callable that returns the key.
51 But: This function is only called if the key is not available. After a
52 certain amount of time (`time_add_setting`) the cache is invalid.
53
54 If the given key is None, the function will not be cached.
55 """
56 def _temp(key_func):
57 dct = {}
58 _time_caches[time_add_setting] = dct
59
60 def wrapper(*args, **kwargs):
61 generator = key_func(*args, **kwargs)
62 key = next(generator)
63 try:
64 expiry, value = dct[key]
65 if expiry > time.time():
66 return value
67 except KeyError:
68 pass
69
70 value = next(generator)
71 time_add = getattr(settings, time_add_setting)
72 if key is not None:
73 dct[key] = time.time() + time_add, value
74 return value
75 return wrapper
76 return _temp
77
78
79def time_cache(seconds):
80 def decorator(func):
81 cache = {}
82
83 @wraps(func)
84 def wrapper(*args, **kwargs):
85 key = (args, frozenset(kwargs.items()))
86 try:
87 created, result = cache[key]
88 if time.time() < created + seconds:
89 return result
90 except KeyError:
91 pass
92 result = func(*args, **kwargs)
93 cache[key] = time.time(), result
94 return result
95
96 wrapper.clear_cache = lambda: cache.clear()
97 return wrapper
98
99 return decorator
100
101
102def memoize_method(method):
103 """A normal memoize function."""
104 @wraps(method)
105 def wrapper(self, *args, **kwargs):
106 cache_dict = self.__dict__.setdefault('_memoize_method_dct', {})
107 dct = cache_dict.setdefault(method, {})
108 key = (args, frozenset(kwargs.items()))
109 try:
110 return dct[key]
111 except KeyError:
112 result = method(self, *args, **kwargs)
113 dct[key] = result
114 return result
115 return wrapper