robotcode-robot 1.0.2__tar.gz → 2.0.3__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.
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/.gitignore +4 -1
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/PKG-INFO +24 -8
- robotcode_robot-2.0.3/README.md +37 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/pyproject.toml +8 -7
- robotcode_robot-2.0.3/src/robotcode/robot/__version__.py +1 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/config/model.py +9 -12
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/data_cache.py +0 -1
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/document_cache_helper.py +5 -1
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/entities.py +20 -46
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/errors.py +2 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/imports_manager.py +70 -15
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/keyword_finder.py +43 -13
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/library_doc.py +24 -10
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/model_helper.py +4 -4
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/namespace.py +246 -203
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/namespace_analyzer.py +222 -135
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/workspace_config.py +3 -0
- robotcode_robot-2.0.3/src/robotcode/robot/utils/__init__.py +14 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/utils/ast.py +21 -19
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/utils/markdownformatter.py +3 -3
- robotcode_robot-2.0.3/src/robotcode/robot/utils/variables.py +227 -0
- robotcode_robot-1.0.2/LICENSE.txt +0 -73
- robotcode_robot-1.0.2/README.md +0 -21
- robotcode_robot-1.0.2/src/robotcode/robot/__version__.py +0 -1
- robotcode_robot-1.0.2/src/robotcode/robot/utils/__init__.py +0 -17
- robotcode_robot-1.0.2/src/robotcode/robot/utils/variables.py +0 -72
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/__init__.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/config/__init__.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/config/loader.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/config/utils.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/__init__.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/diagnostics_modifier.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/py.typed +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/utils/match.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/utils/robot_path.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/utils/stubs.py +0 -0
- {robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/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:
|
|
3
|
+
Version: 2.0.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
|
|
@@ -10,23 +10,23 @@ Project-URL: Issues, https://github.com/robotcodedev/robotcode/issues
|
|
|
10
10
|
Project-URL: Source, https://github.com/robotcodedev/robotcode
|
|
11
11
|
Author-email: Daniel Biehl <dbiehl@live.de>
|
|
12
12
|
License: Apache-2.0
|
|
13
|
-
License-File: LICENSE.txt
|
|
14
13
|
Classifier: Development Status :: 5 - Production/Stable
|
|
15
14
|
Classifier: Framework :: Robot Framework
|
|
16
15
|
Classifier: Framework :: Robot Framework :: Tool
|
|
17
16
|
Classifier: Operating System :: OS Independent
|
|
18
17
|
Classifier: Programming Language :: Python
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
23
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
24
24
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
25
25
|
Classifier: Topic :: Utilities
|
|
26
26
|
Classifier: Typing :: Typed
|
|
27
|
-
Requires-Python: >=3.
|
|
28
|
-
Requires-Dist: platformdirs
|
|
29
|
-
Requires-Dist: robotcode-core==
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Requires-Dist: platformdirs>=4.3
|
|
29
|
+
Requires-Dist: robotcode-core==2.0.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
|
|
@@ -41,7 +41,9 @@ Description-Content-Type: text/markdown
|
|
|
41
41
|
|
|
42
42
|
## Introduction
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
Robot Framework project handling and integration utilities for [RobotCode](https://robotcode.io).
|
|
45
|
+
|
|
46
|
+
This package is part of the [RobotCode](https://robotcode.io) project. The complete source code is available at [github.com/robotcodedev/robotcode](https://github.com/robotcodedev/robotcode).
|
|
45
47
|
|
|
46
48
|
## Installation
|
|
47
49
|
|
|
@@ -49,6 +51,20 @@ Support classes for [RobotCode](https://robotcode.io) for handling Robot Framewo
|
|
|
49
51
|
pip install robotcode-robot
|
|
50
52
|
```
|
|
51
53
|
|
|
54
|
+
## Documentation
|
|
55
|
+
|
|
56
|
+
For comprehensive documentation, please visit [robotcode.io](https://robotcode.io).
|
|
57
|
+
|
|
58
|
+
## Security
|
|
59
|
+
|
|
60
|
+
For security concerns, please refer to our [Security Policy](https://github.com/robotcodedev/robotcode/security/policy).
|
|
61
|
+
|
|
52
62
|
## License
|
|
53
63
|
|
|
54
64
|
`robotcode-robot` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
|
|
65
|
+
|
|
66
|
+
## Support
|
|
67
|
+
|
|
68
|
+
- 📖 [Documentation](https://robotcode.io)
|
|
69
|
+
- 💬 [Discussions](https://github.com/robotcodedev/robotcode/discussions)
|
|
70
|
+
- 🐛 [Issues](https://github.com/robotcodedev/robotcode/issues)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# robotcode-robot
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/robotcode-robot)
|
|
4
|
+
[](https://pypi.org/project/robotcode-robot)
|
|
5
|
+
[](https://github.com/robotcodedev/robotcode/blob/master/LICENSE.txt)
|
|
6
|
+
|
|
7
|
+
-----
|
|
8
|
+
|
|
9
|
+
## Introduction
|
|
10
|
+
|
|
11
|
+
Robot Framework project handling and integration utilities for [RobotCode](https://robotcode.io).
|
|
12
|
+
|
|
13
|
+
This package is part of the [RobotCode](https://robotcode.io) project. The complete source code is available at [github.com/robotcodedev/robotcode](https://github.com/robotcodedev/robotcode).
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```console
|
|
18
|
+
pip install robotcode-robot
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Documentation
|
|
22
|
+
|
|
23
|
+
For comprehensive documentation, please visit [robotcode.io](https://robotcode.io).
|
|
24
|
+
|
|
25
|
+
## Security
|
|
26
|
+
|
|
27
|
+
For security concerns, please refer to our [Security Policy](https://github.com/robotcodedev/robotcode/security/policy).
|
|
28
|
+
|
|
29
|
+
## License
|
|
30
|
+
|
|
31
|
+
`robotcode-robot` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
|
|
32
|
+
|
|
33
|
+
## Support
|
|
34
|
+
|
|
35
|
+
- 📖 [Documentation](https://robotcode.io)
|
|
36
|
+
- 💬 [Discussions](https://github.com/robotcodedev/robotcode/discussions)
|
|
37
|
+
- 🐛 [Issues](https://github.com/robotcodedev/robotcode/issues)
|
|
@@ -7,17 +7,18 @@ build-backend = "hatchling.build"
|
|
|
7
7
|
name = "robotcode-robot"
|
|
8
8
|
description = 'Support classes for RobotCode for handling Robot Framework projects.'
|
|
9
9
|
readme = { "file" = "README.md", "content-type" = "text/markdown" }
|
|
10
|
-
requires-python = ">=3.
|
|
11
|
-
license = {text = "Apache-2.0"}
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
12
|
keywords = []
|
|
13
13
|
authors = [{ name = "Daniel Biehl", email = "dbiehl@live.de" }]
|
|
14
14
|
classifiers = [
|
|
15
15
|
"Development Status :: 5 - Production/Stable",
|
|
16
16
|
"Programming Language :: Python",
|
|
17
|
-
"Programming Language :: Python :: 3.8",
|
|
18
|
-
"Programming Language :: Python :: 3.9",
|
|
19
17
|
"Programming Language :: Python :: 3.10",
|
|
20
18
|
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
21
22
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
22
23
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
23
24
|
"Operating System :: OS Independent",
|
|
@@ -29,8 +30,8 @@ classifiers = [
|
|
|
29
30
|
dependencies = [
|
|
30
31
|
"robotframework>=4.1.0",
|
|
31
32
|
"tomli>=1.1.0; python_version < '3.11'",
|
|
32
|
-
"platformdirs>=
|
|
33
|
-
"robotcode-core==
|
|
33
|
+
"platformdirs>=4.3",
|
|
34
|
+
"robotcode-core==2.0.3",
|
|
34
35
|
]
|
|
35
36
|
dynamic = ["version"]
|
|
36
37
|
|
|
@@ -57,4 +58,4 @@ only-include = ["src"]
|
|
|
57
58
|
|
|
58
59
|
[tool.hatch.envs.build]
|
|
59
60
|
detached = true
|
|
60
|
-
python = "
|
|
61
|
+
python = "310"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.0.3"
|
|
@@ -366,7 +366,7 @@ class RobotBaseOptions(BaseOptions):
|
|
|
366
366
|
)
|
|
367
367
|
|
|
368
368
|
def append_name(field: "dataclasses.Field[Any]", add_flag: Optional[str] = None) -> None:
|
|
369
|
-
if "robot_short_name" in field.metadata:
|
|
369
|
+
if "robot_short_name" in field.metadata and not add_flag:
|
|
370
370
|
result.append(f"-{field.metadata['robot_short_name']}")
|
|
371
371
|
elif "robot_name" in field.metadata:
|
|
372
372
|
result.append(f"--{'no' if add_flag else ''}{field.metadata['robot_name']}")
|
|
@@ -697,9 +697,9 @@ class CommonOptions(RobotBaseOptions):
|
|
|
697
697
|
**passed:** remove data only from keywords in passed
|
|
698
698
|
test cases and suites
|
|
699
699
|
|
|
700
|
-
**for:** remove passed iterations from
|
|
700
|
+
**for:** remove passed iterations from FOR loops
|
|
701
701
|
|
|
702
|
-
**while:** remove passed iterations from
|
|
702
|
+
**while:** remove passed iterations from WHILE loops
|
|
703
703
|
|
|
704
704
|
**wuks:** remove all but the last failing keyword
|
|
705
705
|
inside `BuiltIn.Wait Until Keyword Succeeds`
|
|
@@ -847,7 +847,6 @@ class CommonOptions(RobotBaseOptions):
|
|
|
847
847
|
pattern. Documentation is shown in `Test Details` and
|
|
848
848
|
also as a tooltip in `Statistics by Tag`. Pattern can
|
|
849
849
|
use `*`, `?` and `[]` as wildcards like --test.
|
|
850
|
-
Documentation can contain formatting like --doc.
|
|
851
850
|
|
|
852
851
|
Examples:
|
|
853
852
|
|
|
@@ -1130,9 +1129,9 @@ class CommonExtendOptions(RobotBaseOptions):
|
|
|
1130
1129
|
**passed:** remove data only from keywords in passed
|
|
1131
1130
|
test cases and suites
|
|
1132
1131
|
|
|
1133
|
-
**for:** remove passed iterations from
|
|
1132
|
+
**for:** remove passed iterations from FOR loops
|
|
1134
1133
|
|
|
1135
|
-
**while:** remove passed iterations from
|
|
1134
|
+
**while:** remove passed iterations from WHILE loops
|
|
1136
1135
|
|
|
1137
1136
|
**wuks:** remove all but the last failing keyword
|
|
1138
1137
|
inside `BuiltIn.Wait Until Keyword Succeeds`
|
|
@@ -1202,7 +1201,6 @@ class CommonExtendOptions(RobotBaseOptions):
|
|
|
1202
1201
|
pattern. Documentation is shown in `Test Details` and
|
|
1203
1202
|
also as a tooltip in `Statistics by Tag`. Pattern can
|
|
1204
1203
|
use `*`, `?` and `[]` as wildcards like --test.
|
|
1205
|
-
Documentation can contain formatting like --doc.
|
|
1206
1204
|
|
|
1207
1205
|
Examples:
|
|
1208
1206
|
|
|
@@ -1862,7 +1860,6 @@ class RebotOptions(RobotBaseOptions):
|
|
|
1862
1860
|
Processes output also if the top level suite is
|
|
1863
1861
|
empty. Useful e.g. with --include/--exclude when it
|
|
1864
1862
|
is not an error that there are no matches.
|
|
1865
|
-
Use --skiponfailure when starting execution instead.
|
|
1866
1863
|
|
|
1867
1864
|
corresponds to the `--processemptysuite` option of _rebot_
|
|
1868
1865
|
""",
|
|
@@ -1944,7 +1941,7 @@ class LibDocOptions(RobotBaseOptions):
|
|
|
1944
1941
|
quiet: Union[bool, Flag, None] = field(
|
|
1945
1942
|
description="""\
|
|
1946
1943
|
Do not print the path of the generated output file
|
|
1947
|
-
to the console.
|
|
1944
|
+
to the console.
|
|
1948
1945
|
|
|
1949
1946
|
corresponds to the `--quiet` option of _libdoc_
|
|
1950
1947
|
""",
|
|
@@ -1959,7 +1956,7 @@ class LibDocOptions(RobotBaseOptions):
|
|
|
1959
1956
|
documentation format and HTML means converting
|
|
1960
1957
|
documentation to HTML. The default is RAW with XML
|
|
1961
1958
|
spec files and HTML with JSON specs and when using
|
|
1962
|
-
the special LIBSPEC format.
|
|
1959
|
+
the special LIBSPEC format.
|
|
1963
1960
|
|
|
1964
1961
|
corresponds to the `-s --specdocformat RAW|HTML` option of _libdoc_
|
|
1965
1962
|
""",
|
|
@@ -2371,11 +2368,11 @@ class RobotConfig(RobotExtendBaseProfile):
|
|
|
2371
2368
|
|
|
2372
2369
|
Examples:
|
|
2373
2370
|
```toml
|
|
2374
|
-
|
|
2371
|
+
default-profiles = "default"
|
|
2375
2372
|
```
|
|
2376
2373
|
|
|
2377
2374
|
```toml
|
|
2378
|
-
|
|
2375
|
+
default-profiles = ["default", "Firefox"]
|
|
2379
2376
|
```
|
|
2380
2377
|
"""
|
|
2381
2378
|
)
|
|
@@ -532,6 +532,11 @@ class DocumentsCacheHelper:
|
|
|
532
532
|
self.analysis_config.cache.ignore_arguments_for_library + cache_config.ignore_arguments_for_library,
|
|
533
533
|
self.analysis_config.robot.global_library_search_order + analysis_config.global_library_search_order,
|
|
534
534
|
cache_base_path,
|
|
535
|
+
load_library_timeout=(
|
|
536
|
+
analysis_config.load_library_timeout
|
|
537
|
+
if analysis_config.load_library_timeout is not None
|
|
538
|
+
else self.analysis_config.robot.load_library_timeout
|
|
539
|
+
),
|
|
535
540
|
)
|
|
536
541
|
|
|
537
542
|
result.libraries_changed.add(self._on_libraries_changed)
|
|
@@ -589,7 +594,6 @@ class DocumentsCacheHelper:
|
|
|
589
594
|
return self._imports_managers[folder]
|
|
590
595
|
|
|
591
596
|
def calc_cache_path(self, folder_uri: Uri) -> Path:
|
|
592
|
-
# TODO: cache path should be configurable, save cache in vscode workspace folder or in robotcode cache folder
|
|
593
597
|
return folder_uri.to_path()
|
|
594
598
|
|
|
595
599
|
def get_diagnostic_modifier(self, document: TextDocument) -> DiagnosticsModifier:
|
|
@@ -17,10 +17,9 @@ from typing_extensions import Concatenate, ParamSpec
|
|
|
17
17
|
|
|
18
18
|
from robot.parsing.lexer.tokens import Token
|
|
19
19
|
from robotcode.core.lsp.types import Position, Range
|
|
20
|
-
from robotcode.robot.utils.match import normalize
|
|
21
20
|
|
|
22
21
|
from ..utils.ast import range_from_token
|
|
23
|
-
from ..utils.variables import search_variable
|
|
22
|
+
from ..utils.variables import VariableMatcher, search_variable
|
|
24
23
|
|
|
25
24
|
if TYPE_CHECKING:
|
|
26
25
|
from robotcode.robot.diagnostics.library_doc import KeywordDoc, LibraryDoc
|
|
@@ -164,48 +163,6 @@ class VariablesImport(Import):
|
|
|
164
163
|
return hash((type(self), self.name, self.args))
|
|
165
164
|
|
|
166
165
|
|
|
167
|
-
class InvalidVariableError(Exception):
|
|
168
|
-
pass
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class VariableMatcher:
|
|
172
|
-
def __init__(self, name: str) -> None:
|
|
173
|
-
self.name = name
|
|
174
|
-
|
|
175
|
-
match = search_variable(name, "$@&%", ignore_errors=True)
|
|
176
|
-
|
|
177
|
-
if match.base is None:
|
|
178
|
-
raise InvalidVariableError(f"Invalid variable '{name}'")
|
|
179
|
-
|
|
180
|
-
self.base = match.base
|
|
181
|
-
|
|
182
|
-
self.normalized_name = normalize(self.base)
|
|
183
|
-
|
|
184
|
-
def __eq__(self, o: object) -> bool:
|
|
185
|
-
if type(o) is VariableMatcher:
|
|
186
|
-
return o.normalized_name == self.normalized_name
|
|
187
|
-
|
|
188
|
-
if type(o) is str:
|
|
189
|
-
match = search_variable(o, "$@&%", ignore_errors=True)
|
|
190
|
-
base = match.base
|
|
191
|
-
if base is None:
|
|
192
|
-
return False
|
|
193
|
-
|
|
194
|
-
normalized = normalize(base)
|
|
195
|
-
return self.normalized_name == normalized
|
|
196
|
-
|
|
197
|
-
return False
|
|
198
|
-
|
|
199
|
-
def __hash__(self) -> int:
|
|
200
|
-
return hash(self.normalized_name)
|
|
201
|
-
|
|
202
|
-
def __str__(self) -> str:
|
|
203
|
-
return self.name
|
|
204
|
-
|
|
205
|
-
def __repr__(self) -> str:
|
|
206
|
-
return f"{type(self).__name__}(name={self.name!r})"
|
|
207
|
-
|
|
208
|
-
|
|
209
166
|
class VariableDefinitionType(Enum):
|
|
210
167
|
VARIABLE = "suite variable"
|
|
211
168
|
LOCAL_VARIABLE = "local variable"
|
|
@@ -222,7 +179,8 @@ class VariableDefinitionType(Enum):
|
|
|
222
179
|
@dataclass
|
|
223
180
|
class VariableDefinition(SourceEntity):
|
|
224
181
|
name: str
|
|
225
|
-
name_token: Optional[Token]
|
|
182
|
+
name_token: Optional[Token] # TODO: this is not needed anymore, but kept for compatibility
|
|
183
|
+
|
|
226
184
|
type: VariableDefinitionType = VariableDefinitionType.VARIABLE
|
|
227
185
|
|
|
228
186
|
has_value: bool = field(default=False, compare=False)
|
|
@@ -230,10 +188,17 @@ class VariableDefinition(SourceEntity):
|
|
|
230
188
|
|
|
231
189
|
value: Any = field(default=None, compare=False)
|
|
232
190
|
value_is_native: bool = field(default=False, compare=False)
|
|
191
|
+
value_type: Optional[str] = field(default=None, compare=False)
|
|
233
192
|
|
|
234
193
|
@functools.cached_property
|
|
235
194
|
def matcher(self) -> VariableMatcher:
|
|
236
|
-
return
|
|
195
|
+
return search_variable(self.name)
|
|
196
|
+
|
|
197
|
+
@functools.cached_property
|
|
198
|
+
def convertable_name(self) -> str:
|
|
199
|
+
m = self.matcher
|
|
200
|
+
value_type = f": {self.value_type}" if self.value_type else ""
|
|
201
|
+
return f"{m.identifier}{{{m.base.strip()}{value_type}}}"
|
|
237
202
|
|
|
238
203
|
@single_call
|
|
239
204
|
def __hash__(self) -> int:
|
|
@@ -311,6 +276,15 @@ class ArgumentDefinition(LocalVariableDefinition):
|
|
|
311
276
|
return hash((type(self), self.name, self.type, self.range, self.source))
|
|
312
277
|
|
|
313
278
|
|
|
279
|
+
@dataclass
|
|
280
|
+
class EmbeddedArgumentDefinition(ArgumentDefinition):
|
|
281
|
+
pattern: Optional[str] = field(default=None, compare=False)
|
|
282
|
+
|
|
283
|
+
@single_call
|
|
284
|
+
def __hash__(self) -> int:
|
|
285
|
+
return hash((type(self), self.name, self.type, self.range, self.source))
|
|
286
|
+
|
|
287
|
+
|
|
314
288
|
@dataclass
|
|
315
289
|
class LibraryArgumentDefinition(ArgumentDefinition):
|
|
316
290
|
@single_call
|
|
@@ -39,7 +39,9 @@ class Error:
|
|
|
39
39
|
INVALID_HEADER = "InvalidHeader"
|
|
40
40
|
DEPRECATED_HEADER = "DeprecatedHeader"
|
|
41
41
|
OVERRIDDEN_BY_COMMANDLINE = "OverriddenByCommandLine"
|
|
42
|
+
OVERRIDES_IMPORTED_VARIABLE = "OverridesImportedVariable"
|
|
42
43
|
VARIABLE_ALREADY_DEFINED = "VariableAlreadyDefined"
|
|
43
44
|
VARIABLE_OVERRIDDEN = "VariableOverridden"
|
|
44
45
|
MODEL_ERROR = "ModelError"
|
|
45
46
|
TOKEN_ERROR = "TokenError"
|
|
47
|
+
ASSIGN_MARK_ALLOWED_ONLY_ON_LAST_VAR = "AssignmentMarkAllowedOnlyOnLastVariable"
|
{robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/imports_manager.py
RENAMED
|
@@ -96,8 +96,9 @@ RESOURCE_EXTENSIONS = (
|
|
|
96
96
|
REST_EXTENSIONS = (".rst", ".rest")
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
DEFAULT_LOAD_LIBRARY_TIMEOUT: int = 10
|
|
100
|
+
ENV_LOAD_LIBRARY_TIMEOUT_VAR = "ROBOTCODE_LOAD_LIBRARY_TIMEOUT"
|
|
101
|
+
COMPLETE_LIBRARY_IMPORT_TIMEOUT = COMPLETE_RESOURCE_IMPORT_TIMEOUT = COMPLETE_VARIABLES_IMPORT_TIMEOUT = 5
|
|
101
102
|
|
|
102
103
|
|
|
103
104
|
class _EntryKey:
|
|
@@ -226,7 +227,9 @@ class _LibrariesEntry(_ImportEntry):
|
|
|
226
227
|
source_or_origin = (
|
|
227
228
|
self._lib_doc.source
|
|
228
229
|
if self._lib_doc.source is not None
|
|
229
|
-
else self._lib_doc.module_spec.origin
|
|
230
|
+
else self._lib_doc.module_spec.origin
|
|
231
|
+
if self._lib_doc.module_spec is not None
|
|
232
|
+
else None
|
|
230
233
|
)
|
|
231
234
|
|
|
232
235
|
# we are a module, so add the module path into file watchers
|
|
@@ -512,6 +515,7 @@ class ImportsManager:
|
|
|
512
515
|
ignore_arguments_for_library: List[str],
|
|
513
516
|
global_library_search_order: List[str],
|
|
514
517
|
cache_base_path: Optional[Path],
|
|
518
|
+
load_library_timeout: Optional[int] = None,
|
|
515
519
|
) -> None:
|
|
516
520
|
super().__init__()
|
|
517
521
|
|
|
@@ -588,6 +592,45 @@ class ImportsManager:
|
|
|
588
592
|
|
|
589
593
|
self._diagnostics: List[Diagnostic] = []
|
|
590
594
|
|
|
595
|
+
# precedence: explicit config (arg) > environment variable > default
|
|
596
|
+
if load_library_timeout is None:
|
|
597
|
+
env_value = os.environ.get(ENV_LOAD_LIBRARY_TIMEOUT_VAR)
|
|
598
|
+
if env_value is not None:
|
|
599
|
+
try:
|
|
600
|
+
load_library_timeout = int(env_value)
|
|
601
|
+
except ValueError:
|
|
602
|
+
self._logger.warning(
|
|
603
|
+
lambda: (
|
|
604
|
+
"Invalid value for "
|
|
605
|
+
f"{ENV_LOAD_LIBRARY_TIMEOUT_VAR}={env_value!r}, using default "
|
|
606
|
+
f"{DEFAULT_LOAD_LIBRARY_TIMEOUT}"
|
|
607
|
+
),
|
|
608
|
+
context_name="imports",
|
|
609
|
+
)
|
|
610
|
+
load_library_timeout = DEFAULT_LOAD_LIBRARY_TIMEOUT
|
|
611
|
+
else:
|
|
612
|
+
load_library_timeout = DEFAULT_LOAD_LIBRARY_TIMEOUT
|
|
613
|
+
|
|
614
|
+
# enforce sane lower bound
|
|
615
|
+
if load_library_timeout <= 0:
|
|
616
|
+
self._logger.warning(
|
|
617
|
+
lambda: (
|
|
618
|
+
"Configured load_library_timeout "
|
|
619
|
+
f"{load_library_timeout} is not > 0, fallback to {DEFAULT_LOAD_LIBRARY_TIMEOUT}"
|
|
620
|
+
),
|
|
621
|
+
context_name="imports",
|
|
622
|
+
)
|
|
623
|
+
load_library_timeout = DEFAULT_LOAD_LIBRARY_TIMEOUT
|
|
624
|
+
|
|
625
|
+
self.load_library_timeout = load_library_timeout
|
|
626
|
+
|
|
627
|
+
self._logger.trace(lambda: f"Using LoadLibrary timeout of {self.load_library_timeout} seconds")
|
|
628
|
+
|
|
629
|
+
self._logger.trace(
|
|
630
|
+
lambda: f"Using load_library_timeout={self.load_library_timeout} (config/env/default)",
|
|
631
|
+
context_name="imports",
|
|
632
|
+
)
|
|
633
|
+
|
|
591
634
|
def __del__(self) -> None:
|
|
592
635
|
try:
|
|
593
636
|
if self._executor is not None:
|
|
@@ -1226,8 +1269,7 @@ class ImportsManager:
|
|
|
1226
1269
|
saved_meta = self.data_cache.read_cache_data(CacheSection.LIBRARY, meta_file, LibraryMetaData)
|
|
1227
1270
|
if saved_meta.has_errors:
|
|
1228
1271
|
self._logger.debug(
|
|
1229
|
-
lambda: f"Saved library spec for {name}{args!r} is not used "
|
|
1230
|
-
"due to errors in meta data",
|
|
1272
|
+
lambda: f"Saved library spec for {name}{args!r} is not used due to errors in meta data",
|
|
1231
1273
|
context_name="import",
|
|
1232
1274
|
)
|
|
1233
1275
|
|
|
@@ -1265,10 +1307,16 @@ class ImportsManager:
|
|
|
1265
1307
|
base_dir,
|
|
1266
1308
|
self.get_resolvable_command_line_variables(),
|
|
1267
1309
|
variables,
|
|
1268
|
-
).result(
|
|
1310
|
+
).result(self.load_library_timeout)
|
|
1269
1311
|
|
|
1270
1312
|
except TimeoutError as e:
|
|
1271
|
-
raise RuntimeError(
|
|
1313
|
+
raise RuntimeError(
|
|
1314
|
+
f"Loading library {name!r} with args {args!r} (working_dir={working_dir!r}, base_dir={base_dir!r}) "
|
|
1315
|
+
f"timed out after {self.load_library_timeout} seconds. "
|
|
1316
|
+
"The library may be slow or blocked during import. "
|
|
1317
|
+
"If required, increase the timeout by setting the ROBOTCODE_LOAD_LIBRARY_TIMEOUT "
|
|
1318
|
+
"environment variable."
|
|
1319
|
+
) from e
|
|
1272
1320
|
|
|
1273
1321
|
except (SystemExit, KeyboardInterrupt):
|
|
1274
1322
|
raise
|
|
@@ -1437,10 +1485,17 @@ class ImportsManager:
|
|
|
1437
1485
|
base_dir,
|
|
1438
1486
|
self.get_resolvable_command_line_variables() if resolve_command_line_vars else None,
|
|
1439
1487
|
variables,
|
|
1440
|
-
).result(
|
|
1488
|
+
).result(self.load_library_timeout)
|
|
1441
1489
|
|
|
1442
1490
|
except TimeoutError as e:
|
|
1443
|
-
raise RuntimeError(
|
|
1491
|
+
raise RuntimeError(
|
|
1492
|
+
f"Loading variables {name!r} with args {args!r} (working_dir={working_dir!r}, "
|
|
1493
|
+
f"base_dir={base_dir!r}) "
|
|
1494
|
+
f"timed out after {self.load_library_timeout} seconds. "
|
|
1495
|
+
"The variables may be slow or blocked during import. "
|
|
1496
|
+
"If required, increase the timeout by setting the ROBOTCODE_LOAD_LIBRARY_TIMEOUT "
|
|
1497
|
+
"environment variable."
|
|
1498
|
+
) from e
|
|
1444
1499
|
|
|
1445
1500
|
except (SystemExit, KeyboardInterrupt):
|
|
1446
1501
|
raise
|
|
@@ -1526,11 +1581,11 @@ class ImportsManager:
|
|
|
1526
1581
|
variables: Optional[Dict[str, Any]] = None,
|
|
1527
1582
|
) -> _ResourcesEntry:
|
|
1528
1583
|
source = self.find_resource(name, base_dir, variables=variables)
|
|
1584
|
+
source_path = normalized_path(Path(source))
|
|
1529
1585
|
|
|
1530
1586
|
def _get_document() -> TextDocument:
|
|
1531
|
-
self._logger.debug(lambda: f"Load resource {name} from source {
|
|
1587
|
+
self._logger.debug(lambda: f"Load resource {name} from source {source_path}", context_name="import")
|
|
1532
1588
|
|
|
1533
|
-
source_path = normalized_path(Path(source))
|
|
1534
1589
|
extension = source_path.suffix
|
|
1535
1590
|
if extension.lower() not in RESOURCE_EXTENSIONS:
|
|
1536
1591
|
raise ImportError(
|
|
@@ -1540,7 +1595,7 @@ class ImportsManager:
|
|
|
1540
1595
|
|
|
1541
1596
|
return self.documents_manager.get_or_open_document(source_path)
|
|
1542
1597
|
|
|
1543
|
-
entry_key = _ResourcesEntryKey(
|
|
1598
|
+
entry_key = _ResourcesEntryKey(str(source_path))
|
|
1544
1599
|
|
|
1545
1600
|
with self._resources_lock:
|
|
1546
1601
|
if entry_key not in self._resources:
|
|
@@ -1607,7 +1662,7 @@ class ImportsManager:
|
|
|
1607
1662
|
base_dir,
|
|
1608
1663
|
self.get_resolvable_command_line_variables(),
|
|
1609
1664
|
variables,
|
|
1610
|
-
).result(
|
|
1665
|
+
).result(COMPLETE_LIBRARY_IMPORT_TIMEOUT)
|
|
1611
1666
|
|
|
1612
1667
|
def complete_resource_import(
|
|
1613
1668
|
self,
|
|
@@ -1622,7 +1677,7 @@ class ImportsManager:
|
|
|
1622
1677
|
base_dir,
|
|
1623
1678
|
self.get_resolvable_command_line_variables(),
|
|
1624
1679
|
variables,
|
|
1625
|
-
).result(
|
|
1680
|
+
).result(COMPLETE_RESOURCE_IMPORT_TIMEOUT)
|
|
1626
1681
|
|
|
1627
1682
|
def complete_variables_import(
|
|
1628
1683
|
self,
|
|
@@ -1637,7 +1692,7 @@ class ImportsManager:
|
|
|
1637
1692
|
base_dir,
|
|
1638
1693
|
self.get_resolvable_command_line_variables(),
|
|
1639
1694
|
variables,
|
|
1640
|
-
).result(
|
|
1695
|
+
).result(COMPLETE_VARIABLES_IMPORT_TIMEOUT)
|
|
1641
1696
|
|
|
1642
1697
|
def resolve_variable(
|
|
1643
1698
|
self,
|
{robotcode_robot-1.0.2 → robotcode_robot-2.0.3}/src/robotcode/robot/diagnostics/keyword_finder.py
RENAMED
|
@@ -65,7 +65,6 @@ class KeywordFinder:
|
|
|
65
65
|
self.multiple_keywords_result = None
|
|
66
66
|
self.result_bdd_prefix = None
|
|
67
67
|
|
|
68
|
-
# TODO: make this threadsafe
|
|
69
68
|
def find_keyword(
|
|
70
69
|
self,
|
|
71
70
|
name: Optional[str],
|
|
@@ -87,9 +86,25 @@ class KeywordFinder:
|
|
|
87
86
|
try:
|
|
88
87
|
result = self._find_keyword(name, handle_bdd_style)
|
|
89
88
|
if result is None:
|
|
89
|
+
error_message = "No keyword with found."
|
|
90
|
+
|
|
91
|
+
if name and name.strip(": ").upper() == "FOR":
|
|
92
|
+
error_message = (
|
|
93
|
+
f"Support for the old FOR loop syntax has been removed. "
|
|
94
|
+
f"Replace '{name}' with 'FOR', end the loop with 'END', and "
|
|
95
|
+
f"remove escaping backslashes."
|
|
96
|
+
)
|
|
97
|
+
elif name and name == "\\":
|
|
98
|
+
error_message = (
|
|
99
|
+
"No keyword with name '\\' found. If it is used inside a for "
|
|
100
|
+
"loop, remove escaping backslashes and end the loop with 'END'."
|
|
101
|
+
)
|
|
102
|
+
else:
|
|
103
|
+
error_message = f"No keyword with name '{name}' found."
|
|
104
|
+
|
|
90
105
|
self.diagnostics.append(
|
|
91
106
|
DiagnosticsEntry(
|
|
92
|
-
|
|
107
|
+
error_message,
|
|
93
108
|
DiagnosticSeverity.ERROR,
|
|
94
109
|
Error.KEYWORD_NOT_FOUND,
|
|
95
110
|
)
|
|
@@ -306,17 +321,32 @@ class KeywordFinder:
|
|
|
306
321
|
return True
|
|
307
322
|
return False
|
|
308
323
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
324
|
+
if get_robot_version() >= (7, 3):
|
|
325
|
+
|
|
326
|
+
def _is_better_match(
|
|
327
|
+
self,
|
|
328
|
+
candidate: Tuple[Optional[LibraryEntry], KeywordDoc],
|
|
329
|
+
other: Tuple[Optional[LibraryEntry], KeywordDoc],
|
|
330
|
+
) -> bool:
|
|
331
|
+
return (
|
|
332
|
+
other[1].matcher.embedded_arguments is not None
|
|
333
|
+
and candidate[1].matcher.embedded_arguments is not None
|
|
334
|
+
and other[1].matcher.embedded_arguments.matches(candidate[1].name)
|
|
335
|
+
and not candidate[1].matcher.embedded_arguments.matches(other[1].name)
|
|
336
|
+
)
|
|
337
|
+
else:
|
|
338
|
+
|
|
339
|
+
def _is_better_match(
|
|
340
|
+
self,
|
|
341
|
+
candidate: Tuple[Optional[LibraryEntry], KeywordDoc],
|
|
342
|
+
other: Tuple[Optional[LibraryEntry], KeywordDoc],
|
|
343
|
+
) -> bool:
|
|
344
|
+
return (
|
|
345
|
+
other[1].matcher.embedded_arguments is not None
|
|
346
|
+
and candidate[1].matcher.embedded_arguments is not None
|
|
347
|
+
and other[1].matcher.embedded_arguments.match(candidate[1].name) is not None
|
|
348
|
+
and candidate[1].matcher.embedded_arguments.match(other[1].name) is None
|
|
349
|
+
)
|
|
320
350
|
|
|
321
351
|
@functools.cached_property
|
|
322
352
|
def _resource_imports(self) -> List[ResourceEntry]:
|