robotcode-robot 0.96.0__py3-none-any.whl → 0.98.0__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/config/loader.py +29 -7
- robotcode/robot/diagnostics/imports_manager.py +60 -6
- robotcode/robot/diagnostics/namespace.py +32 -2
- robotcode/robot/diagnostics/workspace_config.py +1 -0
- {robotcode_robot-0.96.0.dist-info → robotcode_robot-0.98.0.dist-info}/METADATA +2 -3
- {robotcode_robot-0.96.0.dist-info → robotcode_robot-0.98.0.dist-info}/RECORD +9 -9
- {robotcode_robot-0.96.0.dist-info → robotcode_robot-0.98.0.dist-info}/WHEEL +1 -1
- {robotcode_robot-0.96.0.dist-info → robotcode_robot-0.98.0.dist-info}/licenses/LICENSE.txt +0 -0
robotcode/robot/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.
|
1
|
+
__version__ = "0.98.0"
|
robotcode/robot/config/loader.py
CHANGED
@@ -55,14 +55,36 @@ class ConfigTypeError(TypeError):
|
|
55
55
|
_ConfigType = TypeVar("_ConfigType", bound=BaseOptions)
|
56
56
|
|
57
57
|
|
58
|
+
class InvalidTomlError(ValueError):
|
59
|
+
pass
|
60
|
+
|
61
|
+
|
62
|
+
class InvalidTomlFileError(ValueError):
|
63
|
+
pass
|
64
|
+
|
65
|
+
|
66
|
+
def _load_toml(data: Union[str, Path]) -> Dict[str, Any]:
|
67
|
+
file = None
|
68
|
+
if isinstance(data, Path):
|
69
|
+
file = data
|
70
|
+
data = data.read_text("utf-8")
|
71
|
+
|
72
|
+
try:
|
73
|
+
return tomllib.loads(data)
|
74
|
+
except tomllib.TOMLDecodeError as e:
|
75
|
+
if file:
|
76
|
+
raise InvalidTomlFileError(f"Invalid TOML file'{file.absolute()}': {e}") from e
|
77
|
+
raise InvalidTomlError(f"Invalid TOML: {e}") from e
|
78
|
+
|
79
|
+
|
58
80
|
def load_robot_config_from_robot_toml_str(__s: str) -> RobotConfig:
|
59
81
|
return load_config_from_robot_toml_str(RobotConfig, __s)
|
60
82
|
|
61
83
|
|
62
84
|
def load_config_from_robot_toml_str(
|
63
|
-
config_type: Type[_ConfigType], data: Union[str, Dict[str, Any]], tool_name: Optional[str] = None
|
85
|
+
config_type: Type[_ConfigType], data: Union[str, Dict[str, Any], Path], tool_name: Optional[str] = None
|
64
86
|
) -> _ConfigType:
|
65
|
-
dict_data =
|
87
|
+
dict_data = _load_toml(data) if isinstance(data, (str, Path)) else data
|
66
88
|
|
67
89
|
if tool_name:
|
68
90
|
try:
|
@@ -76,9 +98,9 @@ def load_config_from_robot_toml_str(
|
|
76
98
|
|
77
99
|
|
78
100
|
def load_config_from_pyproject_toml_str(
|
79
|
-
config_type: Type[_ConfigType], tool_name: str, data: Union[str, Dict[str, Any]]
|
101
|
+
config_type: Type[_ConfigType], tool_name: str, data: Union[str, Dict[str, Any], Path]
|
80
102
|
) -> _ConfigType:
|
81
|
-
dict_data =
|
103
|
+
dict_data = _load_toml(data) if isinstance(data, (str, Path)) else data
|
82
104
|
|
83
105
|
return from_dict(dict_data.get("tool", {}).get(tool_name, {}), config_type)
|
84
106
|
|
@@ -93,13 +115,13 @@ def _load_config_data_from_path(
|
|
93
115
|
try:
|
94
116
|
if path.name == PYPROJECT_TOML:
|
95
117
|
return load_config_from_pyproject_toml_str(
|
96
|
-
config_type, pyproject_toml_tool_name, path
|
118
|
+
config_type, pyproject_toml_tool_name, path if data is None else data
|
97
119
|
)
|
98
120
|
|
99
121
|
if path.name == ROBOT_TOML or path.name == LOCAL_ROBOT_TOML or path.suffix == ".toml":
|
100
122
|
return load_config_from_robot_toml_str(
|
101
123
|
config_type,
|
102
|
-
path
|
124
|
+
path if data is None else data,
|
103
125
|
tool_name=robot_toml_tool_name,
|
104
126
|
)
|
105
127
|
raise TypeError("Unknown config file type.")
|
@@ -143,7 +165,7 @@ def load_config_from_path(
|
|
143
165
|
verbose_callback(f"Load configuration from {__path if isinstance(__path, Path) else __path[0]}")
|
144
166
|
|
145
167
|
p = __path if isinstance(__path, Path) else __path[0]
|
146
|
-
data =
|
168
|
+
data = _load_toml(p)
|
147
169
|
|
148
170
|
result.add_options(
|
149
171
|
_load_config_data_from_path(
|
@@ -25,6 +25,7 @@ from typing import (
|
|
25
25
|
final,
|
26
26
|
)
|
27
27
|
|
28
|
+
from robot.errors import RobotError
|
28
29
|
from robot.libraries import STDLIBS
|
29
30
|
from robot.utils.text import split_args_from_name_or_path
|
30
31
|
from robotcode.core.concurrent import RLock, run_as_task
|
@@ -32,7 +33,16 @@ from robotcode.core.documents_manager import DocumentsManager
|
|
32
33
|
from robotcode.core.event import event
|
33
34
|
from robotcode.core.filewatcher import FileWatcherEntry, FileWatcherManagerBase, FileWatcherManagerDummy
|
34
35
|
from robotcode.core.language import language_id
|
35
|
-
from robotcode.core.lsp.types import
|
36
|
+
from robotcode.core.lsp.types import (
|
37
|
+
Diagnostic,
|
38
|
+
DiagnosticRelatedInformation,
|
39
|
+
DiagnosticSeverity,
|
40
|
+
DocumentUri,
|
41
|
+
FileChangeType,
|
42
|
+
FileEvent,
|
43
|
+
Location,
|
44
|
+
Range,
|
45
|
+
)
|
36
46
|
from robotcode.core.text_document import TextDocument
|
37
47
|
from robotcode.core.uri import Uri
|
38
48
|
from robotcode.core.utils.caching import SimpleLRUCache
|
@@ -577,6 +587,8 @@ class ImportsManager:
|
|
577
587
|
weakref.WeakKeyDictionary()
|
578
588
|
)
|
579
589
|
|
590
|
+
self._diagnostics: List[Diagnostic] = []
|
591
|
+
|
580
592
|
def __del__(self) -> None:
|
581
593
|
try:
|
582
594
|
if self._executor is not None:
|
@@ -584,6 +596,12 @@ class ImportsManager:
|
|
584
596
|
except RuntimeError:
|
585
597
|
pass
|
586
598
|
|
599
|
+
@property
|
600
|
+
def diagnostics(self) -> List[Diagnostic]:
|
601
|
+
self.get_command_line_variables()
|
602
|
+
|
603
|
+
return self._diagnostics
|
604
|
+
|
587
605
|
@property
|
588
606
|
def environment(self) -> Mapping[str, str]:
|
589
607
|
return self._environment
|
@@ -647,18 +665,54 @@ class ImportsManager:
|
|
647
665
|
]
|
648
666
|
|
649
667
|
if lib_doc.errors:
|
650
|
-
# TODO add diagnostics
|
651
668
|
for error in lib_doc.errors:
|
652
|
-
self.
|
653
|
-
|
669
|
+
self._diagnostics.append(
|
670
|
+
Diagnostic(
|
671
|
+
Range.zero(),
|
672
|
+
f"Processing variable file variable file '{name}({', '.join(args)})' failed"
|
673
|
+
+ ("" if error.source is not None else f": {error.message}"),
|
674
|
+
DiagnosticSeverity.ERROR,
|
675
|
+
error.type_name,
|
676
|
+
related_information=(
|
677
|
+
[
|
678
|
+
DiagnosticRelatedInformation(
|
679
|
+
Location(
|
680
|
+
str(Uri.from_path(os.path.abspath(error.source))),
|
681
|
+
Range.from_int_range(
|
682
|
+
(error.line_no - 1) if error.line_no is not None else -1
|
683
|
+
),
|
684
|
+
),
|
685
|
+
error.message,
|
686
|
+
)
|
687
|
+
]
|
688
|
+
if error.source is not None
|
689
|
+
else None
|
690
|
+
),
|
691
|
+
)
|
654
692
|
)
|
693
|
+
except RobotError as e:
|
694
|
+
self._diagnostics.append(
|
695
|
+
Diagnostic(
|
696
|
+
Range.zero(),
|
697
|
+
f"Error in command line variable file '{name}({', '.join(args)})': {e}",
|
698
|
+
DiagnosticSeverity.ERROR,
|
699
|
+
type(e).__name__,
|
700
|
+
)
|
701
|
+
)
|
655
702
|
except (SystemExit, KeyboardInterrupt):
|
656
703
|
raise
|
657
704
|
except BaseException as e:
|
658
|
-
|
705
|
+
self._diagnostics.append(
|
706
|
+
Diagnostic(
|
707
|
+
Range.zero(),
|
708
|
+
f"Error in command line variable file '{name}({', '.join(args)})': {e}",
|
709
|
+
DiagnosticSeverity.ERROR,
|
710
|
+
type(e).__name__,
|
711
|
+
)
|
712
|
+
)
|
659
713
|
ex = e
|
660
714
|
self._logger.exception(
|
661
|
-
lambda: f"Error
|
715
|
+
lambda: f"Error in command line variable file '{name}({', '.join(args)})'",
|
662
716
|
exc_info=ex,
|
663
717
|
)
|
664
718
|
|
@@ -44,6 +44,7 @@ from robotcode.core.lsp.types import (
|
|
44
44
|
from robotcode.core.text_document import TextDocument
|
45
45
|
from robotcode.core.uri import Uri
|
46
46
|
from robotcode.core.utils.logging import LoggingDescriptor
|
47
|
+
from robotcode.core.utils.path import same_file
|
47
48
|
|
48
49
|
from ..utils.ast import (
|
49
50
|
range_from_node,
|
@@ -1242,8 +1243,37 @@ class Namespace:
|
|
1242
1243
|
|
1243
1244
|
source = self.imports_manager.find_resource(value.name, base_dir, variables=variables)
|
1244
1245
|
|
1245
|
-
|
1246
|
+
allread_imported_resource = next(
|
1247
|
+
(
|
1248
|
+
v
|
1249
|
+
for k, v in self._resources.items()
|
1250
|
+
if v.library_doc.source is not None and same_file(v.library_doc.source, source)
|
1251
|
+
),
|
1252
|
+
None,
|
1253
|
+
)
|
1254
|
+
if allread_imported_resource is not None:
|
1246
1255
|
self._logger.debug(lambda: f"Resource '{value.name}' already imported.", context_name="import")
|
1256
|
+
if top_level:
|
1257
|
+
self.append_diagnostics(
|
1258
|
+
range=value.range,
|
1259
|
+
message=f"Resource '{value.name}' already imported.",
|
1260
|
+
severity=DiagnosticSeverity.INFORMATION,
|
1261
|
+
source=DIAGNOSTICS_SOURCE_NAME,
|
1262
|
+
related_information=(
|
1263
|
+
[
|
1264
|
+
DiagnosticRelatedInformation(
|
1265
|
+
location=Location(
|
1266
|
+
uri=str(Uri.from_path(allread_imported_resource.import_source)),
|
1267
|
+
range=allread_imported_resource.import_range,
|
1268
|
+
),
|
1269
|
+
message="",
|
1270
|
+
)
|
1271
|
+
]
|
1272
|
+
if allread_imported_resource.import_source
|
1273
|
+
else None
|
1274
|
+
),
|
1275
|
+
code=Error.RESOURCE_ALREADY_IMPORTED,
|
1276
|
+
)
|
1247
1277
|
return None
|
1248
1278
|
|
1249
1279
|
if self.source == source:
|
@@ -1453,7 +1483,7 @@ class Namespace:
|
|
1453
1483
|
allread_imported_resource = self._resources_files.get(entry.library_doc.source, None)
|
1454
1484
|
|
1455
1485
|
if allread_imported_resource is None and entry.library_doc.source != self.source:
|
1456
|
-
self._resources[entry.
|
1486
|
+
self._resources[entry.library_doc.source] = entry
|
1457
1487
|
self._resources_files[entry.library_doc.source] = entry
|
1458
1488
|
if entry.variables:
|
1459
1489
|
variables = self.get_suite_variables()
|
@@ -75,6 +75,7 @@ class WorkspaceConfig(ConfigBase):
|
|
75
75
|
|
76
76
|
@dataclass
|
77
77
|
class WorkspaceAnalysisConfig:
|
78
|
+
exclude_patterns: List[str] = field(default_factory=list)
|
78
79
|
cache: CacheConfig = field(default_factory=CacheConfig)
|
79
80
|
robot: AnalysisRobotConfig = field(default_factory=AnalysisRobotConfig)
|
80
81
|
modifiers: AnalysisDiagnosticModifiersConfig = field(default_factory=AnalysisDiagnosticModifiersConfig)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: robotcode-robot
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.98.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
|
@@ -10,7 +10,6 @@ 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
|
@@ -26,7 +25,7 @@ Classifier: Topic :: Utilities
|
|
26
25
|
Classifier: Typing :: Typed
|
27
26
|
Requires-Python: >=3.8
|
28
27
|
Requires-Dist: platformdirs<4.4.0,>=3.2.0
|
29
|
-
Requires-Dist: robotcode-core==0.
|
28
|
+
Requires-Dist: robotcode-core==0.98.0
|
30
29
|
Requires-Dist: robotframework>=4.1.0
|
31
30
|
Requires-Dist: tomli>=1.1.0; python_version < '3.11'
|
32
31
|
Description-Content-Type: text/markdown
|
@@ -1,8 +1,8 @@
|
|
1
1
|
robotcode/robot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
robotcode/robot/__version__.py,sha256=
|
2
|
+
robotcode/robot/__version__.py,sha256=wDatk6DOlwcbppXlUNCn5v8i6SpKrbGGBYEGlrqUork,23
|
3
3
|
robotcode/robot/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
|
4
4
|
robotcode/robot/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
robotcode/robot/config/loader.py,sha256=
|
5
|
+
robotcode/robot/config/loader.py,sha256=tLPzeyHl4ELBIVSj2JtU2wVqlurouKTdfxHy0T5HxRE,8584
|
6
6
|
robotcode/robot/config/model.py,sha256=sgr6-4_E06g-yIXW41Z-NtIXZ_7JMmR5WvUD7kTUqu4,89106
|
7
7
|
robotcode/robot/config/utils.py,sha256=xY-LH31BidWzonpvSrle-4HvKrp02I7IRqU2JwlL4Ls,2931
|
8
8
|
robotcode/robot/diagnostics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -11,13 +11,13 @@ robotcode/robot/diagnostics/diagnostics_modifier.py,sha256=3dDsu8-ET6weIvv7Sk3IQ
|
|
11
11
|
robotcode/robot/diagnostics/document_cache_helper.py,sha256=n903UxVXM4Uq4fPxN5s-dugQAKcWUwf4Nw4q0CJV7aw,23902
|
12
12
|
robotcode/robot/diagnostics/entities.py,sha256=b4u2yQN8MDg90RoTMaW7iLogiDNwOAtK180KCB94RfE,10970
|
13
13
|
robotcode/robot/diagnostics/errors.py,sha256=vRH7HiZOfQIC-L7ys2Bj9ULYxLpUH7I03qJRSkEx08k,1813
|
14
|
-
robotcode/robot/diagnostics/imports_manager.py,sha256=
|
14
|
+
robotcode/robot/diagnostics/imports_manager.py,sha256=jaEE7iUzEA4Rp-KXP3nfn0JyUGyp-0BMfNi8_DsQ6KE,61169
|
15
15
|
robotcode/robot/diagnostics/keyword_finder.py,sha256=dm4BA0ccp5V4C65CkSYUJUNXegSmvG24uu09T3eL6a4,17319
|
16
16
|
robotcode/robot/diagnostics/library_doc.py,sha256=VPCX7xp-0LJiYSFLO68y8MuNAMIYcnhJTIHRmWPpl30,100507
|
17
17
|
robotcode/robot/diagnostics/model_helper.py,sha256=ltuUNWwZJFBmMFXIomMmW1IP5v7tMpQSoC1YbncgoNI,30985
|
18
|
-
robotcode/robot/diagnostics/namespace.py,sha256=
|
18
|
+
robotcode/robot/diagnostics/namespace.py,sha256=nP2Nr388yw91tkd5L6DE9Yn8lb9Y4ML6c5hFn9qq4O4,76705
|
19
19
|
robotcode/robot/diagnostics/namespace_analyzer.py,sha256=MgEoEGH7FvwVYoR3wA0JEGQxMWJTUUHq10NrorJV5LY,74183
|
20
|
-
robotcode/robot/diagnostics/workspace_config.py,sha256=
|
20
|
+
robotcode/robot/diagnostics/workspace_config.py,sha256=gyKR5z-HpnjxPAui3YujgeZqXX7RYBO_ErGVlk7vnGc,2689
|
21
21
|
robotcode/robot/utils/__init__.py,sha256=OjNPMn_XSnfaMCyKd8Kmq6vlRt6mIGlzW4qiiD3ykUg,447
|
22
22
|
robotcode/robot/utils/ast.py,sha256=eqAVVquoRbMw3WvGmK6FnkUjZzAxHAitVjqK-vx-HSY,10764
|
23
23
|
robotcode/robot/utils/markdownformatter.py,sha256=SdHFfK9OdBnljWMP5r5Jy2behtHy-_Myd7GV4hiH-kI,11688
|
@@ -26,7 +26,7 @@ robotcode/robot/utils/robot_path.py,sha256=Z-GVBOPA_xeD20bCJi4_AWaU0eQWvCym-YFty
|
|
26
26
|
robotcode/robot/utils/stubs.py,sha256=umugZYAyneFNgqRJBRMJPzm0u0B_TH8Sx_y-ykXnxpw,351
|
27
27
|
robotcode/robot/utils/variables.py,sha256=-ldL8mRRSYYW2pwlm8IpoDeQcG6LYBqaYyV_7U3xsIc,2174
|
28
28
|
robotcode/robot/utils/visitor.py,sha256=nP3O0qh3YYuxR6S8wYJRBFfNwIVgsgohURBlrnFkRYQ,2299
|
29
|
-
robotcode_robot-0.
|
30
|
-
robotcode_robot-0.
|
31
|
-
robotcode_robot-0.
|
32
|
-
robotcode_robot-0.
|
29
|
+
robotcode_robot-0.98.0.dist-info/METADATA,sha256=uHcW1ePx5mWUf9_sVG8Gdkc6Fr1kPyxlpmKF1Zj674c,2214
|
30
|
+
robotcode_robot-0.98.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
31
|
+
robotcode_robot-0.98.0.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
|
32
|
+
robotcode_robot-0.98.0.dist-info/RECORD,,
|
File without changes
|