robotcode-robot 0.82.0__py3-none-any.whl → 0.82.2__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/model_helper.py +6 -0
- robotcode/robot/diagnostics/namespace.py +96 -56
- robotcode/robot/diagnostics/namespace_analyzer.py +33 -3
- {robotcode_robot-0.82.0.dist-info → robotcode_robot-0.82.2.dist-info}/METADATA +2 -2
- {robotcode_robot-0.82.0.dist-info → robotcode_robot-0.82.2.dist-info}/RECORD +8 -8
- {robotcode_robot-0.82.0.dist-info → robotcode_robot-0.82.2.dist-info}/WHEEL +0 -0
- {robotcode_robot-0.82.0.dist-info → robotcode_robot-0.82.2.dist-info}/licenses/LICENSE.txt +0 -0
robotcode/robot/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.82.
|
1
|
+
__version__ = "0.82.2"
|
@@ -258,6 +258,7 @@ class ModelHelper:
|
|
258
258
|
nodes: Optional[List[ast.AST]],
|
259
259
|
position: Optional[Position] = None,
|
260
260
|
skip_commandline_variables: bool = False,
|
261
|
+
skip_local_variables: bool = False,
|
261
262
|
return_not_found: bool = False,
|
262
263
|
) -> Iterator[Tuple[Token, VariableDefinition]]:
|
263
264
|
variable_started = False
|
@@ -270,6 +271,7 @@ class ModelHelper:
|
|
270
271
|
nodes,
|
271
272
|
position,
|
272
273
|
skip_commandline_variables=skip_commandline_variables,
|
274
|
+
skip_local_variables=skip_local_variables,
|
273
275
|
ignore_error=True,
|
274
276
|
)
|
275
277
|
sub_token = Token(
|
@@ -376,6 +378,7 @@ class ModelHelper:
|
|
376
378
|
nodes: Optional[List[ast.AST]],
|
377
379
|
position: Optional[Position] = None,
|
378
380
|
skip_commandline_variables: bool = False,
|
381
|
+
skip_local_variables: bool = False,
|
379
382
|
return_not_found: bool = False,
|
380
383
|
) -> Iterator[Tuple[Token, VariableDefinition]]:
|
381
384
|
def is_number(name: str) -> bool:
|
@@ -405,6 +408,7 @@ class ModelHelper:
|
|
405
408
|
nodes,
|
406
409
|
position,
|
407
410
|
skip_commandline_variables=skip_commandline_variables,
|
411
|
+
skip_local_variables=skip_local_variables,
|
408
412
|
return_not_found=return_not_found,
|
409
413
|
):
|
410
414
|
yield v
|
@@ -461,6 +465,7 @@ class ModelHelper:
|
|
461
465
|
nodes,
|
462
466
|
position,
|
463
467
|
skip_commandline_variables=skip_commandline_variables,
|
468
|
+
skip_local_variables=skip_local_variables,
|
464
469
|
ignore_error=True,
|
465
470
|
)
|
466
471
|
if var is not None:
|
@@ -485,6 +490,7 @@ class ModelHelper:
|
|
485
490
|
nodes,
|
486
491
|
position,
|
487
492
|
skip_commandline_variables=skip_commandline_variables,
|
493
|
+
skip_local_variables=skip_local_variables,
|
488
494
|
ignore_error=True,
|
489
495
|
)
|
490
496
|
sub_sub_token = Token(
|
@@ -26,13 +26,8 @@ from typing import (
|
|
26
26
|
from robot.errors import VariableError
|
27
27
|
from robot.libraries import STDLIBS
|
28
28
|
from robot.parsing.lexer.tokens import Token
|
29
|
-
from robot.parsing.model.blocks import
|
30
|
-
|
31
|
-
SettingSection,
|
32
|
-
TestCase,
|
33
|
-
VariableSection,
|
34
|
-
)
|
35
|
-
from robot.parsing.model.statements import Arguments, Statement
|
29
|
+
from robot.parsing.model.blocks import Keyword, SettingSection, TestCase, VariableSection
|
30
|
+
from robot.parsing.model.statements import Arguments, Fixture, Statement, Timeout
|
36
31
|
from robot.parsing.model.statements import LibraryImport as RobotLibraryImport
|
37
32
|
from robot.parsing.model.statements import ResourceImport as RobotResourceImport
|
38
33
|
from robot.parsing.model.statements import (
|
@@ -182,7 +177,7 @@ class VariablesVisitor(Visitor):
|
|
182
177
|
)
|
183
178
|
|
184
179
|
|
185
|
-
class
|
180
|
+
class VariableVisitorBase(Visitor):
|
186
181
|
def __init__(
|
187
182
|
self,
|
188
183
|
namespace: "Namespace",
|
@@ -198,7 +193,79 @@ class BlockVariableVisitor(Visitor):
|
|
198
193
|
|
199
194
|
self._results: Dict[str, VariableDefinition] = {}
|
200
195
|
self.current_kw_doc: Optional[KeywordDoc] = None
|
196
|
+
self.current_kw: Optional[Keyword] = None
|
197
|
+
|
198
|
+
def get_variable_token(self, token: Token) -> Optional[Token]:
|
199
|
+
return next(
|
200
|
+
(
|
201
|
+
v
|
202
|
+
for v in itertools.dropwhile(
|
203
|
+
lambda t: t.type in Token.NON_DATA_TOKENS,
|
204
|
+
tokenize_variables(token, ignore_errors=True, extra_types={Token.VARIABLE}),
|
205
|
+
)
|
206
|
+
if v.type == Token.VARIABLE
|
207
|
+
),
|
208
|
+
None,
|
209
|
+
)
|
210
|
+
|
211
|
+
|
212
|
+
class ArgumentVisitor(VariableVisitorBase):
|
213
|
+
def __init__(
|
214
|
+
self,
|
215
|
+
namespace: "Namespace",
|
216
|
+
nodes: Optional[List[ast.AST]],
|
217
|
+
position: Optional[Position],
|
218
|
+
in_args: bool,
|
219
|
+
current_kw_doc: Optional[KeywordDoc],
|
220
|
+
) -> None:
|
221
|
+
super().__init__(namespace, nodes, position, in_args)
|
222
|
+
|
223
|
+
self.current_kw_doc: Optional[KeywordDoc] = current_kw_doc
|
224
|
+
|
225
|
+
def get(self, model: ast.AST) -> Dict[str, VariableDefinition]:
|
226
|
+
self._results = {}
|
227
|
+
|
228
|
+
self.visit(model)
|
229
|
+
|
230
|
+
return self._results
|
231
|
+
|
232
|
+
def visit_Arguments(self, node: Statement) -> None: # noqa: N802
|
233
|
+
args: List[str] = []
|
234
|
+
|
235
|
+
arguments = node.get_tokens(Token.ARGUMENT)
|
236
|
+
|
237
|
+
for argument_token in arguments:
|
238
|
+
try:
|
239
|
+
argument = self.get_variable_token(argument_token)
|
240
|
+
|
241
|
+
if argument is not None and argument.value != "@{}":
|
242
|
+
if (
|
243
|
+
self.in_args
|
244
|
+
and self.position is not None
|
245
|
+
and self.position in range_from_token(argument_token)
|
246
|
+
and self.position > range_from_token(argument).end
|
247
|
+
):
|
248
|
+
break
|
249
|
+
|
250
|
+
if argument.value not in args:
|
251
|
+
args.append(argument.value)
|
252
|
+
arg_def = ArgumentDefinition(
|
253
|
+
name=argument.value,
|
254
|
+
name_token=strip_variable_token(argument),
|
255
|
+
line_no=argument.lineno,
|
256
|
+
col_offset=argument.col_offset,
|
257
|
+
end_line_no=argument.lineno,
|
258
|
+
end_col_offset=argument.end_col_offset,
|
259
|
+
source=self.namespace.source,
|
260
|
+
keyword_doc=self.current_kw_doc,
|
261
|
+
)
|
262
|
+
self._results[argument.value] = arg_def
|
263
|
+
|
264
|
+
except VariableError:
|
265
|
+
pass
|
201
266
|
|
267
|
+
|
268
|
+
class OnlyArgumentsVisitor(VariableVisitorBase):
|
202
269
|
def get(self, model: ast.AST) -> List[VariableDefinition]:
|
203
270
|
self._results = {}
|
204
271
|
|
@@ -211,9 +278,11 @@ class BlockVariableVisitor(Visitor):
|
|
211
278
|
super().visit(node)
|
212
279
|
|
213
280
|
def visit_Keyword(self, node: ast.AST) -> None: # noqa: N802
|
281
|
+
self.current_kw = cast(Keyword, node)
|
214
282
|
try:
|
215
283
|
self.generic_visit(node)
|
216
284
|
finally:
|
285
|
+
self.current_kw = None
|
217
286
|
self.current_kw_doc = None
|
218
287
|
|
219
288
|
def visit_KeywordName(self, node: Statement) -> None: # noqa: N802
|
@@ -248,53 +317,15 @@ class BlockVariableVisitor(Visitor):
|
|
248
317
|
keyword_doc=self.current_kw_doc,
|
249
318
|
)
|
250
319
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
tokenize_variables(token, ignore_errors=True, extra_types={Token.VARIABLE}),
|
258
|
-
)
|
259
|
-
if v.type == Token.VARIABLE
|
260
|
-
),
|
261
|
-
None,
|
262
|
-
)
|
263
|
-
|
264
|
-
def visit_Arguments(self, node: Statement) -> None: # noqa: N802
|
265
|
-
args: List[str] = []
|
320
|
+
if self.current_kw is not None:
|
321
|
+
args = ArgumentVisitor(
|
322
|
+
self.namespace, self.nodes, self.position, self.in_args, self.current_kw_doc
|
323
|
+
).get(self.current_kw)
|
324
|
+
if args:
|
325
|
+
self._results.update(args)
|
266
326
|
|
267
|
-
arguments = node.get_tokens(Token.ARGUMENT)
|
268
327
|
|
269
|
-
|
270
|
-
try:
|
271
|
-
argument = self.get_variable_token(argument_token)
|
272
|
-
|
273
|
-
if argument is not None and argument.value != "@{}":
|
274
|
-
if (
|
275
|
-
self.in_args
|
276
|
-
and self.position is not None
|
277
|
-
and self.position in range_from_token(argument_token)
|
278
|
-
and self.position > range_from_token(argument).end
|
279
|
-
):
|
280
|
-
break
|
281
|
-
|
282
|
-
if argument.value not in args:
|
283
|
-
args.append(argument.value)
|
284
|
-
arg_def = ArgumentDefinition(
|
285
|
-
name=argument.value,
|
286
|
-
name_token=strip_variable_token(argument),
|
287
|
-
line_no=argument.lineno,
|
288
|
-
col_offset=argument.col_offset,
|
289
|
-
end_line_no=argument.lineno,
|
290
|
-
end_col_offset=argument.end_col_offset,
|
291
|
-
source=self.namespace.source,
|
292
|
-
keyword_doc=self.current_kw_doc,
|
293
|
-
)
|
294
|
-
self._results[argument.value] = arg_def
|
295
|
-
|
296
|
-
except VariableError:
|
297
|
-
pass
|
328
|
+
class BlockVariableVisitor(OnlyArgumentsVisitor):
|
298
329
|
|
299
330
|
def visit_ExceptHeader(self, node: Statement) -> None: # noqa: N802
|
300
331
|
variables = node.get_tokens(Token.VARIABLE)[:1]
|
@@ -990,10 +1021,12 @@ class Namespace:
|
|
990
1021
|
nodes: Optional[List[ast.AST]] = None,
|
991
1022
|
position: Optional[Position] = None,
|
992
1023
|
skip_commandline_variables: bool = False,
|
1024
|
+
skip_local_variables: bool = False,
|
993
1025
|
) -> Iterator[Tuple[VariableMatcher, VariableDefinition]]:
|
994
1026
|
yielded: Dict[VariableMatcher, VariableDefinition] = {}
|
995
1027
|
|
996
1028
|
test_or_keyword = None
|
1029
|
+
test_or_keyword_nodes = None
|
997
1030
|
|
998
1031
|
if nodes:
|
999
1032
|
test_or_keyword_nodes = list(
|
@@ -1004,18 +1037,23 @@ class Namespace:
|
|
1004
1037
|
)
|
1005
1038
|
test_or_keyword = test_or_keyword_nodes[0] if test_or_keyword_nodes else None
|
1006
1039
|
|
1040
|
+
in_args = isinstance(test_or_keyword_nodes[-1], Arguments) if test_or_keyword_nodes else False
|
1041
|
+
only_args = (
|
1042
|
+
isinstance(test_or_keyword_nodes[-1], (Arguments, Fixture, Timeout)) if test_or_keyword_nodes else False
|
1043
|
+
)
|
1044
|
+
|
1007
1045
|
for var in chain(
|
1008
1046
|
*[
|
1009
1047
|
(
|
1010
1048
|
(
|
1011
|
-
BlockVariableVisitor(
|
1049
|
+
(OnlyArgumentsVisitor if only_args else BlockVariableVisitor)(
|
1012
1050
|
self,
|
1013
1051
|
nodes,
|
1014
1052
|
position,
|
1015
|
-
|
1053
|
+
in_args,
|
1016
1054
|
).get(test_or_keyword)
|
1017
1055
|
)
|
1018
|
-
if test_or_keyword is not None
|
1056
|
+
if test_or_keyword is not None and not skip_local_variables
|
1019
1057
|
else []
|
1020
1058
|
)
|
1021
1059
|
],
|
@@ -1081,6 +1119,7 @@ class Namespace:
|
|
1081
1119
|
nodes: Optional[List[ast.AST]] = None,
|
1082
1120
|
position: Optional[Position] = None,
|
1083
1121
|
skip_commandline_variables: bool = False,
|
1122
|
+
skip_local_variables: bool = False,
|
1084
1123
|
ignore_error: bool = False,
|
1085
1124
|
) -> Optional[VariableDefinition]:
|
1086
1125
|
self.ensure_initialized()
|
@@ -1105,6 +1144,7 @@ class Namespace:
|
|
1105
1144
|
nodes,
|
1106
1145
|
position,
|
1107
1146
|
skip_commandline_variables=skip_commandline_variables,
|
1147
|
+
skip_local_variables=skip_local_variables,
|
1108
1148
|
):
|
1109
1149
|
if matcher == m:
|
1110
1150
|
return v
|
@@ -12,12 +12,14 @@ from robot.parsing.lexer.tokens import Token
|
|
12
12
|
from robot.parsing.model.blocks import Keyword, TestCase
|
13
13
|
from robot.parsing.model.statements import (
|
14
14
|
Arguments,
|
15
|
+
DefaultTags,
|
15
16
|
DocumentationOrMetadata,
|
16
17
|
Fixture,
|
17
18
|
KeywordCall,
|
18
19
|
LibraryImport,
|
19
20
|
ResourceImport,
|
20
21
|
Statement,
|
22
|
+
Tags,
|
21
23
|
Template,
|
22
24
|
TemplateArguments,
|
23
25
|
TestCaseName,
|
@@ -70,9 +72,35 @@ from .namespace import KeywordFinder, Namespace
|
|
70
72
|
|
71
73
|
if get_robot_version() < (7, 0):
|
72
74
|
from robot.variables.search import VariableIterator
|
75
|
+
|
76
|
+
VARIABLE_NOT_FOUND_HINT_TYPES: Tuple[Any, ...] = (
|
77
|
+
DocumentationOrMetadata,
|
78
|
+
TestCaseName,
|
79
|
+
Tags,
|
80
|
+
robot.parsing.model.statements.ForceTags,
|
81
|
+
DefaultTags,
|
82
|
+
)
|
83
|
+
|
84
|
+
IN_SETTING_TYPES: Tuple[Any, ...] = (
|
85
|
+
DocumentationOrMetadata,
|
86
|
+
Tags,
|
87
|
+
robot.parsing.model.statements.ForceTags,
|
88
|
+
DefaultTags,
|
89
|
+
Template,
|
90
|
+
)
|
73
91
|
else:
|
74
92
|
from robot.variables.search import VariableMatches
|
75
93
|
|
94
|
+
VARIABLE_NOT_FOUND_HINT_TYPES = (
|
95
|
+
DocumentationOrMetadata,
|
96
|
+
TestCaseName,
|
97
|
+
Tags,
|
98
|
+
robot.parsing.model.statements.TestTags,
|
99
|
+
DefaultTags,
|
100
|
+
)
|
101
|
+
|
102
|
+
IN_SETTING_TYPES = (DocumentationOrMetadata, Tags, robot.parsing.model.statements.TestTags, DefaultTags, Template)
|
103
|
+
|
76
104
|
|
77
105
|
@dataclass
|
78
106
|
class AnalyzerResult:
|
@@ -266,10 +294,10 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
266
294
|
|
267
295
|
self.node_stack.append(node)
|
268
296
|
try:
|
297
|
+
in_setting = isinstance(node, IN_SETTING_TYPES)
|
298
|
+
|
269
299
|
severity = (
|
270
|
-
DiagnosticSeverity.HINT
|
271
|
-
if isinstance(node, (DocumentationOrMetadata, TestCaseName))
|
272
|
-
else DiagnosticSeverity.ERROR
|
300
|
+
DiagnosticSeverity.HINT if isinstance(node, VARIABLE_NOT_FOUND_HINT_TYPES) else DiagnosticSeverity.ERROR
|
273
301
|
)
|
274
302
|
|
275
303
|
if isinstance(node, KeywordCall) and node.keyword:
|
@@ -295,6 +323,7 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
295
323
|
self.node_stack,
|
296
324
|
range_from_token(token).start,
|
297
325
|
skip_commandline_variables=False,
|
326
|
+
skip_local_variables=in_setting,
|
298
327
|
return_not_found=True,
|
299
328
|
):
|
300
329
|
if isinstance(var, VariableNotFoundDefinition):
|
@@ -380,6 +409,7 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
380
409
|
self.node_stack,
|
381
410
|
range_from_token(token).start,
|
382
411
|
skip_commandline_variables=False,
|
412
|
+
skip_local_variables=in_setting,
|
383
413
|
return_not_found=True,
|
384
414
|
):
|
385
415
|
if isinstance(var, VariableNotFoundDefinition):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: robotcode-robot
|
3
|
-
Version: 0.82.
|
3
|
+
Version: 0.82.2
|
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
|
@@ -26,7 +26,7 @@ Classifier: Topic :: Utilities
|
|
26
26
|
Classifier: Typing :: Typed
|
27
27
|
Requires-Python: >=3.8
|
28
28
|
Requires-Dist: platformdirs<4.2.0,>=3.2.0
|
29
|
-
Requires-Dist: robotcode-core==0.82.
|
29
|
+
Requires-Dist: robotcode-core==0.82.2
|
30
30
|
Requires-Dist: robotframework>=4.1.0
|
31
31
|
Requires-Dist: tomli>=1.1.0; python_version < '3.11'
|
32
32
|
Description-Content-Type: text/markdown
|
@@ -1,5 +1,5 @@
|
|
1
1
|
robotcode/robot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
robotcode/robot/__version__.py,sha256=
|
2
|
+
robotcode/robot/__version__.py,sha256=RTYfZgQQ2I7IHQ7CnMLKfzWJLJYwV_HoEeJ8bvw2WlY,23
|
3
3
|
robotcode/robot/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
|
4
4
|
robotcode/robot/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
robotcode/robot/config/loader.py,sha256=LpGqJAdysvVSZpccW-Il52xn9RMBBb9X94emlBY7zCc,6077
|
@@ -11,9 +11,9 @@ robotcode/robot/diagnostics/entities.py,sha256=CrjhLHHwKCCE3YI_dcjoZADJz1urm0VGb
|
|
11
11
|
robotcode/robot/diagnostics/errors.py,sha256=VavgWYuHoW5sTT16j2rl9hxMhWxBKNSFsNmHWPzARQQ,1413
|
12
12
|
robotcode/robot/diagnostics/imports_manager.py,sha256=qE__lm0Hsj3R0gUauXRmbWJPYihNjk3O-c5hcICGQjc,56251
|
13
13
|
robotcode/robot/diagnostics/library_doc.py,sha256=sLENYhMoq5IvYgd0jUhVpRkRTvY9IfTotlthLUUO0vY,97124
|
14
|
-
robotcode/robot/diagnostics/model_helper.py,sha256=
|
15
|
-
robotcode/robot/diagnostics/namespace.py,sha256=
|
16
|
-
robotcode/robot/diagnostics/namespace_analyzer.py,sha256=
|
14
|
+
robotcode/robot/diagnostics/model_helper.py,sha256=_5ixKKMrb-nY-uvV8_WjJ1rlNlz7gT7kHM5NYi_hjVg,30232
|
15
|
+
robotcode/robot/diagnostics/namespace.py,sha256=OlhhK1RH4ZFGXZEerFQIzye0ddAq8V-W0cCsxYg6tdc,91315
|
16
|
+
robotcode/robot/diagnostics/namespace_analyzer.py,sha256=PWZjpLdn-9GCpp4L4dKxVF2B1hxzSEdDzBNUw2Lp51A,50937
|
17
17
|
robotcode/robot/diagnostics/workspace_config.py,sha256=lWNq1KmGGJ9cHFNHn0QTCBHHzgz4AewTw0l-W4TKrj0,1803
|
18
18
|
robotcode/robot/utils/__init__.py,sha256=OjNPMn_XSnfaMCyKd8Kmq6vlRt6mIGlzW4qiiD3ykUg,447
|
19
19
|
robotcode/robot/utils/ast.py,sha256=N7PobxXjpPWwv6UBa-GBn5wn6RAsiRm8unP6UZt0P6M,10193
|
@@ -23,7 +23,7 @@ robotcode/robot/utils/robot_path.py,sha256=qKBh1cEnReBBLKkWu4gB9EzM-scAwE4xJc1m6
|
|
23
23
|
robotcode/robot/utils/stubs.py,sha256=6-DMI_CQVJHDgG13t-zINKGCRb_Q7MQPm0_AkfhAEvE,748
|
24
24
|
robotcode/robot/utils/variables.py,sha256=fEl8S37lb_mD4hn2MZRAlkiuLGBjAOeZVK0r2o2CfPw,742
|
25
25
|
robotcode/robot/utils/visitor.py,sha256=uYLqEhGPmzWKWI3SSrmCaYMwtKvNShvbiPZ4b3FavX8,3241
|
26
|
-
robotcode_robot-0.82.
|
27
|
-
robotcode_robot-0.82.
|
28
|
-
robotcode_robot-0.82.
|
29
|
-
robotcode_robot-0.82.
|
26
|
+
robotcode_robot-0.82.2.dist-info/METADATA,sha256=pRwfD5QyBb_O5ISAAeBTS_ERjDt3ksXL7ac5FqxT2cg,2240
|
27
|
+
robotcode_robot-0.82.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
28
|
+
robotcode_robot-0.82.2.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
|
29
|
+
robotcode_robot-0.82.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|