robotcode-robot 0.94.0__py3-none-any.whl → 0.95.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- robotcode/robot/__version__.py +1 -1
- robotcode/robot/diagnostics/data_cache.py +83 -0
- robotcode/robot/diagnostics/entities.py +3 -3
- robotcode/robot/diagnostics/errors.py +1 -1
- robotcode/robot/diagnostics/imports_manager.py +100 -99
- robotcode/robot/diagnostics/keyword_finder.py +69 -43
- robotcode/robot/diagnostics/library_doc.py +197 -151
- robotcode/robot/diagnostics/model_helper.py +10 -6
- robotcode/robot/diagnostics/namespace.py +17 -28
- robotcode/robot/diagnostics/namespace_analyzer.py +120 -43
- robotcode/robot/utils/ast.py +0 -7
- robotcode/robot/utils/match.py +2 -2
- robotcode/robot/utils/robot_path.py +15 -16
- robotcode/robot/utils/stubs.py +1 -19
- robotcode/robot/utils/variables.py +35 -0
- robotcode/robot/utils/visitor.py +0 -27
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.1.dist-info}/METADATA +2 -2
- robotcode_robot-0.95.1.dist-info/RECORD +32 -0
- robotcode_robot-0.94.0.dist-info/RECORD +0 -31
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.1.dist-info}/WHEEL +0 -0
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.1.dist-info}/licenses/LICENSE.txt +0 -0
robotcode/robot/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.
|
1
|
+
__version__ = "0.95.1"
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import pickle
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from enum import Enum
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import Any, Tuple, Type, TypeVar, Union, cast
|
6
|
+
|
7
|
+
from robotcode.core.utils.dataclasses import as_json, from_json
|
8
|
+
|
9
|
+
_T = TypeVar("_T")
|
10
|
+
|
11
|
+
|
12
|
+
class CacheSection(Enum):
|
13
|
+
LIBRARY = "libdoc"
|
14
|
+
VARIABLES = "variables"
|
15
|
+
|
16
|
+
|
17
|
+
class DataCache(ABC):
|
18
|
+
@abstractmethod
|
19
|
+
def cache_data_exists(self, section: CacheSection, entry_name: str) -> bool: ...
|
20
|
+
|
21
|
+
@abstractmethod
|
22
|
+
def read_cache_data(
|
23
|
+
self, section: CacheSection, entry_name: str, types: Union[Type[_T], Tuple[Type[_T], ...]]
|
24
|
+
) -> _T: ...
|
25
|
+
|
26
|
+
@abstractmethod
|
27
|
+
def save_cache_data(self, section: CacheSection, entry_name: str, data: Any) -> None: ...
|
28
|
+
|
29
|
+
|
30
|
+
class JsonDataCache(DataCache):
|
31
|
+
def __init__(self, cache_dir: Path) -> None:
|
32
|
+
self.cache_dir = cache_dir
|
33
|
+
|
34
|
+
def build_cache_data_filename(self, section: CacheSection, entry_name: str) -> Path:
|
35
|
+
return self.cache_dir / section.value / (entry_name + ".json")
|
36
|
+
|
37
|
+
def cache_data_exists(self, section: CacheSection, entry_name: str) -> bool:
|
38
|
+
cache_file = self.build_cache_data_filename(section, entry_name)
|
39
|
+
return cache_file.exists()
|
40
|
+
|
41
|
+
def read_cache_data(
|
42
|
+
self, section: CacheSection, entry_name: str, types: Union[Type[_T], Tuple[Type[_T], ...]]
|
43
|
+
) -> _T:
|
44
|
+
cache_file = self.build_cache_data_filename(section, entry_name)
|
45
|
+
return from_json(cache_file.read_text("utf-8"), types)
|
46
|
+
|
47
|
+
def save_cache_data(self, section: CacheSection, entry_name: str, data: Any) -> None:
|
48
|
+
cached_file = self.build_cache_data_filename(section, entry_name)
|
49
|
+
|
50
|
+
cached_file.parent.mkdir(parents=True, exist_ok=True)
|
51
|
+
cached_file.write_text(as_json(data), "utf-8")
|
52
|
+
|
53
|
+
|
54
|
+
class PickleDataCache(DataCache):
|
55
|
+
def __init__(self, cache_dir: Path) -> None:
|
56
|
+
self.cache_dir = cache_dir
|
57
|
+
|
58
|
+
def build_cache_data_filename(self, section: CacheSection, entry_name: str) -> Path:
|
59
|
+
return self.cache_dir / section.value / (entry_name + ".pkl")
|
60
|
+
|
61
|
+
def cache_data_exists(self, section: CacheSection, entry_name: str) -> bool:
|
62
|
+
cache_file = self.build_cache_data_filename(section, entry_name)
|
63
|
+
return cache_file.exists()
|
64
|
+
|
65
|
+
def read_cache_data(
|
66
|
+
self, section: CacheSection, entry_name: str, types: Union[Type[_T], Tuple[Type[_T], ...]]
|
67
|
+
) -> _T:
|
68
|
+
cache_file = self.build_cache_data_filename(section, entry_name)
|
69
|
+
|
70
|
+
with cache_file.open("rb") as f:
|
71
|
+
result = pickle.load(f)
|
72
|
+
|
73
|
+
if isinstance(result, types):
|
74
|
+
return cast(_T, result)
|
75
|
+
|
76
|
+
raise TypeError(f"Expected {types} but got {type(result)}")
|
77
|
+
|
78
|
+
def save_cache_data(self, section: CacheSection, entry_name: str, data: Any) -> None:
|
79
|
+
cached_file = self.build_cache_data_filename(section, entry_name)
|
80
|
+
|
81
|
+
cached_file.parent.mkdir(parents=True, exist_ok=True)
|
82
|
+
with cached_file.open("wb") as f:
|
83
|
+
pickle.dump(data, f)
|
@@ -12,11 +12,11 @@ from typing import (
|
|
12
12
|
)
|
13
13
|
|
14
14
|
from robot.parsing.lexer.tokens import Token
|
15
|
-
from robot.variables.search import search_variable
|
16
15
|
from robotcode.core.lsp.types import Position, Range
|
17
16
|
from robotcode.robot.utils.match import normalize
|
18
17
|
|
19
18
|
from ..utils.ast import range_from_token
|
19
|
+
from ..utils.variables import search_variable
|
20
20
|
|
21
21
|
if TYPE_CHECKING:
|
22
22
|
from robotcode.robot.diagnostics.library_doc import KeywordDoc, LibraryDoc
|
@@ -145,10 +145,10 @@ class VariableMatcher:
|
|
145
145
|
self.normalized_name = str(normalize(self.base))
|
146
146
|
|
147
147
|
def __eq__(self, o: object) -> bool:
|
148
|
-
if
|
148
|
+
if type(o) is VariableMatcher:
|
149
149
|
return o.normalized_name == self.normalized_name
|
150
150
|
|
151
|
-
if
|
151
|
+
if type(o) is str:
|
152
152
|
match = search_variable(o, "$@&%", ignore_errors=True)
|
153
153
|
base = match.base
|
154
154
|
if base is None:
|
@@ -6,7 +6,7 @@ DIAGNOSTICS_SOURCE_NAME = "robotcode"
|
|
6
6
|
@final
|
7
7
|
class Error:
|
8
8
|
VARIABLE_NOT_FOUND = "VariableNotFound"
|
9
|
-
|
9
|
+
ENVIRONMENT_VARIABLE_NOT_FOUND = "EnvironmentVariableNotFound"
|
10
10
|
KEYWORD_NOT_FOUND = "KeywordNotFound"
|
11
11
|
LIBRARY_CONTAINS_NO_KEYWORDS = "LibraryContainsNoKeywords"
|
12
12
|
POSSIBLE_CIRCULAR_IMPORT = "PossibleCircularImport"
|
@@ -25,6 +25,7 @@ from typing import (
|
|
25
25
|
final,
|
26
26
|
)
|
27
27
|
|
28
|
+
from robot.libraries import STDLIBS
|
28
29
|
from robot.utils.text import split_args_from_name_or_path
|
29
30
|
from robotcode.core.concurrent import RLock, run_as_task
|
30
31
|
from robotcode.core.documents_manager import DocumentsManager
|
@@ -35,14 +36,16 @@ from robotcode.core.lsp.types import DocumentUri, FileChangeType, FileEvent
|
|
35
36
|
from robotcode.core.text_document import TextDocument
|
36
37
|
from robotcode.core.uri import Uri
|
37
38
|
from robotcode.core.utils.caching import SimpleLRUCache
|
38
|
-
from robotcode.core.utils.
|
39
|
-
from robotcode.core.utils.glob_path import Pattern, iter_files
|
39
|
+
from robotcode.core.utils.glob_path import Pattern
|
40
40
|
from robotcode.core.utils.logging import LoggingDescriptor
|
41
41
|
from robotcode.core.utils.path import normalized_path, path_is_relative_to
|
42
42
|
|
43
43
|
from ..__version__ import __version__
|
44
44
|
from ..utils import get_robot_version, get_robot_version_str
|
45
45
|
from ..utils.robot_path import find_file_ex
|
46
|
+
from ..utils.variables import contains_variable
|
47
|
+
from .data_cache import CacheSection
|
48
|
+
from .data_cache import PickleDataCache as DefaultDataCache
|
46
49
|
from .entities import (
|
47
50
|
CommandLineVariableDefinition,
|
48
51
|
VariableDefinition,
|
@@ -521,18 +524,10 @@ class ImportsManager:
|
|
521
524
|
self._logger.trace(lambda: f"use {cache_base_path} as base for caching")
|
522
525
|
|
523
526
|
self.cache_path = cache_base_path / ".robotcode_cache"
|
524
|
-
|
525
|
-
self.lib_doc_cache_path = (
|
526
|
-
self.cache_path
|
527
|
-
/ f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
528
|
-
/ get_robot_version_str()
|
529
|
-
/ "libdoc"
|
530
|
-
)
|
531
|
-
self.variables_doc_cache_path = (
|
527
|
+
self.data_cache = DefaultDataCache(
|
532
528
|
self.cache_path
|
533
529
|
/ f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
534
530
|
/ get_robot_version_str()
|
535
|
-
/ "variables"
|
536
531
|
)
|
537
532
|
|
538
533
|
self.cmd_variables = variables
|
@@ -564,9 +559,9 @@ class ImportsManager:
|
|
564
559
|
if environment:
|
565
560
|
self._environment.update(environment)
|
566
561
|
|
567
|
-
self._library_files_cache = SimpleLRUCache(
|
568
|
-
self._resource_files_cache = SimpleLRUCache(
|
569
|
-
self._variables_files_cache = SimpleLRUCache(
|
562
|
+
self._library_files_cache = SimpleLRUCache(2048)
|
563
|
+
self._resource_files_cache = SimpleLRUCache(2048)
|
564
|
+
self._variables_files_cache = SimpleLRUCache(2048)
|
570
565
|
|
571
566
|
self._executor_lock = RLock(default_timeout=120, name="ImportsManager._executor_lock")
|
572
567
|
self._executor: Optional[ProcessPoolExecutor] = None
|
@@ -582,6 +577,8 @@ class ImportsManager:
|
|
582
577
|
weakref.WeakKeyDictionary()
|
583
578
|
)
|
584
579
|
|
580
|
+
self._process_pool_executor: Optional[ProcessPoolExecutor] = None
|
581
|
+
|
585
582
|
def __del__(self) -> None:
|
586
583
|
try:
|
587
584
|
if self._executor is not None:
|
@@ -899,12 +896,14 @@ class ImportsManager:
|
|
899
896
|
)
|
900
897
|
|
901
898
|
if result is not None:
|
899
|
+
# TODO: use IgnoreSpec instead of this
|
902
900
|
ignore_arguments = any(
|
903
901
|
(p.matches(result.name) if result.name is not None else False)
|
904
902
|
or (p.matches(result.origin) if result.origin is not None else False)
|
905
903
|
for p in self.ignore_arguments_for_library_patters
|
906
904
|
)
|
907
905
|
|
906
|
+
# TODO: use IgnoreSpec instead of this
|
908
907
|
if any(
|
909
908
|
(p.matches(result.name) if result.name is not None else False)
|
910
909
|
or (p.matches(result.origin) if result.origin is not None else False)
|
@@ -918,16 +917,16 @@ class ImportsManager:
|
|
918
917
|
return None, import_name, ignore_arguments
|
919
918
|
|
920
919
|
if result.origin is not None:
|
921
|
-
result.mtimes = {result.origin:
|
920
|
+
result.mtimes = {result.origin: os.stat(result.origin, follow_symlinks=False).st_mtime_ns}
|
922
921
|
|
923
922
|
if result.submodule_search_locations:
|
924
923
|
if result.mtimes is None:
|
925
924
|
result.mtimes = {}
|
926
925
|
result.mtimes.update(
|
927
926
|
{
|
928
|
-
str(f):
|
927
|
+
str(f): os.stat(f, follow_symlinks=False).st_mtime_ns
|
929
928
|
for f in itertools.chain(
|
930
|
-
*(
|
929
|
+
*(Path(loc).rglob("**/*.py") for loc in result.submodule_search_locations)
|
931
930
|
)
|
932
931
|
}
|
933
932
|
)
|
@@ -987,16 +986,16 @@ class ImportsManager:
|
|
987
986
|
return None, import_name
|
988
987
|
|
989
988
|
if result.origin is not None:
|
990
|
-
result.mtimes = {result.origin:
|
989
|
+
result.mtimes = {result.origin: os.stat(result.origin, follow_symlinks=False).st_mtime_ns}
|
991
990
|
|
992
991
|
if result.submodule_search_locations:
|
993
992
|
if result.mtimes is None:
|
994
993
|
result.mtimes = {}
|
995
994
|
result.mtimes.update(
|
996
995
|
{
|
997
|
-
str(f):
|
996
|
+
str(f): os.stat(f, follow_symlinks=False).st_mtime_ns
|
998
997
|
for f in itertools.chain(
|
999
|
-
*(
|
998
|
+
*(Path(loc).rglob("**/*.py") for loc in result.submodule_search_locations)
|
1000
999
|
)
|
1001
1000
|
}
|
1002
1001
|
)
|
@@ -1015,7 +1014,10 @@ class ImportsManager:
|
|
1015
1014
|
base_dir: str,
|
1016
1015
|
variables: Optional[Dict[str, Any]] = None,
|
1017
1016
|
) -> str:
|
1018
|
-
|
1017
|
+
if contains_variable(name, "$@&%"):
|
1018
|
+
return self._library_files_cache.get(self._find_library, name, base_dir, variables)
|
1019
|
+
|
1020
|
+
return self._library_files_cache.get(self._find_library_simple, name, base_dir)
|
1019
1021
|
|
1020
1022
|
def _find_library(
|
1021
1023
|
self,
|
@@ -1023,17 +1025,19 @@ class ImportsManager:
|
|
1023
1025
|
base_dir: str,
|
1024
1026
|
variables: Optional[Dict[str, Any]] = None,
|
1025
1027
|
) -> str:
|
1026
|
-
|
1027
|
-
|
1028
|
+
return find_library(
|
1029
|
+
name,
|
1030
|
+
str(self.root_folder),
|
1031
|
+
base_dir,
|
1032
|
+
self.get_resolvable_command_line_variables(),
|
1033
|
+
variables,
|
1034
|
+
)
|
1028
1035
|
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
self.get_resolvable_command_line_variables(),
|
1035
|
-
variables,
|
1036
|
-
)
|
1036
|
+
def _find_library_simple(
|
1037
|
+
self,
|
1038
|
+
name: str,
|
1039
|
+
base_dir: str,
|
1040
|
+
) -> str:
|
1037
1041
|
|
1038
1042
|
if name in STDLIBS:
|
1039
1043
|
result = ROBOT_LIBRARY_PACKAGE + "." + name
|
@@ -1052,7 +1056,10 @@ class ImportsManager:
|
|
1052
1056
|
file_type: str = "Resource",
|
1053
1057
|
variables: Optional[Dict[str, Any]] = None,
|
1054
1058
|
) -> str:
|
1055
|
-
|
1059
|
+
if contains_variable(name, "$@&%"):
|
1060
|
+
return self._resource_files_cache.get(self.__find_resource, name, base_dir, file_type, variables)
|
1061
|
+
|
1062
|
+
return self._resource_files_cache.get(self.__find_resource_simple, name, base_dir, file_type)
|
1056
1063
|
|
1057
1064
|
@_logger.call
|
1058
1065
|
def __find_resource(
|
@@ -1062,64 +1069,71 @@ class ImportsManager:
|
|
1062
1069
|
file_type: str = "Resource",
|
1063
1070
|
variables: Optional[Dict[str, Any]] = None,
|
1064
1071
|
) -> str:
|
1065
|
-
|
1072
|
+
return find_file(
|
1073
|
+
name,
|
1074
|
+
str(self.root_folder),
|
1075
|
+
base_dir,
|
1076
|
+
self.get_resolvable_command_line_variables(),
|
1077
|
+
variables,
|
1078
|
+
file_type,
|
1079
|
+
)
|
1066
1080
|
|
1067
|
-
|
1068
|
-
|
1081
|
+
def __find_resource_simple(
|
1082
|
+
self,
|
1083
|
+
name: str,
|
1084
|
+
base_dir: str,
|
1085
|
+
file_type: str = "Resource",
|
1086
|
+
) -> str:
|
1087
|
+
return find_file_ex(name, base_dir, file_type)
|
1088
|
+
|
1089
|
+
def find_variables(
|
1090
|
+
self,
|
1091
|
+
name: str,
|
1092
|
+
base_dir: str,
|
1093
|
+
variables: Optional[Dict[str, Any]] = None,
|
1094
|
+
resolve_variables: bool = True,
|
1095
|
+
resolve_command_line_vars: bool = True,
|
1096
|
+
) -> str:
|
1097
|
+
if resolve_variables and contains_variable(name, "$@&%"):
|
1098
|
+
return self._variables_files_cache.get(
|
1099
|
+
self.__find_variables,
|
1069
1100
|
name,
|
1070
|
-
str(self.root_folder),
|
1071
1101
|
base_dir,
|
1072
|
-
self.get_resolvable_command_line_variables(),
|
1073
1102
|
variables,
|
1074
|
-
|
1103
|
+
resolve_command_line_vars,
|
1075
1104
|
)
|
1105
|
+
return self._variables_files_cache.get(self.__find_variables_simple, name, base_dir)
|
1076
1106
|
|
1077
|
-
|
1078
|
-
|
1079
|
-
def find_variables(
|
1107
|
+
@_logger.call
|
1108
|
+
def __find_variables(
|
1080
1109
|
self,
|
1081
1110
|
name: str,
|
1082
1111
|
base_dir: str,
|
1083
1112
|
variables: Optional[Dict[str, Any]] = None,
|
1084
|
-
resolve_variables: bool = True,
|
1085
1113
|
resolve_command_line_vars: bool = True,
|
1086
1114
|
) -> str:
|
1087
|
-
return
|
1088
|
-
self.__find_variables,
|
1115
|
+
return find_variables(
|
1089
1116
|
name,
|
1117
|
+
str(self.root_folder),
|
1090
1118
|
base_dir,
|
1119
|
+
self.get_resolvable_command_line_variables() if resolve_command_line_vars else None,
|
1091
1120
|
variables,
|
1092
|
-
resolve_variables,
|
1093
|
-
resolve_command_line_vars,
|
1094
1121
|
)
|
1095
1122
|
|
1096
1123
|
@_logger.call
|
1097
|
-
def
|
1124
|
+
def __find_variables_simple(
|
1098
1125
|
self,
|
1099
1126
|
name: str,
|
1100
1127
|
base_dir: str,
|
1101
|
-
variables: Optional[Dict[str, Any]] = None,
|
1102
|
-
resolve_variables: bool = True,
|
1103
|
-
resolve_command_line_vars: bool = True,
|
1104
1128
|
) -> str:
|
1105
|
-
from robot.variables.search import contains_variable
|
1106
|
-
|
1107
|
-
if resolve_variables and contains_variable(name, "$@&%"):
|
1108
|
-
return find_variables(
|
1109
|
-
name,
|
1110
|
-
str(self.root_folder),
|
1111
|
-
base_dir,
|
1112
|
-
self.get_resolvable_command_line_variables() if resolve_command_line_vars else None,
|
1113
|
-
variables,
|
1114
|
-
)
|
1115
1129
|
|
1116
1130
|
if get_robot_version() >= (5, 0):
|
1117
1131
|
if is_variables_by_path(name):
|
1118
|
-
return
|
1132
|
+
return find_file_ex(name, base_dir, "Variables")
|
1119
1133
|
|
1120
1134
|
return name
|
1121
1135
|
|
1122
|
-
return
|
1136
|
+
return find_file_ex(name, base_dir, "Variables")
|
1123
1137
|
|
1124
1138
|
@property
|
1125
1139
|
def executor(self) -> ProcessPoolExecutor:
|
@@ -1155,29 +1169,26 @@ class ImportsManager:
|
|
1155
1169
|
|
1156
1170
|
if meta is not None and not meta.has_errors:
|
1157
1171
|
|
1158
|
-
meta_file =
|
1159
|
-
if
|
1172
|
+
meta_file = meta.filepath_base + ".meta"
|
1173
|
+
if self.data_cache.cache_data_exists(CacheSection.LIBRARY, meta_file):
|
1160
1174
|
try:
|
1161
1175
|
spec_path = None
|
1162
1176
|
try:
|
1163
|
-
saved_meta =
|
1177
|
+
saved_meta = self.data_cache.read_cache_data(CacheSection.LIBRARY, meta_file, LibraryMetaData)
|
1164
1178
|
if saved_meta.has_errors:
|
1165
1179
|
self._logger.debug(
|
1166
|
-
lambda: "Saved library spec for {name}{args!r} is not used "
|
1180
|
+
lambda: f"Saved library spec for {name}{args!r} is not used "
|
1167
1181
|
"due to errors in meta data",
|
1168
1182
|
context_name="import",
|
1169
1183
|
)
|
1170
1184
|
|
1171
1185
|
if not saved_meta.has_errors and saved_meta == meta:
|
1172
|
-
spec_path =
|
1173
|
-
self.lib_doc_cache_path,
|
1174
|
-
meta.filepath_base + ".spec.json",
|
1175
|
-
)
|
1186
|
+
spec_path = meta.filepath_base + ".spec"
|
1176
1187
|
|
1177
1188
|
self._logger.debug(
|
1178
1189
|
lambda: f"Use cached library meta data for {name}", context_name="import"
|
1179
1190
|
)
|
1180
|
-
return
|
1191
|
+
return self.data_cache.read_cache_data(CacheSection.LIBRARY, spec_path, LibraryDoc)
|
1181
1192
|
|
1182
1193
|
except (SystemExit, KeyboardInterrupt):
|
1183
1194
|
raise
|
@@ -1191,6 +1202,9 @@ class ImportsManager:
|
|
1191
1202
|
self._logger.exception(e)
|
1192
1203
|
|
1193
1204
|
self._logger.debug(lambda: f"Load library in process {name}{args!r}", context_name="import")
|
1205
|
+
# if self._process_pool_executor is None:
|
1206
|
+
# self._process_pool_executor = ProcessPoolExecutor(max_workers=1, mp_context=mp.get_context("spawn"))
|
1207
|
+
# executor = self._process_pool_executor
|
1194
1208
|
executor = ProcessPoolExecutor(max_workers=1, mp_context=mp.get_context("spawn"))
|
1195
1209
|
try:
|
1196
1210
|
try:
|
@@ -1222,19 +1236,17 @@ class ImportsManager:
|
|
1222
1236
|
if meta is not None:
|
1223
1237
|
meta.has_errors = bool(result.errors)
|
1224
1238
|
|
1225
|
-
meta_file =
|
1226
|
-
spec_file =
|
1227
|
-
|
1228
|
-
spec_file.parent.mkdir(parents=True, exist_ok=True)
|
1239
|
+
meta_file = meta.filepath_base + ".meta"
|
1240
|
+
spec_file = meta.filepath_base + ".spec"
|
1229
1241
|
|
1230
1242
|
try:
|
1231
|
-
|
1243
|
+
self.data_cache.save_cache_data(CacheSection.LIBRARY, spec_file, result)
|
1232
1244
|
except (SystemExit, KeyboardInterrupt):
|
1233
1245
|
raise
|
1234
1246
|
except BaseException as e:
|
1235
1247
|
raise RuntimeError(f"Cannot write spec file for library '{name}' to '{spec_file}'") from e
|
1236
1248
|
|
1237
|
-
|
1249
|
+
self.data_cache.save_cache_data(CacheSection.LIBRARY, meta_file, meta)
|
1238
1250
|
else:
|
1239
1251
|
self._logger.debug(lambda: f"Skip caching library {name}{args!r}", context_name="import")
|
1240
1252
|
except (SystemExit, KeyboardInterrupt):
|
@@ -1351,21 +1363,17 @@ class ImportsManager:
|
|
1351
1363
|
)
|
1352
1364
|
|
1353
1365
|
if meta is not None:
|
1354
|
-
meta_file =
|
1355
|
-
|
1356
|
-
|
1357
|
-
)
|
1358
|
-
if meta_file.exists():
|
1366
|
+
meta_file = meta.filepath_base + ".meta"
|
1367
|
+
|
1368
|
+
if self.data_cache.cache_data_exists(CacheSection.VARIABLES, meta_file):
|
1359
1369
|
try:
|
1360
1370
|
spec_path = None
|
1361
1371
|
try:
|
1362
|
-
saved_meta =
|
1372
|
+
saved_meta = self.data_cache.read_cache_data(CacheSection.VARIABLES, meta_file, LibraryMetaData)
|
1363
1373
|
if saved_meta == meta:
|
1364
|
-
spec_path =
|
1365
|
-
|
1366
|
-
|
1367
|
-
)
|
1368
|
-
return from_json(spec_path.read_text("utf-8"), VariablesDoc)
|
1374
|
+
spec_path = meta.filepath_base + ".spec"
|
1375
|
+
|
1376
|
+
return self.data_cache.read_cache_data(CacheSection.VARIABLES, spec_path, VariablesDoc)
|
1369
1377
|
except (SystemExit, KeyboardInterrupt):
|
1370
1378
|
raise
|
1371
1379
|
except BaseException as e:
|
@@ -1406,23 +1414,16 @@ class ImportsManager:
|
|
1406
1414
|
|
1407
1415
|
try:
|
1408
1416
|
if meta is not None:
|
1409
|
-
meta_file =
|
1410
|
-
|
1411
|
-
meta.filepath_base + ".meta.json",
|
1412
|
-
)
|
1413
|
-
spec_file = Path(
|
1414
|
-
self.variables_doc_cache_path,
|
1415
|
-
meta.filepath_base + ".spec.json",
|
1416
|
-
)
|
1417
|
-
spec_file.parent.mkdir(parents=True, exist_ok=True)
|
1417
|
+
meta_file = meta.filepath_base + ".meta"
|
1418
|
+
spec_file = meta.filepath_base + ".spec"
|
1418
1419
|
|
1419
1420
|
try:
|
1420
|
-
|
1421
|
+
self.data_cache.save_cache_data(CacheSection.VARIABLES, spec_file, result)
|
1421
1422
|
except (SystemExit, KeyboardInterrupt):
|
1422
1423
|
raise
|
1423
1424
|
except BaseException as e:
|
1424
1425
|
raise RuntimeError(f"Cannot write spec file for variables '{name}' to '{spec_file}'") from e
|
1425
|
-
|
1426
|
+
self.data_cache.save_cache_data(CacheSection.VARIABLES, meta_file, meta)
|
1426
1427
|
else:
|
1427
1428
|
self._logger.debug(lambda: f"Skip caching variables {name}{args!r}", context_name="import")
|
1428
1429
|
except (SystemExit, KeyboardInterrupt):
|