robotcode-robot 2.1.0__tar.gz → 2.2.0__tar.gz

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.
Files changed (33) hide show
  1. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/PKG-INFO +1 -1
  2. robotcode_robot-2.2.0/src/robotcode/robot/__version__.py +1 -0
  3. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/document_cache_helper.py +43 -17
  4. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/entities.py +40 -116
  5. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/keyword_finder.py +2 -1
  6. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/library_doc.py +35 -47
  7. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/namespace.py +48 -35
  8. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/namespace_analyzer.py +1 -1
  9. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/utils/match.py +2 -2
  10. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/utils/variables.py +5 -5
  11. robotcode_robot-2.1.0/src/robotcode/robot/__version__.py +0 -1
  12. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/.gitignore +0 -0
  13. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/README.md +0 -0
  14. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/pyproject.toml +0 -0
  15. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/__init__.py +0 -0
  16. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/config/__init__.py +0 -0
  17. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/config/loader.py +0 -0
  18. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/config/model.py +0 -0
  19. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/config/utils.py +0 -0
  20. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/__init__.py +0 -0
  21. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/data_cache.py +0 -0
  22. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/diagnostics_modifier.py +0 -0
  23. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/errors.py +0 -0
  24. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/imports_manager.py +0 -0
  25. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/model_helper.py +0 -0
  26. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/diagnostics/workspace_config.py +0 -0
  27. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/py.typed +0 -0
  28. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/utils/__init__.py +0 -0
  29. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/utils/ast.py +0 -0
  30. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/utils/markdownformatter.py +0 -0
  31. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/utils/robot_path.py +0 -0
  32. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/utils/stubs.py +0 -0
  33. {robotcode_robot-2.1.0 → robotcode_robot-2.2.0}/src/robotcode/robot/utils/visitor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotcode-robot
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: Support classes for RobotCode for handling Robot Framework projects.
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -0,0 +1 @@
1
+ __version__ = "2.2.0"
@@ -173,8 +173,8 @@ class DocumentsCacheHelper:
173
173
 
174
174
  def get_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
175
175
  if data_only:
176
- return document.get_cache(self.__get_tokens_data_only)
177
- return document.get_cache(self.__get_tokens)
176
+ return self.__get_tokens_data_only(document)
177
+ return self.__get_tokens(document)
178
178
 
179
179
  def __get_tokens_data_only(self, document: TextDocument) -> List[Token]:
180
180
  document_type = self.get_document_type(document)
@@ -199,6 +199,12 @@ class DocumentsCacheHelper:
199
199
  raise UnknownFileTypeError(str(document.uri))
200
200
 
201
201
  def get_general_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
202
+ if document.version is None:
203
+ if data_only:
204
+ return self.__get_general_tokens_data_only(document)
205
+
206
+ return self.__get_general_tokens(document)
207
+
202
208
  if data_only:
203
209
  return document.get_cache(self.__get_general_tokens_data_only)
204
210
  return document.get_cache(self.__get_general_tokens)
@@ -282,6 +288,12 @@ class DocumentsCacheHelper:
282
288
  return get(document.text())
283
289
 
284
290
  def get_resource_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
291
+ if document.version is None:
292
+ if data_only:
293
+ return self.__get_resource_tokens_data_only(document)
294
+
295
+ return self.__get_resource_tokens(document)
296
+
285
297
  if data_only:
286
298
  return document.get_cache(self.__get_resource_tokens_data_only)
287
299
 
@@ -306,6 +318,12 @@ class DocumentsCacheHelper:
306
318
  return self.__get_tokens_internal(document, get)
307
319
 
308
320
  def get_init_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
321
+ if document.version is None:
322
+ if data_only:
323
+ return self.__get_init_tokens_data_only(document)
324
+
325
+ return self.__get_init_tokens(document)
326
+
309
327
  if data_only:
310
328
  return document.get_cache(self.__get_init_tokens_data_only)
311
329
  return document.get_cache(self.__get_init_tokens)
@@ -363,11 +381,15 @@ class DocumentsCacheHelper:
363
381
  return cast(ast.AST, model)
364
382
 
365
383
  def get_general_model(self, document: TextDocument, data_only: bool = True) -> ast.AST:
384
+ if document.version is None:
385
+ if data_only:
386
+ return self.__get_general_model_data_only(document, self.get_general_tokens(document, True))
387
+
388
+ return self.__get_general_model(document, self.get_general_tokens(document))
389
+
366
390
  if data_only:
367
- return document.get_cache(
368
- self.__get_general_model_data_only,
369
- self.get_general_tokens(document, True),
370
- )
391
+ return document.get_cache(self.__get_general_model_data_only, self.get_general_tokens(document, True))
392
+
371
393
  return document.get_cache(self.__get_general_model, self.get_general_tokens(document))
372
394
 
373
395
  def __get_general_model_data_only(self, document: TextDocument, tokens: Iterable[Any]) -> ast.AST:
@@ -377,6 +399,12 @@ class DocumentsCacheHelper:
377
399
  return self.__get_model(document, tokens, DocumentType.GENERAL)
378
400
 
379
401
  def get_resource_model(self, document: TextDocument, data_only: bool = True) -> ast.AST:
402
+ if document.version is None:
403
+ if data_only:
404
+ return self.__get_resource_model_data_only(document, self.get_resource_tokens(document, True))
405
+
406
+ return self.__get_resource_model(document, self.get_resource_tokens(document))
407
+
380
408
  if data_only:
381
409
  return document.get_cache(
382
410
  self.__get_resource_model_data_only,
@@ -392,11 +420,15 @@ class DocumentsCacheHelper:
392
420
  return self.__get_model(document, tokens, DocumentType.RESOURCE)
393
421
 
394
422
  def get_init_model(self, document: TextDocument, data_only: bool = True) -> ast.AST:
423
+ if document.version is None:
424
+ if data_only:
425
+ return self.__get_init_model_data_only(document, self.get_init_tokens(document, True))
426
+
427
+ return self.__get_init_model(document, self.get_init_tokens(document))
428
+
395
429
  if data_only:
396
- return document.get_cache(
397
- self.__get_init_model_data_only,
398
- self.get_init_tokens(document, True),
399
- )
430
+ return document.get_cache(self.__get_init_model_data_only, self.get_init_tokens(document, True))
431
+
400
432
  return document.get_cache(self.__get_init_model, self.get_init_tokens(document))
401
433
 
402
434
  def __get_init_model_data_only(self, document: TextDocument, tokens: Iterable[Any]) -> ast.AST:
@@ -406,19 +438,14 @@ class DocumentsCacheHelper:
406
438
  return self.__get_model(document, tokens, DocumentType.INIT)
407
439
 
408
440
  def get_namespace(self, document: TextDocument) -> Namespace:
409
- return document.get_cache(self.__get_namespace)
410
-
411
- def __get_namespace(self, document: TextDocument) -> Namespace:
412
441
  document_type = self.get_document_type(document)
413
442
 
414
443
  if document_type == DocumentType.INIT:
415
444
  return self.get_init_namespace(document)
416
445
  if document_type == DocumentType.RESOURCE:
417
446
  return self.get_resource_namespace(document)
418
- if document_type == DocumentType.GENERAL:
419
- return self.get_general_namespace(document)
420
447
 
421
- return self.__get_namespace_for_document_type(document, document_type)
448
+ return self.get_general_namespace(document)
422
449
 
423
450
  def get_resource_namespace(self, document: TextDocument) -> Namespace:
424
451
  return document.get_cache(self.__get_resource_namespace)
@@ -450,7 +477,6 @@ class DocumentsCacheHelper:
450
477
  document.remove_cache_entry(self.__get_general_namespace)
451
478
  document.remove_cache_entry(self.__get_init_namespace)
452
479
  document.remove_cache_entry(self.__get_resource_namespace)
453
- document.remove_cache_entry(self.__get_namespace)
454
480
 
455
481
  self.namespace_invalidated(self, sender)
456
482
 
@@ -1,20 +1,13 @@
1
- import functools
2
1
  from dataclasses import dataclass, field
3
2
  from enum import Enum
4
3
  from typing import (
5
4
  TYPE_CHECKING,
6
5
  Any,
7
- Callable,
8
- Generic,
9
6
  List,
10
7
  Optional,
11
8
  Tuple,
12
- TypeVar,
13
- cast,
14
9
  )
15
10
 
16
- from typing_extensions import Concatenate, ParamSpec
17
-
18
11
  from robot.parsing.lexer.tokens import Token
19
12
  from robotcode.core.lsp.types import Position, Range
20
13
 
@@ -24,59 +17,8 @@ from ..utils.variables import VariableMatcher, search_variable
24
17
  if TYPE_CHECKING:
25
18
  from robotcode.robot.diagnostics.library_doc import KeywordDoc, LibraryDoc
26
19
 
27
- _F = TypeVar("_F", bound=Callable[..., Any])
28
-
29
-
30
- _NOT_SET = object()
31
-
32
-
33
- def single_call(func: _F) -> _F:
34
- name = f"__single_result_{func.__name__}__"
35
-
36
- def wrapper(self: Any, *args: Any, **kwargs: Any) -> Any:
37
- result = self.__dict__.get(name, _NOT_SET)
38
- if result is _NOT_SET:
39
- result = func(self, *args, **kwargs)
40
- self.__dict__[name] = result
41
- return result
42
-
43
- return cast(_F, wrapper)
44
-
45
-
46
- P = ParamSpec("P")
47
- R = TypeVar("R")
48
20
 
49
-
50
- class cached_method(Generic[P, R]): # noqa: N801
51
- def __init__(
52
- self, func: Optional[Callable[Concatenate[Any, P], R]] = None, *, maxsize: Optional[int] = None
53
- ) -> None:
54
- self.func: Optional[Callable[Concatenate[Any, P], R]] = func
55
- self._maxsize = maxsize
56
- self.cache_name: Optional[str] = None
57
- if func is not None:
58
- functools.update_wrapper(self, func)
59
-
60
- def __set_name__(self, owner: type, name: str) -> None:
61
- self.cache_name = f"__cached_{owner.__name__}_{name}"
62
-
63
- def __call__(self, func: Callable[Concatenate[Any, P], R]) -> "cached_method[P, R]":
64
- self.func = func
65
- functools.update_wrapper(self, func)
66
- return self
67
-
68
- def __get__(self, instance: Any, owner: Optional[type] = None) -> Callable[P, R]:
69
- cached = instance.__dict__.get(self.cache_name, _NOT_SET)
70
- if cached is _NOT_SET:
71
- assert self.func is not None
72
-
73
- bound_method = self.func.__get__(instance, owner)
74
- cached = functools.lru_cache(maxsize=self._maxsize)(bound_method)
75
- instance.__dict__[self.cache_name] = cached
76
- return cast(Callable[P, R], cached)
77
-
78
-
79
- @dataclass
21
+ @dataclass(slots=True)
80
22
  class SourceEntity:
81
23
  line_no: int
82
24
  col_offset: int
@@ -91,7 +33,6 @@ class SourceEntity:
91
33
  end=Position(line=self.end_line_no - 1, character=self.end_col_offset),
92
34
  )
93
35
 
94
- @single_call
95
36
  def __hash__(self) -> int:
96
37
  return hash(
97
38
  (
@@ -104,7 +45,7 @@ class SourceEntity:
104
45
  )
105
46
 
106
47
 
107
- @dataclass
48
+ @dataclass(slots=True)
108
49
  class Import(SourceEntity):
109
50
  name: Optional[str]
110
51
  name_token: Optional[Token]
@@ -123,7 +64,7 @@ class Import(SourceEntity):
123
64
  )
124
65
 
125
66
 
126
- @dataclass
67
+ @dataclass(slots=True)
127
68
  class LibraryImport(Import):
128
69
  args: Tuple[str, ...] = ()
129
70
  alias: Optional[str] = None
@@ -142,23 +83,20 @@ class LibraryImport(Import):
142
83
  ),
143
84
  )
144
85
 
145
- @single_call
146
86
  def __hash__(self) -> int:
147
87
  return hash((type(self), self.name, self.args, self.alias))
148
88
 
149
89
 
150
- @dataclass
90
+ @dataclass(slots=True)
151
91
  class ResourceImport(Import):
152
- @single_call
153
92
  def __hash__(self) -> int:
154
93
  return hash((type(self), self.name))
155
94
 
156
95
 
157
- @dataclass
96
+ @dataclass(slots=True)
158
97
  class VariablesImport(Import):
159
98
  args: Tuple[str, ...] = ()
160
99
 
161
- @single_call
162
100
  def __hash__(self) -> int:
163
101
  return hash((type(self), self.name, self.args))
164
102
 
@@ -168,6 +106,7 @@ class VariableDefinitionType(Enum):
168
106
  LOCAL_VARIABLE = "local variable"
169
107
  TEST_VARIABLE = "test variable"
170
108
  ARGUMENT = "argument"
109
+ LIBRARY_ARGUMENT = "library argument"
171
110
  GLOBAL_VARIABLE = "global variable"
172
111
  COMMAND_LINE_VARIABLE = "global variable [command line]"
173
112
  BUILTIN_VARIABLE = "builtin variable"
@@ -176,7 +115,7 @@ class VariableDefinitionType(Enum):
176
115
  VARIABLE_NOT_FOUND = "variable not found"
177
116
 
178
117
 
179
- @dataclass
118
+ @dataclass(slots=True)
180
119
  class VariableDefinition(SourceEntity):
181
120
  name: str
182
121
  name_token: Optional[Token] # TODO: this is not needed anymore, but kept for compatibility
@@ -190,19 +129,18 @@ class VariableDefinition(SourceEntity):
190
129
  value_is_native: bool = field(default=False, compare=False)
191
130
  value_type: Optional[str] = field(default=None, compare=False)
192
131
 
193
- @functools.cached_property
132
+ @property
194
133
  def matcher(self) -> VariableMatcher:
195
134
  return search_variable(self.name)
196
135
 
197
- @functools.cached_property
136
+ @property
198
137
  def convertable_name(self) -> str:
199
138
  m = self.matcher
200
139
  value_type = f": {self.value_type}" if self.value_type else ""
201
140
  return f"{m.identifier}{{{m.base.strip()}{value_type}}}"
202
141
 
203
- @single_call
204
142
  def __hash__(self) -> int:
205
- return hash((type(self), self.name, self.type, self.range, self.source))
143
+ return hash((self.type, self.name, self.source, self.range))
206
144
 
207
145
  @property
208
146
  def name_range(self) -> Range:
@@ -219,80 +157,74 @@ class VariableDefinition(SourceEntity):
219
157
  )
220
158
 
221
159
 
222
- @dataclass
160
+ @dataclass(slots=True)
223
161
  class TestVariableDefinition(VariableDefinition):
224
162
  type: VariableDefinitionType = VariableDefinitionType.TEST_VARIABLE
225
163
 
226
- @single_call
227
164
  def __hash__(self) -> int:
228
- return hash((type(self), self.name, self.type, self.range, self.source))
165
+ return hash((self.type, self.name, self.source, self.range))
229
166
 
230
167
 
231
- @dataclass
168
+ @dataclass(slots=True)
232
169
  class LocalVariableDefinition(VariableDefinition):
233
170
  type: VariableDefinitionType = VariableDefinitionType.LOCAL_VARIABLE
234
171
 
235
- @single_call
236
172
  def __hash__(self) -> int:
237
- return hash((type(self), self.name, self.type, self.range, self.source))
173
+ return hash((self.type, self.name, self.source, self.range))
238
174
 
239
175
 
240
- @dataclass
176
+ @dataclass(slots=True)
241
177
  class GlobalVariableDefinition(VariableDefinition):
242
178
  type: VariableDefinitionType = VariableDefinitionType.GLOBAL_VARIABLE
243
179
 
244
- @single_call
245
180
  def __hash__(self) -> int:
246
- return hash((type(self), self.name, self.type, self.range, self.source))
181
+ return hash((self.type, self.name, self.source, self.range))
247
182
 
248
183
 
249
- @dataclass
184
+ @dataclass(slots=True)
250
185
  class BuiltInVariableDefinition(GlobalVariableDefinition):
251
186
  type: VariableDefinitionType = VariableDefinitionType.BUILTIN_VARIABLE
252
187
  resolvable: bool = True
253
188
 
254
- @single_call
255
189
  def __hash__(self) -> int:
256
- return hash((type(self), self.name, self.type, None, None))
190
+ return hash((self.type, self.name, self.source, self.range))
257
191
 
258
192
 
259
- @dataclass
193
+ @dataclass(slots=True)
260
194
  class CommandLineVariableDefinition(GlobalVariableDefinition):
261
195
  type: VariableDefinitionType = VariableDefinitionType.COMMAND_LINE_VARIABLE
262
196
  resolvable: bool = True
263
197
 
264
- @single_call
265
198
  def __hash__(self) -> int:
266
- return hash((type(self), self.name, self.type, self.range, self.source))
199
+ return hash((self.type, self.name, self.source, self.range))
267
200
 
268
201
 
269
- @dataclass
202
+ @dataclass(slots=True)
270
203
  class ArgumentDefinition(LocalVariableDefinition):
271
204
  type: VariableDefinitionType = VariableDefinitionType.ARGUMENT
272
205
  keyword_doc: Optional["KeywordDoc"] = field(default=None, compare=False, metadata={"nosave": True})
273
206
 
274
- @single_call
275
207
  def __hash__(self) -> int:
276
- return hash((type(self), self.name, self.type, self.range, self.source))
208
+ return hash((self.type, self.name, self.source, self.range))
277
209
 
278
210
 
279
- @dataclass
211
+ @dataclass(slots=True)
280
212
  class EmbeddedArgumentDefinition(ArgumentDefinition):
281
213
  pattern: Optional[str] = field(default=None, compare=False)
282
214
 
283
- @single_call
284
215
  def __hash__(self) -> int:
285
- return hash((type(self), self.name, self.type, self.range, self.source))
216
+ return hash((self.type, self.name, self.source, self.range))
286
217
 
287
218
 
288
- @dataclass
219
+ @dataclass(slots=True)
289
220
  class LibraryArgumentDefinition(ArgumentDefinition):
290
- @single_call
221
+ type: VariableDefinitionType = VariableDefinitionType.LIBRARY_ARGUMENT
222
+
291
223
  def __hash__(self) -> int:
292
- return hash((type(self), self.name, self.type, self.range, self.source))
224
+ return hash((self.type, self.name, self.source, self.range))
293
225
 
294
226
 
295
- @dataclass(frozen=True, eq=False, repr=False)
227
+ @dataclass(slots=True, frozen=True, eq=False, repr=False)
296
228
  class NativeValue:
297
229
  value: Any
298
230
 
@@ -303,39 +235,36 @@ class NativeValue:
303
235
  return str(self.value)
304
236
 
305
237
 
306
- @dataclass
238
+ @dataclass(slots=True)
307
239
  class ImportedVariableDefinition(VariableDefinition):
308
240
  type: VariableDefinitionType = VariableDefinitionType.IMPORTED_VARIABLE
309
241
  value: Optional[NativeValue] = field(default=None, compare=False)
310
242
 
311
- @single_call
312
243
  def __hash__(self) -> int:
313
- return hash((type(self), self.name, self.type, self.source))
244
+ return hash((self.type, self.name, self.source, self.range))
314
245
 
315
246
 
316
- @dataclass
247
+ @dataclass(slots=True)
317
248
  class EnvironmentVariableDefinition(VariableDefinition):
318
249
  type: VariableDefinitionType = VariableDefinitionType.ENVIRONMENT_VARIABLE
319
250
  resolvable: bool = True
320
251
 
321
252
  default_value: Any = field(default=None, compare=False)
322
253
 
323
- @single_call
324
254
  def __hash__(self) -> int:
325
- return hash((type(self), self.name, self.type))
255
+ return hash((self.type, self.name, self.source, self.range))
326
256
 
327
257
 
328
- @dataclass
258
+ @dataclass(slots=True)
329
259
  class VariableNotFoundDefinition(VariableDefinition):
330
260
  type: VariableDefinitionType = VariableDefinitionType.VARIABLE_NOT_FOUND
331
261
  resolvable: bool = False
332
262
 
333
- @single_call
334
263
  def __hash__(self) -> int:
335
- return hash((type(self), self.name, self.type))
264
+ return hash((self.type, self.name, self.source, self.range))
336
265
 
337
266
 
338
- @dataclass
267
+ @dataclass(slots=True)
339
268
  class LibraryEntry:
340
269
  name: str
341
270
  import_name: str
@@ -354,7 +283,6 @@ class LibraryEntry:
354
283
  result += f" WITH NAME {self.alias}"
355
284
  return result
356
285
 
357
- @single_call
358
286
  def __hash__(self) -> int:
359
287
  return hash(
360
288
  (
@@ -370,12 +298,11 @@ class LibraryEntry:
370
298
  )
371
299
 
372
300
 
373
- @dataclass
301
+ @dataclass(slots=True)
374
302
  class ResourceEntry(LibraryEntry):
375
303
  imports: List[Import] = field(default_factory=list, compare=False)
376
304
  variables: List[VariableDefinition] = field(default_factory=list, compare=False)
377
305
 
378
- @single_call
379
306
  def __hash__(self) -> int:
380
307
  return hash(
381
308
  (
@@ -388,11 +315,10 @@ class ResourceEntry(LibraryEntry):
388
315
  )
389
316
 
390
317
 
391
- @dataclass
318
+ @dataclass(slots=True)
392
319
  class VariablesEntry(LibraryEntry):
393
320
  variables: List[ImportedVariableDefinition] = field(default_factory=list, compare=False)
394
321
 
395
- @single_call
396
322
  def __hash__(self) -> int:
397
323
  return hash(
398
324
  (
@@ -406,11 +332,10 @@ class VariablesEntry(LibraryEntry):
406
332
  )
407
333
 
408
334
 
409
- @dataclass
335
+ @dataclass(slots=True)
410
336
  class TestCaseDefinition(SourceEntity):
411
337
  name: str
412
338
 
413
- @single_call
414
339
  def __hash__(self) -> int:
415
340
  return hash(
416
341
  (
@@ -424,11 +349,10 @@ class TestCaseDefinition(SourceEntity):
424
349
  )
425
350
 
426
351
 
427
- @dataclass
352
+ @dataclass(slots=True)
428
353
  class TagDefinition(SourceEntity):
429
354
  name: str
430
355
 
431
- @single_call
432
356
  def __hash__(self) -> int:
433
357
  return hash(
434
358
  (
@@ -1,5 +1,6 @@
1
1
  import functools
2
2
  import re
3
+ import weakref
3
4
  from itertools import chain
4
5
  from typing import TYPE_CHECKING, Dict, Iterable, Iterator, List, NamedTuple, Optional, Sequence, Tuple
5
6
 
@@ -40,7 +41,7 @@ DEFAULT_BDD_PREFIXES = {"Given ", "When ", "Then ", "And ", "But "}
40
41
 
41
42
  class KeywordFinder:
42
43
  def __init__(self, namespace: "Namespace") -> None:
43
- self._namespace = namespace
44
+ self._namespace: "Namespace" = weakref.proxy(namespace)
44
45
 
45
46
  self.diagnostics: List[DiagnosticsEntry] = []
46
47
  self.result_bdd_prefix: Optional[str] = None
@@ -80,8 +80,6 @@ from .entities import (
80
80
  LibraryArgumentDefinition,
81
81
  NativeValue,
82
82
  SourceEntity,
83
- cached_method,
84
- single_call,
85
83
  )
86
84
 
87
85
  if get_robot_version() < (7, 0):
@@ -202,7 +200,7 @@ if get_robot_version() >= (6, 0):
202
200
  # monkey patch robot framework for performance reasons
203
201
  _old_from_name = EmbeddedArguments.from_name
204
202
 
205
- @functools.lru_cache(maxsize=8192)
203
+ @functools.lru_cache(maxsize=1024)
206
204
  def _new_from_name(name: str) -> EmbeddedArguments:
207
205
  return _old_from_name(name)
208
206
 
@@ -225,7 +223,7 @@ if get_robot_version() >= (6, 0):
225
223
 
226
224
  else:
227
225
 
228
- @functools.lru_cache(maxsize=8192)
226
+ @functools.lru_cache(maxsize=1024)
229
227
  def _get_embedded_arguments(name: str) -> Any:
230
228
  try:
231
229
  return EmbeddedArguments(name)
@@ -290,7 +288,6 @@ class KeywordMatcher:
290
288
 
291
289
  return self.normalized_name == (normalize_namespace(o) if self._is_namespace else normalize(o))
292
290
 
293
- @single_call
294
291
  def __hash__(self) -> int:
295
292
  return hash(
296
293
  (
@@ -329,20 +326,20 @@ class TypeDocType(Enum):
329
326
  STANDARD = "Standard"
330
327
 
331
328
 
332
- @dataclass
329
+ @dataclass(slots=True)
333
330
  class TypedDictItem:
334
331
  key: str
335
332
  type: str
336
333
  required: Optional[bool] = None
337
334
 
338
335
 
339
- @dataclass
336
+ @dataclass(slots=True)
340
337
  class EnumMember:
341
338
  name: str
342
339
  value: str
343
340
 
344
341
 
345
- @dataclass
342
+ @dataclass(slots=True)
346
343
  class TypeDoc:
347
344
  type: str
348
345
  name: str
@@ -356,7 +353,6 @@ class TypeDoc:
356
353
 
357
354
  doc_format: str = ROBOT_DOC_FORMAT
358
355
 
359
- @single_call
360
356
  def __hash__(self) -> int:
361
357
  return hash(
362
358
  (
@@ -369,7 +365,6 @@ class TypeDoc:
369
365
  )
370
366
  )
371
367
 
372
- @cached_method
373
368
  def to_markdown(self, header_level: int = 2, only_doc: bool = False) -> str:
374
369
  result = ""
375
370
 
@@ -406,13 +401,13 @@ class TypeDoc:
406
401
  return result
407
402
 
408
403
 
409
- @dataclass
404
+ @dataclass(slots=True)
410
405
  class SourceAndLineInfo:
411
406
  source: str
412
407
  line_no: int
413
408
 
414
409
 
415
- @dataclass
410
+ @dataclass(slots=True)
416
411
  class Error:
417
412
  message: str
418
413
  type_name: str
@@ -453,7 +448,7 @@ def robot_arg_repr(arg: Any) -> Optional[str]:
453
448
  return str(robot_arg.default_repr)
454
449
 
455
450
 
456
- @dataclass
451
+ @dataclass(slots=True)
457
452
  class ArgumentInfo:
458
453
  name: str
459
454
  str_repr: str
@@ -486,7 +481,6 @@ class ArgumentInfo:
486
481
  def __str__(self) -> str:
487
482
  return self.signature()
488
483
 
489
- @cached_method
490
484
  def signature(self, add_types: bool = True) -> str:
491
485
  prefix = ""
492
486
  if self.kind == KeywordArgumentKind.POSITIONAL_ONLY_MARKER:
@@ -519,7 +513,7 @@ class ArgumentInfo:
519
513
  DEPRECATED_PATTERN = re.compile(r"^\*DEPRECATED(?P<message>.*)\*(?P<doc>.*)")
520
514
 
521
515
 
522
- @dataclass
516
+ @dataclass(slots=True)
523
517
  class ArgumentSpec:
524
518
  name: Optional[str]
525
519
  type: str
@@ -560,7 +554,7 @@ class ArgumentSpec:
560
554
  ) -> Tuple[List[Any], List[Tuple[str, Any]]]:
561
555
  if not hasattr(self, "__robot_arguments"):
562
556
  if get_robot_version() < (7, 0):
563
- self.__robot_arguments = RobotArgumentSpec(
557
+ __robot_arguments = RobotArgumentSpec(
564
558
  self.name,
565
559
  self.type,
566
560
  self.positional_only,
@@ -572,7 +566,7 @@ class ArgumentSpec:
572
566
  None,
573
567
  )
574
568
  else:
575
- self.__robot_arguments = RobotArgumentSpec(
569
+ __robot_arguments = RobotArgumentSpec(
576
570
  self.name,
577
571
  self.type,
578
572
  self.positional_only,
@@ -584,18 +578,18 @@ class ArgumentSpec:
584
578
  self.embedded,
585
579
  None,
586
580
  )
587
- self.__robot_arguments.name = self.name
581
+ __robot_arguments.name = self.name
588
582
  if validate:
589
583
  if get_robot_version() < (7, 0):
590
584
  resolver = ArgumentResolver(
591
- self.__robot_arguments,
585
+ __robot_arguments,
592
586
  resolve_named=resolve_named,
593
587
  resolve_variables_until=resolve_variables_until,
594
588
  dict_to_kwargs=dict_to_kwargs,
595
589
  )
596
590
  else:
597
591
  resolver = ArgumentResolver(
598
- self.__robot_arguments,
592
+ __robot_arguments,
599
593
  resolve_named=resolve_named,
600
594
  resolve_args_until=resolve_variables_until,
601
595
  dict_to_kwargs=dict_to_kwargs,
@@ -609,18 +603,18 @@ class ArgumentSpec:
609
603
  def _raise_positional_after_named(self) -> None:
610
604
  pass
611
605
 
612
- positional, named = MyNamedArgumentResolver(self.__robot_arguments).resolve(arguments, variables)
606
+ positional, named = MyNamedArgumentResolver(__robot_arguments).resolve(arguments, variables)
613
607
  if get_robot_version() < (7, 0):
614
608
  positional, named = ArgumentsVariableReplacer(resolve_variables_until).replace(positional, named, variables)
615
609
  else:
616
- positional, named = ArgumentsVariableReplacer(self.__robot_arguments, resolve_variables_until).replace(
610
+ positional, named = ArgumentsVariableReplacer(__robot_arguments, resolve_variables_until).replace(
617
611
  positional, named, variables
618
612
  )
619
- positional, named = DictToKwargs(self.__robot_arguments, dict_to_kwargs).handle(positional, named)
613
+ positional, named = DictToKwargs(__robot_arguments, dict_to_kwargs).handle(positional, named)
620
614
  return positional, named
621
615
 
622
616
 
623
- @dataclass
617
+ @dataclass(slots=True)
624
618
  class KeywordDoc(SourceEntity):
625
619
  name: str = ""
626
620
  name_token: Optional[Token] = field(default=None, compare=False)
@@ -673,15 +667,15 @@ class KeywordDoc(SourceEntity):
673
667
  def __str__(self) -> str:
674
668
  return f"{self.name}({', '.join(str(arg) for arg in self.arguments)})"
675
669
 
676
- @functools.cached_property
670
+ @property
677
671
  def is_embedded(self) -> bool:
678
672
  return self.matcher.embedded_arguments is not None
679
673
 
680
- @functools.cached_property
674
+ @property
681
675
  def matcher(self) -> KeywordMatcher:
682
676
  return KeywordMatcher(self.name)
683
677
 
684
- @functools.cached_property
678
+ @property
685
679
  def is_deprecated(self) -> bool:
686
680
  return self.deprecated or DEPRECATED_PATTERN.match(self.doc) is not None
687
681
 
@@ -693,31 +687,31 @@ class KeywordDoc(SourceEntity):
693
687
  def is_library_keyword(self) -> bool:
694
688
  return self.libtype == "LIBRARY"
695
689
 
696
- @functools.cached_property
690
+ @property
697
691
  def deprecated_message(self) -> str:
698
692
  if (m := DEPRECATED_PATTERN.match(self.doc)) is not None:
699
693
  return m.group("message").strip()
700
694
  return ""
701
695
 
702
- @functools.cached_property
696
+ @property
703
697
  def name_range(self) -> Range:
704
698
  if self.name_token is not None:
705
699
  return range_from_token(self.name_token)
706
700
 
707
701
  return Range.invalid()
708
702
 
709
- @functools.cached_property
703
+ @property
710
704
  def normalized_tags(self) -> List[str]:
711
705
  return [normalize(tag) for tag in self.tags]
712
706
 
713
- @functools.cached_property
707
+ @property
714
708
  def is_private(self) -> bool:
715
709
  if get_robot_version() < (6, 0):
716
710
  return False
717
711
 
718
712
  return "robot:private" in self.normalized_tags
719
713
 
720
- @functools.cached_property
714
+ @property
721
715
  def range(self) -> Range:
722
716
  if self.name_token is not None:
723
717
  return range_from_token(self.name_token)
@@ -733,7 +727,6 @@ class KeywordDoc(SourceEntity):
733
727
  ),
734
728
  )
735
729
 
736
- @cached_method
737
730
  def to_markdown(
738
731
  self,
739
732
  add_signature: bool = True,
@@ -829,7 +822,7 @@ class KeywordDoc(SourceEntity):
829
822
 
830
823
  return result
831
824
 
832
- @functools.cached_property
825
+ @property
833
826
  def signature(self) -> str:
834
827
  return (
835
828
  f'({self.type}) "{self.name}": ('
@@ -845,7 +838,6 @@ class KeywordDoc(SourceEntity):
845
838
  + ")"
846
839
  )
847
840
 
848
- @cached_method
849
841
  def parameter_signature(self, full_signatures: Optional[Sequence[int]] = None) -> str:
850
842
  return (
851
843
  "("
@@ -889,7 +881,6 @@ class KeywordDoc(SourceEntity):
889
881
  def is_run_keywords(self) -> bool:
890
882
  return self.libname == BUILTIN_LIBRARY_NAME and self.name == RUN_KEYWORDS_NAME
891
883
 
892
- @single_call
893
884
  def __hash__(self) -> int:
894
885
  return hash(
895
886
  (
@@ -922,7 +913,7 @@ class KeywordError(Exception):
922
913
  self.multiple_keywords = multiple_keywords
923
914
 
924
915
 
925
- @dataclass
916
+ @dataclass(slots=True)
926
917
  class KeywordStore:
927
918
  source: Optional[str] = None
928
919
  source_type: Optional[str] = None
@@ -989,7 +980,7 @@ class KeywordStore:
989
980
  return (v for v in self.keywords if v.matcher.match_string(key))
990
981
 
991
982
 
992
- @dataclass
983
+ @dataclass(slots=True)
993
984
  class ModuleSpec:
994
985
  name: str
995
986
  origin: Optional[str]
@@ -1010,7 +1001,7 @@ RE_INLINE_LINK = re.compile(r"([\`])((?:\1|.)+?)\1", re.VERBOSE)
1010
1001
  RE_HEADERS = re.compile(r"^(#{2,9})\s+(\S.*)$", re.MULTILINE)
1011
1002
 
1012
1003
 
1013
- @dataclass
1004
+ @dataclass(slots=True)
1014
1005
  class LibraryDoc:
1015
1006
  name: str = ""
1016
1007
  doc: str = field(default="", compare=False)
@@ -1062,7 +1053,6 @@ class LibraryDoc:
1062
1053
  self._update_keywords(self._inits)
1063
1054
  self._update_keywords(self._keywords)
1064
1055
 
1065
- @single_call
1066
1056
  def __hash__(self) -> int:
1067
1057
  return hash(
1068
1058
  (
@@ -1108,7 +1098,6 @@ class LibraryDoc:
1108
1098
  ),
1109
1099
  )
1110
1100
 
1111
- @cached_method
1112
1101
  def to_markdown(
1113
1102
  self,
1114
1103
  add_signature: bool = True,
@@ -1258,21 +1247,20 @@ def var_repr(value: Any) -> str:
1258
1247
  return "${{ " + repr(value) + " }}"
1259
1248
 
1260
1249
 
1261
- @dataclass
1250
+ @dataclass(slots=True)
1262
1251
  class VariablesDoc(LibraryDoc):
1263
1252
  type: str = "VARIABLES"
1264
1253
  scope: str = "GLOBAL"
1265
1254
 
1266
1255
  variables: List[ImportedVariableDefinition] = field(default_factory=list)
1267
1256
 
1268
- @cached_method
1269
1257
  def to_markdown(
1270
1258
  self,
1271
1259
  add_signature: bool = True,
1272
1260
  only_doc: bool = True,
1273
1261
  header_level: int = 2,
1274
1262
  ) -> str:
1275
- result = super().to_markdown(add_signature, only_doc, header_level)
1263
+ result = super(VariablesDoc, self).to_markdown(add_signature, only_doc, header_level)
1276
1264
 
1277
1265
  if self.variables:
1278
1266
  result += "\n---\n\n"
@@ -1291,12 +1279,12 @@ class VariablesDoc(LibraryDoc):
1291
1279
  return result
1292
1280
 
1293
1281
 
1294
- @functools.lru_cache(maxsize=8192)
1282
+ @functools.lru_cache(maxsize=1024)
1295
1283
  def is_library_by_path(path: str) -> bool:
1296
1284
  return path.lower().endswith((".py", "/", os.sep))
1297
1285
 
1298
1286
 
1299
- @functools.lru_cache(maxsize=8192)
1287
+ @functools.lru_cache(maxsize=1024)
1300
1288
  def is_variables_by_path(path: str) -> bool:
1301
1289
  if get_robot_version() >= (6, 1):
1302
1290
  return path.lower().endswith((".py", ".yml", ".yaml", ".json", "/", os.sep))
@@ -1492,7 +1480,7 @@ def error_from_exception(
1492
1480
  )
1493
1481
 
1494
1482
 
1495
- @dataclass
1483
+ @dataclass(slots=True)
1496
1484
  class _Variable:
1497
1485
  name: str
1498
1486
  value: Iterable[str]
@@ -757,14 +757,14 @@ class Namespace:
757
757
  self._suite_variables: Optional[Dict[str, Any]] = None
758
758
  self._suite_variables_lock = RLock(default_timeout=120, name="Namespace.global_variables")
759
759
 
760
- self._diagnostics: List[Diagnostic] = []
761
- self._keyword_references: Dict[KeywordDoc, Set[Location]] = {}
762
- self._variable_references: Dict[VariableDefinition, Set[Location]] = {}
763
- self._local_variable_assignments: Dict[VariableDefinition, Set[Range]] = {}
764
- self._namespace_references: Dict[LibraryEntry, Set[Location]] = {}
760
+ self._diagnostics: Optional[List[Diagnostic]] = None
761
+ self._keyword_references: Optional[Dict[KeywordDoc, Set[Location]]] = None
762
+ self._variable_references: Optional[Dict[VariableDefinition, Set[Location]]] = None
763
+ self._local_variable_assignments: Optional[Dict[VariableDefinition, Set[Range]]] = None
764
+ self._namespace_references: Optional[Dict[LibraryEntry, Set[Location]]] = None
765
765
 
766
- self._test_case_definitions: List[TestCaseDefinition] = []
767
- self._tag_definitions: List[TagDefinition] = []
766
+ self._test_case_definitions: Optional[List[TestCaseDefinition]] = None
767
+ self._tag_definitions: Optional[List[TagDefinition]] = None
768
768
 
769
769
  self._imported_keywords: Optional[List[KeywordDoc]] = None
770
770
  self._imported_keywords_lock = RLock(default_timeout=120, name="Namespace.imported_keywords")
@@ -879,47 +879,53 @@ class Namespace:
879
879
 
880
880
  @_logger.call
881
881
  def get_diagnostics(self) -> List[Diagnostic]:
882
- self.ensure_initialized()
882
+ if self._diagnostics is None:
883
+ self.ensure_initialized()
883
884
 
884
- self.analyze()
885
+ self.analyze()
885
886
 
886
- return self._diagnostics
887
+ return self._diagnostics if self._diagnostics is not None else []
887
888
 
888
889
  @_logger.call
889
890
  def get_keyword_references(self) -> Dict[KeywordDoc, Set[Location]]:
890
- self.ensure_initialized()
891
+ if self._keyword_references is None:
892
+ self.ensure_initialized()
891
893
 
892
- self.analyze()
894
+ self.analyze()
893
895
 
894
- return self._keyword_references
896
+ return self._keyword_references if self._keyword_references is not None else {}
895
897
 
896
898
  def get_variable_references(self) -> Dict[VariableDefinition, Set[Location]]:
897
- self.ensure_initialized()
899
+ if self._variable_references is None:
900
+ self.ensure_initialized()
898
901
 
899
- self.analyze()
902
+ self.analyze()
900
903
 
901
- return self._variable_references
904
+ return self._variable_references if self._variable_references is not None else {}
902
905
 
903
906
  def get_testcase_definitions(self) -> List[TestCaseDefinition]:
904
- self.ensure_initialized()
907
+ if self._test_case_definitions is None:
908
+ self.ensure_initialized()
905
909
 
906
- self.analyze()
910
+ self.analyze()
907
911
 
908
- return self._test_case_definitions
912
+ return self._test_case_definitions if self._test_case_definitions is not None else []
909
913
 
910
914
  def get_local_variable_assignments(self) -> Dict[VariableDefinition, Set[Range]]:
911
- self.ensure_initialized()
915
+ if self._local_variable_assignments is None:
916
+ self.ensure_initialized()
912
917
 
913
- self.analyze()
918
+ self.analyze()
914
919
 
915
- return self._local_variable_assignments
920
+ return self._local_variable_assignments if self._local_variable_assignments is not None else {}
916
921
 
917
922
  def get_namespace_references(self) -> Dict[LibraryEntry, Set[Location]]:
918
- self.ensure_initialized()
923
+ if self._namespace_references is None:
924
+ self.ensure_initialized()
919
925
 
920
- self.analyze()
926
+ self.analyze()
921
927
 
922
- return self._namespace_references
928
+ return self._namespace_references if self._namespace_references is not None else {}
923
929
 
924
930
  def get_import_entries(self) -> Dict[Import, LibraryEntry]:
925
931
  self.ensure_initialized()
@@ -1182,7 +1188,6 @@ class Namespace:
1182
1188
  ) -> Dict[VariableMatcher, VariableDefinition]:
1183
1189
  self.ensure_initialized()
1184
1190
 
1185
- # return {m: v for m, v in self.yield_variables(nodes, position)}
1186
1191
  l = list(self.yield_variables(nodes, position))
1187
1192
  return dict(reversed(l))
1188
1193
 
@@ -1926,6 +1931,9 @@ class Namespace:
1926
1931
  related_information: Optional[List[DiagnosticRelatedInformation]] = None,
1927
1932
  data: Optional[Any] = None,
1928
1933
  ) -> None:
1934
+ if self._diagnostics is None:
1935
+ self._diagnostics = []
1936
+
1929
1937
  self._diagnostics.append(
1930
1938
  Diagnostic(
1931
1939
  range,
@@ -1953,16 +1961,20 @@ class Namespace:
1953
1961
  self.ensure_initialized()
1954
1962
 
1955
1963
  with self._logger.measure_time(lambda: f"analyzing document {self.source}", context_name="analyze"):
1956
- try:
1957
- result = NamespaceAnalyzer(self.model, self, self.create_finder()).run()
1964
+ analyzer = NamespaceAnalyzer(self.model, self, self.create_finder())
1958
1965
 
1959
- self._diagnostics += result.diagnostics
1960
- self._keyword_references = result.keyword_references
1961
- self._variable_references = result.variable_references
1962
- self._local_variable_assignments = result.local_variable_assignments
1963
- self._namespace_references = result.namespace_references
1964
- self._test_case_definitions = result.test_case_definitions
1965
- self._tag_definitions = result.tag_definitions
1966
+ try:
1967
+ analyzer_result = analyzer.run()
1968
+
1969
+ if self._diagnostics is None:
1970
+ self._diagnostics = []
1971
+ self._diagnostics += analyzer_result.diagnostics
1972
+ self._keyword_references = analyzer_result.keyword_references
1973
+ self._variable_references = analyzer_result.variable_references
1974
+ self._local_variable_assignments = analyzer_result.local_variable_assignments
1975
+ self._namespace_references = analyzer_result.namespace_references
1976
+ self._test_case_definitions = analyzer_result.test_case_definitions
1977
+ self._tag_definitions = analyzer_result.tag_definitions
1966
1978
 
1967
1979
  lib_doc = self.get_library_doc()
1968
1980
 
@@ -1989,6 +2001,7 @@ class Namespace:
1989
2001
  self._logger.debug("analyzing canceled")
1990
2002
  raise
1991
2003
  finally:
2004
+ del analyzer
1992
2005
  self._analyzed = not canceled
1993
2006
 
1994
2007
  self.has_analysed(self)
@@ -93,7 +93,7 @@ else:
93
93
  from robot.variables.search import VariableMatches
94
94
 
95
95
 
96
- @dataclass
96
+ @dataclass(slots=True, frozen=True)
97
97
  class AnalyzerResult:
98
98
  diagnostics: List[Diagnostic]
99
99
  keyword_references: Dict[KeywordDoc, Set[Location]]
@@ -5,12 +5,12 @@ _transform_table = str.maketrans("", "", "_ ")
5
5
  _transform_table_namespace = str.maketrans("", "", " ")
6
6
 
7
7
 
8
- @lru_cache(maxsize=8192)
8
+ @lru_cache(maxsize=1024)
9
9
  def normalize(text: str) -> str:
10
10
  return text.translate(_transform_table).casefold()
11
11
 
12
12
 
13
- @lru_cache(maxsize=8192)
13
+ @lru_cache(maxsize=1024)
14
14
  def normalize_namespace(text: str) -> str:
15
15
  return text.translate(_transform_table_namespace).casefold()
16
16
 
@@ -200,28 +200,28 @@ BUILTIN_VARIABLES = [
200
200
  ]
201
201
 
202
202
 
203
- @functools.lru_cache(maxsize=8192)
203
+ @functools.lru_cache(maxsize=1024)
204
204
  def contains_variable(string: str, identifiers: str = "$@&") -> bool:
205
205
  return cast(bool, robot_contains_variable(string, identifiers))
206
206
 
207
207
 
208
- @functools.lru_cache(maxsize=8192)
208
+ @functools.lru_cache(maxsize=1024)
209
209
  def is_scalar_assign(string: str, allow_assign_mark: bool = False) -> bool:
210
210
  return cast(bool, robot_is_scalar_assign(string, allow_assign_mark))
211
211
 
212
212
 
213
- @functools.lru_cache(maxsize=8192)
213
+ @functools.lru_cache(maxsize=1024)
214
214
  def is_variable(string: str, identifiers: str = "$@&") -> bool:
215
215
  return cast(bool, robot_is_variable(string, identifiers))
216
216
 
217
217
 
218
- @functools.lru_cache(maxsize=8192)
218
+ @functools.lru_cache(maxsize=1024)
219
219
  def search_variable(
220
220
  string: str, identifiers: str = "$@&%*", parse_type: bool = False, ignore_errors: bool = False
221
221
  ) -> VariableMatcher:
222
222
  return VariableMatcher(string, identifiers, parse_type, ignore_errors)
223
223
 
224
224
 
225
- @functools.lru_cache(maxsize=8192)
225
+ @functools.lru_cache(maxsize=1024)
226
226
  def split_from_equals(string: str) -> Tuple[str, Optional[str]]:
227
227
  return cast(Tuple[str, Optional[str]], robot_split_from_equals(string))
@@ -1 +0,0 @@
1
- __version__ = "2.1.0"