robotcode-robot 0.82.1__py3-none-any.whl → 0.82.3__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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.1.dist-info → robotcode_robot-0.82.3.dist-info}/METADATA +2 -2
- {robotcode_robot-0.82.1.dist-info → robotcode_robot-0.82.3.dist-info}/RECORD +8 -8
- {robotcode_robot-0.82.1.dist-info → robotcode_robot-0.82.3.dist-info}/WHEEL +0 -0
- {robotcode_robot-0.82.1.dist-info → robotcode_robot-0.82.3.dist-info}/licenses/LICENSE.txt +0 -0
robotcode/robot/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.82.
|
1
|
+
__version__ = "0.82.3"
|
@@ -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, Setup, 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, Setup, 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.3
|
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.3
|
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=3x2wKMbffUEEJlJ3cDVbyt1M_iEH-TBgkPoWxClY4WU,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=dpaJximTWvCXvjJK1deP4SiTxxYq3r4Yid9Lf-Es8hI,91311
|
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.3.dist-info/METADATA,sha256=RtQ4bgd6YXdFY9N6vUiCN7adbqm8wP73A3tMkKe2JSY,2240
|
27
|
+
robotcode_robot-0.82.3.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
28
|
+
robotcode_robot-0.82.3.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
|
29
|
+
robotcode_robot-0.82.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|