robotcode-robot 0.99.0__tar.gz → 0.100.0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/PKG-INFO +2 -2
  2. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/pyproject.toml +1 -1
  3. robotcode_robot-0.100.0/src/robotcode/robot/__version__.py +1 -0
  4. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/config/loader.py +2 -2
  5. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/diagnostics_modifier.py +1 -2
  6. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/errors.py +2 -0
  7. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/imports_manager.py +1 -5
  8. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/library_doc.py +27 -27
  9. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/model_helper.py +2 -3
  10. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/namespace.py +0 -6
  11. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/namespace_analyzer.py +19 -18
  12. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/utils/ast.py +2 -2
  13. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/utils/markdownformatter.py +1 -1
  14. robotcode_robot-0.99.0/src/robotcode/robot/__version__.py +0 -1
  15. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/.gitignore +0 -0
  16. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/LICENSE.txt +0 -0
  17. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/README.md +0 -0
  18. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/__init__.py +0 -0
  19. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/config/__init__.py +0 -0
  20. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/config/model.py +0 -0
  21. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/config/utils.py +0 -0
  22. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/__init__.py +0 -0
  23. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/data_cache.py +0 -0
  24. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/document_cache_helper.py +0 -0
  25. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/entities.py +0 -0
  26. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/keyword_finder.py +0 -0
  27. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/diagnostics/workspace_config.py +0 -0
  28. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/py.typed +0 -0
  29. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/utils/__init__.py +0 -0
  30. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/utils/match.py +0 -0
  31. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/utils/robot_path.py +0 -0
  32. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/utils/stubs.py +0 -0
  33. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/utils/variables.py +0 -0
  34. {robotcode_robot-0.99.0 → robotcode_robot-0.100.0}/src/robotcode/robot/utils/visitor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: robotcode-robot
3
- Version: 0.99.0
3
+ Version: 0.100.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
@@ -25,7 +25,7 @@ Classifier: Topic :: Utilities
25
25
  Classifier: Typing :: Typed
26
26
  Requires-Python: >=3.8
27
27
  Requires-Dist: platformdirs<4.4.0,>=3.2.0
28
- Requires-Dist: robotcode-core==0.99.0
28
+ Requires-Dist: robotcode-core==0.100.0
29
29
  Requires-Dist: robotframework>=4.1.0
30
30
  Requires-Dist: tomli>=1.1.0; python_version < '3.11'
31
31
  Description-Content-Type: text/markdown
@@ -30,7 +30,7 @@ dependencies = [
30
30
  "robotframework>=4.1.0",
31
31
  "tomli>=1.1.0; python_version < '3.11'",
32
32
  "platformdirs>=3.2.0,<4.4.0",
33
- "robotcode-core==0.99.0",
33
+ "robotcode-core==0.100.0",
34
34
  ]
35
35
  dynamic = ["version"]
36
36
 
@@ -0,0 +1 @@
1
+ __version__ = "0.100.0"
@@ -5,6 +5,7 @@ from pathlib import Path
5
5
  from typing import Any, Callable, Dict, Optional, Sequence, Tuple, Type, TypeVar, Union
6
6
 
7
7
  from robotcode.core.utils.dataclasses import from_dict
8
+ from robotcode.core.utils.path import normalized_path
8
9
 
9
10
  if sys.version_info >= (3, 11):
10
11
  import tomllib
@@ -217,14 +218,13 @@ def find_project_root(
217
218
  root_folder: Optional[Path] = None,
218
219
  no_vcs: bool = False,
219
220
  ) -> Tuple[Optional[Path], DiscoverdBy]:
220
-
221
221
  if root_folder:
222
222
  return root_folder.absolute(), DiscoverdBy.COMMAND_LINE
223
223
 
224
224
  if not sources:
225
225
  sources = (str(Path.cwd().absolute()),)
226
226
 
227
- path_srcs = [Path(Path.cwd(), src).absolute() for src in sources]
227
+ path_srcs = [normalized_path(Path(Path.cwd(), src).absolute()) for src in sources]
228
228
 
229
229
  src_parents = [list(path.parents) + ([path] if path.is_dir() else []) for path in path_srcs]
230
230
 
@@ -47,7 +47,6 @@ ROBOTCODE_MARKER = "robotcode:"
47
47
 
48
48
 
49
49
  class ModifiersVisitor(Visitor):
50
-
51
50
  def __init__(self) -> None:
52
51
  super().__init__()
53
52
 
@@ -209,7 +208,7 @@ class DiagnosticsModifier:
209
208
 
210
209
  lines = self.rules_and_codes.codes.get(code)
211
210
 
212
- if lines is None or lines is not None and diagnostic.range.start.line not in lines:
211
+ if lines is None or (lines is not None and diagnostic.range.start.line not in lines):
213
212
  code = "*"
214
213
  lines = self.rules_and_codes.codes.get(code)
215
214
 
@@ -6,7 +6,9 @@ DIAGNOSTICS_SOURCE_NAME = "robotcode"
6
6
  @final
7
7
  class Error:
8
8
  VARIABLE_NOT_FOUND = "VariableNotFound"
9
+ VARIABLE_NOT_REPLACED = "VariableNotReplaced"
9
10
  ENVIRONMENT_VARIABLE_NOT_FOUND = "EnvironmentVariableNotFound"
11
+ ENVIRONMENT_VARIABLE_NOT_REPLACED = "EnvironmentVariableNotReplaced"
10
12
  KEYWORD_NOT_FOUND = "KeywordNotFound"
11
13
  LIBRARY_CONTAINS_NO_KEYWORDS = "LibraryContainsNoKeywords"
12
14
  POSSIBLE_CIRCULAR_IMPORT = "PossibleCircularImport"
@@ -322,8 +322,7 @@ class _ResourcesEntry(_ImportEntry):
322
322
  if (
323
323
  self._document is not None
324
324
  and (normalized_path(path) == normalized_path(self._document.uri.to_path()))
325
- or self._document is None
326
- ):
325
+ ) or self._document is None:
327
326
  self._invalidate()
328
327
 
329
328
  return change.type
@@ -1090,7 +1089,6 @@ class ImportsManager:
1090
1089
  name: str,
1091
1090
  base_dir: str,
1092
1091
  ) -> str:
1093
-
1094
1092
  if name in STDLIBS:
1095
1093
  result = ROBOT_LIBRARY_PACKAGE + "." + name
1096
1094
  else:
@@ -1178,7 +1176,6 @@ class ImportsManager:
1178
1176
  name: str,
1179
1177
  base_dir: str,
1180
1178
  ) -> str:
1181
-
1182
1179
  if get_robot_version() >= (5, 0):
1183
1180
  if is_variables_by_path(name):
1184
1181
  return find_file_ex(name, base_dir, "Variables")
@@ -1220,7 +1217,6 @@ class ImportsManager:
1220
1217
  meta, _source, ignore_arguments = self.get_library_meta(name, base_dir, variables)
1221
1218
 
1222
1219
  if meta is not None and not meta.has_errors:
1223
-
1224
1220
  meta_file = meta.filepath_base + ".meta"
1225
1221
  if self.data_cache.cache_data_exists(CacheSection.LIBRARY, meta_file):
1226
1222
  try:
@@ -199,7 +199,6 @@ def convert_from_rest(text: str) -> str:
199
199
 
200
200
 
201
201
  if get_robot_version() >= (6, 0):
202
-
203
202
  # monkey patch robot framework
204
203
  _old_from_name = EmbeddedArguments.from_name
205
204
 
@@ -1515,7 +1514,6 @@ __default_variables: Any = None
1515
1514
 
1516
1515
 
1517
1516
  def _get_default_variables() -> Any:
1518
-
1519
1517
  global __default_variables
1520
1518
  if __default_variables is None:
1521
1519
  __default_variables = Variables()
@@ -1622,7 +1620,6 @@ def replace_variables_scalar(
1622
1620
  variables: Optional[Dict[str, Optional[Any]]] = None,
1623
1621
  ignore_errors: bool = False,
1624
1622
  ) -> Any:
1625
-
1626
1623
  _update_env(working_dir)
1627
1624
 
1628
1625
  if contains_variable(scalar, "$@&%"):
@@ -1668,7 +1665,6 @@ def _find_library_internal(
1668
1665
  command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
1669
1666
  variables: Optional[Dict[str, Optional[Any]]] = None,
1670
1667
  ) -> Tuple[str, Any]:
1671
-
1672
1668
  _update_env(working_dir)
1673
1669
 
1674
1670
  robot_variables = None
@@ -1781,7 +1777,6 @@ def get_library_doc(
1781
1777
  command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
1782
1778
  variables: Optional[Dict[str, Optional[Any]]] = None,
1783
1779
  ) -> LibraryDoc:
1784
-
1785
1780
  with _std_capture() as std_capturer:
1786
1781
  import_name, robot_variables = _find_library_internal(
1787
1782
  name,
@@ -1824,7 +1819,11 @@ def get_library_doc(
1824
1819
  if module_spec is not None and module_spec.origin
1825
1820
  else import_name if is_library_by_path(import_name) else None
1826
1821
  ),
1827
- 1 if source is not None or module_spec is not None and module_spec.origin is not None else None,
1822
+ (
1823
+ 1
1824
+ if source is not None or (module_spec is not None and module_spec.origin is not None)
1825
+ else None
1826
+ ),
1828
1827
  )
1829
1828
  ],
1830
1829
  python_path=sys.path,
@@ -1868,7 +1867,7 @@ def get_library_doc(
1868
1867
  error_from_exception(
1869
1868
  e,
1870
1869
  source or module_spec.origin if module_spec is not None else None,
1871
- 1 if source is not None or module_spec is not None and module_spec.origin is not None else None,
1870
+ 1 if source is not None or (module_spec is not None and module_spec.origin is not None) else None,
1872
1871
  )
1873
1872
  )
1874
1873
 
@@ -1919,7 +1918,8 @@ def get_library_doc(
1919
1918
  source or module_spec.origin if module_spec is not None else None,
1920
1919
  (
1921
1920
  1
1922
- if source is not None or module_spec is not None and module_spec.origin is not None
1921
+ if source is not None
1922
+ or (module_spec is not None and module_spec.origin is not None)
1923
1923
  else None
1924
1924
  ),
1925
1925
  )
@@ -2119,7 +2119,11 @@ def get_library_doc(
2119
2119
  error_from_exception(
2120
2120
  e,
2121
2121
  source or module_spec.origin if module_spec is not None else None,
2122
- 1 if source is not None or module_spec is not None and module_spec.origin is not None else None,
2122
+ (
2123
+ 1
2124
+ if source is not None or (module_spec is not None and module_spec.origin is not None)
2125
+ else None
2126
+ ),
2123
2127
  )
2124
2128
  )
2125
2129
 
@@ -2138,7 +2142,6 @@ def _find_variables_internal(
2138
2142
  command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
2139
2143
  variables: Optional[Dict[str, Optional[Any]]] = None,
2140
2144
  ) -> str:
2141
-
2142
2145
  _update_env(working_dir)
2143
2146
 
2144
2147
  if contains_variable(name, "$@&%"):
@@ -2209,7 +2212,6 @@ def get_variables_doc(
2209
2212
  command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
2210
2213
  variables: Optional[Dict[str, Optional[Any]]] = None,
2211
2214
  ) -> VariablesDoc:
2212
-
2213
2215
  import_name: str = name
2214
2216
  stem = Path(name).stem
2215
2217
  module_spec: Optional[ModuleSpec] = None
@@ -2412,7 +2414,11 @@ def get_variables_doc(
2412
2414
  if module_spec is not None and module_spec.origin
2413
2415
  else import_name if is_variables_by_path(import_name) else None
2414
2416
  ),
2415
- 1 if source is not None or module_spec is not None and module_spec.origin is not None else None,
2417
+ (
2418
+ 1
2419
+ if source is not None or (module_spec is not None and module_spec.origin is not None)
2420
+ else None
2421
+ ),
2416
2422
  )
2417
2423
  ]
2418
2424
 
@@ -2432,7 +2438,7 @@ def get_variables_doc(
2432
2438
  if module_spec is not None and module_spec.origin
2433
2439
  else import_name if is_variables_by_path(import_name) else None
2434
2440
  ),
2435
- 1 if source is not None or module_spec is not None and module_spec.origin is not None else None,
2441
+ 1 if source is not None or (module_spec is not None and module_spec.origin is not None) else None,
2436
2442
  )
2437
2443
  ],
2438
2444
  python_path=sys.path,
@@ -2480,7 +2486,7 @@ def is_file_like(name: Optional[str]) -> bool:
2480
2486
  return False
2481
2487
 
2482
2488
  base, filename = os.path.split(name)
2483
- return name.startswith(".") or bool(base) and filename != name
2489
+ return name.startswith(".") or (bool(base) and filename != name)
2484
2490
 
2485
2491
 
2486
2492
  def iter_module_names(name: Optional[str] = None) -> Iterator[str]:
@@ -2522,10 +2528,8 @@ def iter_modules_from_python_path(
2522
2528
  if e.is_dir():
2523
2529
  for f in e.iterdir():
2524
2530
  if not f.name.startswith(("_", ".")) and (
2525
- f.is_file()
2526
- and f.suffix in ALLOWED_LIBRARY_FILE_EXTENSIONS
2527
- or f.is_dir()
2528
- and f.suffix not in NOT_WANTED_DIR_EXTENSIONS
2531
+ (f.is_file() and f.suffix in ALLOWED_LIBRARY_FILE_EXTENSIONS)
2532
+ or (f.is_dir() and f.suffix not in NOT_WANTED_DIR_EXTENSIONS)
2529
2533
  ):
2530
2534
  if f.is_dir():
2531
2535
  yield CompleteResult(f.name, CompleteResultKind.MODULE)
@@ -2586,8 +2590,7 @@ def complete_library_import(
2586
2590
  if not f.name.startswith(("_", "."))
2587
2591
  and (
2588
2592
  (f.is_file() and f.suffix in ALLOWED_LIBRARY_FILE_EXTENSIONS)
2589
- or f.is_dir()
2590
- and f.suffix not in NOT_WANTED_DIR_EXTENSIONS
2593
+ or (f.is_dir() and f.suffix not in NOT_WANTED_DIR_EXTENSIONS)
2591
2594
  )
2592
2595
  ]
2593
2596
 
@@ -2606,10 +2609,8 @@ def iter_resources_from_python_path(
2606
2609
  if e.is_dir():
2607
2610
  for f in e.iterdir():
2608
2611
  if not f.name.startswith(("_", ".")) and (
2609
- f.is_file()
2610
- and f.suffix in ALLOWED_RESOURCE_FILE_EXTENSIONS
2611
- or f.is_dir()
2612
- and f.suffix not in NOT_WANTED_DIR_EXTENSIONS
2612
+ (f.is_file() and f.suffix in ALLOWED_RESOURCE_FILE_EXTENSIONS)
2613
+ or (f.is_dir() and f.suffix not in NOT_WANTED_DIR_EXTENSIONS)
2613
2614
  ):
2614
2615
  yield CompleteResult(
2615
2616
  f.name,
@@ -2633,7 +2634,7 @@ def complete_resource_import(
2633
2634
 
2634
2635
  name = robot_variables.replace_string(name, ignore_errors=True)
2635
2636
 
2636
- if name is None or not name.startswith(".") and not name.startswith("/") and not name.startswith(os.sep):
2637
+ if name is None or (not name.startswith(".") and not name.startswith("/") and not name.startswith(os.sep)):
2637
2638
  result += list(iter_resources_from_python_path(name))
2638
2639
 
2639
2640
  if name is None or name.startswith((".", "/", os.sep)):
@@ -2702,8 +2703,7 @@ def complete_variables_import(
2702
2703
  if not f.name.startswith(("_", "."))
2703
2704
  and (
2704
2705
  (f.is_file() and f.suffix in ALLOWED_VARIABLES_FILE_EXTENSIONS)
2705
- or f.is_dir()
2706
- and f.suffix not in NOT_WANTED_DIR_EXTENSIONS
2706
+ or (f.is_dir() and f.suffix not in NOT_WANTED_DIR_EXTENSIONS)
2707
2707
  )
2708
2708
  ]
2709
2709
 
@@ -749,9 +749,8 @@ class ModelHelper:
749
749
  if argument_token_index < len(tokens) and tokens[argument_token_index].type == Token.ARGUMENT:
750
750
  argument_token = tokens[argument_token_index]
751
751
 
752
- if (
753
- argument_index < 0
754
- or argument_token is not None
752
+ if argument_index < 0 or (
753
+ argument_token is not None
755
754
  and argument_token.type == Token.ARGUMENT
756
755
  and argument_token.value.startswith(("@{", "&{"))
757
756
  and argument_token.value.endswith("}")
@@ -169,7 +169,6 @@ class VariablesVisitor(Visitor):
169
169
 
170
170
 
171
171
  class VariableVisitorBase(Visitor):
172
-
173
172
  def __init__(
174
173
  self,
175
174
  namespace: "Namespace",
@@ -320,7 +319,6 @@ class OnlyArgumentsVisitor(VariableVisitorBase):
320
319
 
321
320
 
322
321
  class BlockVariableVisitor(OnlyArgumentsVisitor):
323
-
324
322
  def visit_ExceptHeader(self, node: Statement) -> None: # noqa: N802
325
323
  variables = node.get_tokens(Token.VARIABLE)[:1]
326
324
  if variables and is_scalar_assign(variables[0].value):
@@ -1468,7 +1466,6 @@ class Namespace:
1468
1466
  parent_import: Optional[Import] = None,
1469
1467
  parent_source: Optional[str] = None,
1470
1468
  ) -> Optional[Dict[str, Any]]:
1471
-
1472
1469
  with self._logger.measure_time(
1473
1470
  lambda: f"loading imports for {self.source if top_level else source}",
1474
1471
  context_name="import",
@@ -1693,7 +1690,6 @@ class Namespace:
1693
1690
  return None
1694
1691
 
1695
1692
  def _import_default_libraries(self, variables: Optional[Dict[str, Any]] = None) -> None:
1696
-
1697
1693
  with self._logger.measure_time(lambda: f"importing default libraries for {self.source}", context_name="import"):
1698
1694
  if variables is None:
1699
1695
  variables = self.get_suite_variables()
@@ -1853,7 +1849,6 @@ class Namespace:
1853
1849
  def get_keywords(self) -> List[KeywordDoc]:
1854
1850
  with self._keywords_lock:
1855
1851
  if self._keywords is None:
1856
-
1857
1852
  i = 0
1858
1853
 
1859
1854
  self.ensure_initialized()
@@ -1880,7 +1875,6 @@ class Namespace:
1880
1875
  related_information: Optional[List[DiagnosticRelatedInformation]] = None,
1881
1876
  data: Optional[Any] = None,
1882
1877
  ) -> None:
1883
-
1884
1878
  self._diagnostics.append(
1885
1879
  Diagnostic(
1886
1880
  range,
@@ -97,7 +97,6 @@ class AnalyzerResult:
97
97
 
98
98
 
99
99
  class NamespaceAnalyzer(Visitor):
100
-
101
100
  _logger = LoggingDescriptor()
102
101
 
103
102
  def __init__(
@@ -222,7 +221,6 @@ class NamespaceAnalyzer(Visitor):
222
221
  add_to_references = True
223
222
  first_overidden_reference: Optional[VariableDefinition] = None
224
223
  if existing_var is not None:
225
-
226
224
  self._variable_references[existing_var].add(Location(self._namespace.document_uri, r))
227
225
  if existing_var not in self._overridden_variables:
228
226
  self._overridden_variables[existing_var] = var_def
@@ -375,7 +373,6 @@ class NamespaceAnalyzer(Visitor):
375
373
  def _analyze_statement_expression_variables(
376
374
  self, node: Statement, severity: DiagnosticSeverity = DiagnosticSeverity.ERROR
377
375
  ) -> None:
378
-
379
376
  for token in node.get_tokens(Token.ARGUMENT):
380
377
  self._analyze_token_variables(token, severity)
381
378
  self._analyze_token_expression_variables(token, severity)
@@ -480,9 +477,13 @@ class NamespaceAnalyzer(Visitor):
480
477
  if var.type == VariableDefinitionType.VARIABLE_NOT_FOUND:
481
478
  self._append_diagnostics(
482
479
  range=range_from_token(var_token),
483
- message=f"Variable '{var.name}' not found.",
480
+ message=(
481
+ f"Variable '{var.name}' not replaced."
482
+ if severity == DiagnosticSeverity.HINT
483
+ else f"Variable '{var.name}' not found."
484
+ ),
484
485
  severity=severity,
485
- code=Error.VARIABLE_NOT_FOUND,
486
+ code=Error.VARIABLE_NOT_REPLACED if severity == DiagnosticSeverity.HINT else Error.VARIABLE_NOT_FOUND,
486
487
  )
487
488
  else:
488
489
  if (
@@ -493,9 +494,17 @@ class NamespaceAnalyzer(Visitor):
493
494
  if os.environ.get(env_name, None) is None:
494
495
  self._append_diagnostics(
495
496
  range=range_from_token(var_token),
496
- message=f"Environment variable '{var.name}' not found.",
497
+ message=(
498
+ f"Environment variable '{var.name}' not replaced."
499
+ if severity == DiagnosticSeverity.HINT
500
+ else f"Environment variable '{var.name}' not found."
501
+ ),
497
502
  severity=severity,
498
- code=Error.ENVIRONMENT_VARIABLE_NOT_FOUND,
503
+ code=(
504
+ Error.ENVIRONMENT_VARIABLE_NOT_REPLACED
505
+ if severity == DiagnosticSeverity.HINT
506
+ else Error.ENVIRONMENT_VARIABLE_NOT_FOUND
507
+ ),
499
508
  )
500
509
 
501
510
  if var.type == VariableDefinitionType.ENVIRONMENT_VARIABLE:
@@ -535,7 +544,6 @@ class NamespaceAnalyzer(Visitor):
535
544
  related_information: Optional[List[DiagnosticRelatedInformation]] = None,
536
545
  data: Optional[Any] = None,
537
546
  ) -> None:
538
-
539
547
  self._diagnostics.append(
540
548
  Diagnostic(
541
549
  range,
@@ -572,10 +580,11 @@ class NamespaceAnalyzer(Visitor):
572
580
  analyze_run_keywords: bool = True,
573
581
  allow_variables: bool = False,
574
582
  ignore_errors_if_contains_variables: bool = False,
583
+ unescape_keyword: bool = True,
575
584
  ) -> Optional[KeywordDoc]:
576
585
  result: Optional[KeywordDoc] = None
577
586
 
578
- keyword = unescape(keyword_token.value)
587
+ keyword = unescape(keyword_token.value) if unescape_keyword else keyword_token.value
579
588
 
580
589
  try:
581
590
  lib_entry = None
@@ -639,7 +648,6 @@ class NamespaceAnalyzer(Visitor):
639
648
  for d in self._finder.multiple_keywords_result:
640
649
  self._keyword_references[d].add(Location(self._namespace.document_uri, kw_range))
641
650
  else:
642
-
643
651
  self._keyword_references[result].add(Location(self._namespace.document_uri, kw_range))
644
652
 
645
653
  if result.errors:
@@ -996,9 +1004,7 @@ class NamespaceAnalyzer(Visitor):
996
1004
  self._analyze_statement_variables(node)
997
1005
 
998
1006
  self._analyze_keyword_call(
999
- node,
1000
- keyword_token,
1001
- [e for e in node.get_tokens(Token.ARGUMENT)],
1007
+ node, keyword_token, [e for e in node.get_tokens(Token.ARGUMENT)], unescape_keyword=False
1002
1008
  )
1003
1009
 
1004
1010
  if not self._current_testcase_or_keyword_name:
@@ -1101,7 +1107,6 @@ class NamespaceAnalyzer(Visitor):
1101
1107
  name_token = node.get_token(Token.KEYWORD_NAME)
1102
1108
 
1103
1109
  if name_token is not None and name_token.value:
1104
-
1105
1110
  for variable_token in filter(
1106
1111
  lambda e: e.type == Token.VARIABLE,
1107
1112
  tokenize_variables(name_token, identifiers="$", ignore_errors=True),
@@ -1459,7 +1464,6 @@ class NamespaceAnalyzer(Visitor):
1459
1464
  if get_robot_version() >= (7, 0):
1460
1465
 
1461
1466
  def visit_ReturnSetting(self, node: Statement) -> None: # noqa: N802
1462
-
1463
1467
  def _handler() -> None:
1464
1468
  self._analyze_statement_variables(node)
1465
1469
 
@@ -1524,7 +1528,6 @@ class NamespaceAnalyzer(Visitor):
1524
1528
  break
1525
1529
 
1526
1530
  def visit_ResourceImport(self, node: ResourceImport) -> None: # noqa: N802
1527
-
1528
1531
  if get_robot_version() >= (6, 1):
1529
1532
  self._check_import_name(node.name, node, "Resource")
1530
1533
 
@@ -1636,7 +1639,6 @@ class NamespaceAnalyzer(Visitor):
1636
1639
  self,
1637
1640
  to: Token,
1638
1641
  ) -> Iterator[Tuple[Token, Optional[VariableDefinition]]]:
1639
-
1640
1642
  def exception_handler(e: BaseException, t: Token) -> None:
1641
1643
  self._append_diagnostics(
1642
1644
  range_from_token(t),
@@ -1687,7 +1689,6 @@ class NamespaceAnalyzer(Visitor):
1687
1689
  yield sub_token_or_var, var_def
1688
1690
 
1689
1691
  def _iter_variables_from_token(self, token: Token) -> Iterator[Tuple[Token, VariableDefinition]]:
1690
-
1691
1692
  if token.type == Token.VARIABLE and token.value.endswith("="):
1692
1693
  match = search_variable(token.value, ignore_errors=True)
1693
1694
  if not match.is_assign(allow_assign_mark=True):
@@ -205,7 +205,7 @@ def get_tokens_at_position(node: Statement, position: Position, include_end: boo
205
205
  return [
206
206
  t
207
207
  for t in node.tokens
208
- if position.is_in_range(range := range_from_token(t), include_end) or include_end and range.end == position
208
+ if position.is_in_range(range := range_from_token(t), include_end) or (include_end and range.end == position)
209
209
  ]
210
210
 
211
211
 
@@ -214,7 +214,7 @@ def iter_nodes_at_position(node: ast.AST, position: Position, include_end: bool
214
214
  yield node
215
215
 
216
216
  for n in iter_nodes(node):
217
- if position.is_in_range(range := range_from_node(n), include_end) or include_end and range.end == position:
217
+ if position.is_in_range(range := range_from_node(n), include_end) or (include_end and range.end == position):
218
218
  yield n
219
219
 
220
220
 
@@ -276,7 +276,7 @@ class ListFormatter(Formatter):
276
276
  _strip_lines = False
277
277
 
278
278
  def _handles(self, line: str) -> bool:
279
- return bool(line.strip().startswith("- ") or line.startswith(" ") and self._lines)
279
+ return bool(line.strip().startswith("- ") or (line.startswith(" ") and self._lines))
280
280
 
281
281
  def format(self, lines: List[str]) -> str:
282
282
  items = ["- %s" % _line_formatter.format(line) for line in self._combine_lines(lines)]
@@ -1 +0,0 @@
1
- __version__ = "0.99.0"