robotcode-robot 0.95.2__py3-none-any.whl → 0.97.0__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.
@@ -1 +1 @@
1
- __version__ = "0.95.2"
1
+ __version__ = "0.97.0"
@@ -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 = tomllib.loads(data) if isinstance(data, str) else 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 = tomllib.loads(data) if isinstance(data, str) else 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.read_text("utf-8") if data is None else data
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.read_text("utf-8") if data is None else data,
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 = tomllib.loads(p.read_text("utf-8"))
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 DocumentUri, FileChangeType, FileEvent
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._logger.error(
653
- lambda: f"{error.type_name}: {error.message} in {error.source}:{error.line_no}"
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
- # TODO add diagnostics
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 getting command line variables: {ex}",
715
+ lambda: f"Error in command line variable file '{name}({', '.join(args)})'",
662
716
  exc_info=ex,
663
717
  )
664
718
 
@@ -1227,9 +1281,6 @@ class ImportsManager:
1227
1281
  finally:
1228
1282
  executor.shutdown(wait=True)
1229
1283
 
1230
- if result.stdout:
1231
- self._logger.warning(lambda: f"stdout captured at loading library {name}{args!r}:\n{result.stdout}")
1232
-
1233
1284
  try:
1234
1285
  if meta is not None:
1235
1286
  meta.has_errors = bool(result.errors)
@@ -1402,9 +1453,6 @@ class ImportsManager:
1402
1453
  finally:
1403
1454
  executor.shutdown(True)
1404
1455
 
1405
- if result.stdout:
1406
- self._logger.warning(lambda: f"stdout captured at loading variables {name}{args!r}:\n{result.stdout}")
1407
-
1408
1456
  try:
1409
1457
  if meta is not None:
1410
1458
  meta_file = meta.filepath_base + ".meta"
@@ -292,9 +292,12 @@ class KeywordMatcher:
292
292
  self.normalized_name,
293
293
  self._is_namespace,
294
294
  self._can_have_embedded,
295
- self.embedded_arguments,
296
295
  self.embedded_arguments.name if self.embedded_arguments else None,
297
- self.embedded_arguments.args if self.embedded_arguments else None,
296
+ (
297
+ tuple(self.embedded_arguments.args)
298
+ if self.embedded_arguments and self.embedded_arguments.args
299
+ else None
300
+ ),
298
301
  )
299
302
  )
300
303
 
@@ -67,8 +67,15 @@ class AnalysisDiagnosticModifiersConfig(ConfigBase):
67
67
  hint: List[str] = field(default_factory=list)
68
68
 
69
69
 
70
+ @config_section("robotcode.workspace")
71
+ @dataclass
72
+ class WorkspaceConfig(ConfigBase):
73
+ exclude_patterns: List[str] = field(default_factory=list)
74
+
75
+
70
76
  @dataclass
71
77
  class WorkspaceAnalysisConfig:
78
+ exclude_patterns: List[str] = field(default_factory=list)
72
79
  cache: CacheConfig = field(default_factory=CacheConfig)
73
80
  robot: AnalysisRobotConfig = field(default_factory=AnalysisRobotConfig)
74
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.95.2
3
+ Version: 0.97.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
@@ -25,8 +24,8 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
25
24
  Classifier: Topic :: Utilities
26
25
  Classifier: Typing :: Typed
27
26
  Requires-Python: >=3.8
28
- Requires-Dist: platformdirs<4.2.0,>=3.2.0
29
- Requires-Dist: robotcode-core==0.95.2
27
+ Requires-Dist: platformdirs<4.4.0,>=3.2.0
28
+ Requires-Dist: robotcode-core==0.97.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=MtUGhM3YznPa3gIwYy1bSEC9CMiXlkQf9fXXldoBPnM,23
2
+ robotcode/robot/__version__.py,sha256=4n3tdadixJ_eZgVwheQyewJFQEfb651DXkoZqfN9A3o,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=bNJwr_XdCoUzpG2ag0BH33PIfiCwn0GMxn7q_Sw3zOk,8103
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=_IA_aDdylTGXul4FLoN4bmUBwPjiRqpaSszulZcl45M,58886
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
- robotcode/robot/diagnostics/library_doc.py,sha256=ndDh5AVqCKWLmp1raB-9HBE3e-ptkkXInfAZyiU7lDA,100428
16
+ robotcode/robot/diagnostics/library_doc.py,sha256=VPCX7xp-0LJiYSFLO68y8MuNAMIYcnhJTIHRmWPpl30,100507
17
17
  robotcode/robot/diagnostics/model_helper.py,sha256=ltuUNWwZJFBmMFXIomMmW1IP5v7tMpQSoC1YbncgoNI,30985
18
18
  robotcode/robot/diagnostics/namespace.py,sha256=lJOkaS_yCp8SVhURqh5NqAsm394s0cHZUMQwVeh9nno,75159
19
19
  robotcode/robot/diagnostics/namespace_analyzer.py,sha256=MgEoEGH7FvwVYoR3wA0JEGQxMWJTUUHq10NrorJV5LY,74183
20
- robotcode/robot/diagnostics/workspace_config.py,sha256=3SoewUj_LZB1Ki5hXM8oxQpJr6vyiog66SUw-ibODSA,2478
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.95.2.dist-info/METADATA,sha256=df4ORmop30qwHqbcpO1sXHaYH-F5Bb4hhzfaM8rGOwg,2240
30
- robotcode_robot-0.95.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
31
- robotcode_robot-0.95.2.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
32
- robotcode_robot-0.95.2.dist-info/RECORD,,
29
+ robotcode_robot-0.97.0.dist-info/METADATA,sha256=ZH34rvGP5O_-ihAJedp0f682Q7DOkNVFoT8s9n9wUeo,2214
30
+ robotcode_robot-0.97.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
31
+ robotcode_robot-0.97.0.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
32
+ robotcode_robot-0.97.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.25.0
2
+ Generator: hatchling 1.26.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any