robotcode-robot 0.77.1__py3-none-any.whl → 0.78.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- __version__ = "0.77.1"
1
+ __version__ = "0.78.1"
@@ -16,6 +16,7 @@ from typing import (
16
16
  List,
17
17
  Literal,
18
18
  Optional,
19
+ Set,
19
20
  Tuple,
20
21
  Union,
21
22
  get_type_hints,
@@ -2264,6 +2265,9 @@ class RobotExtendBaseProfile(RobotBaseProfile):
2264
2265
  class RobotProfile(RobotExtendBaseProfile):
2265
2266
  """Robot Framework configuration profile."""
2266
2267
 
2268
+ def __hash__(self) -> int:
2269
+ return id(self)
2270
+
2267
2271
  description: Optional[str] = field(description="Description of the profile.")
2268
2272
 
2269
2273
  detached: Optional[bool] = field(
@@ -2291,6 +2295,9 @@ class RobotProfile(RobotExtendBaseProfile):
2291
2295
  """
2292
2296
  )
2293
2297
 
2298
+ def is_enabled(self) -> bool:
2299
+ return self.enabled is None or bool(self.enabled)
2300
+
2294
2301
  hidden: Union[bool, Condition, None] = field(
2295
2302
  description="""\
2296
2303
  The profile should be hidden.
@@ -2349,13 +2356,13 @@ class RobotConfig(RobotExtendBaseProfile):
2349
2356
 
2350
2357
  tool: Any = field(description="Tool configurations.")
2351
2358
 
2352
- def select_profiles(
2359
+ def _select_profiles(
2353
2360
  self,
2354
2361
  *names: str,
2355
2362
  verbose_callback: Optional[Callable[[Union[str, Callable[[], Any]]], None]] = None,
2356
2363
  error_callback: Optional[Callable[[Union[str, Callable[[], Any]]], None]] = None,
2357
- ) -> Dict[str, RobotProfile]:
2358
- result: Dict[str, RobotProfile] = {}
2364
+ ) -> Dict[str, Tuple[RobotProfile, Optional[Set[Tuple[str, RobotProfile]]]]]:
2365
+ result: Dict[str, Tuple[RobotProfile, Optional[Set[Tuple[str, RobotProfile]]]]] = {}
2359
2366
 
2360
2367
  profiles = self.profiles or {}
2361
2368
 
@@ -2372,14 +2379,20 @@ class RobotConfig(RobotExtendBaseProfile):
2372
2379
 
2373
2380
  names = (*(default_profile or ()),)
2374
2381
 
2375
- def select(name: str) -> None:
2382
+ def select(name: str, parent_profiles: Optional[Set[Tuple[str, RobotProfile]]] = None) -> None:
2376
2383
  if not name:
2377
2384
  return
2378
2385
 
2379
2386
  nonlocal result
2380
2387
 
2381
2388
  if verbose_callback:
2382
- verbose_callback(f"Selecting profiles matching '{name}'.")
2389
+ if parent_profiles is not None:
2390
+ verbose_callback(
2391
+ f"Selecting profiles matching '{name}'"
2392
+ f" for parent profile '{next(f for f in parent_profiles)[0]}'."
2393
+ )
2394
+ else:
2395
+ verbose_callback(f"Selecting profiles matching '{name}'.")
2383
2396
 
2384
2397
  profile_names = [p for p in profiles.keys() if fnmatch.fnmatchcase(p, name)]
2385
2398
 
@@ -2393,13 +2406,24 @@ class RobotConfig(RobotExtendBaseProfile):
2393
2406
 
2394
2407
  for v in profile_names:
2395
2408
  p = profiles[v]
2396
- result.update({v: p})
2409
+
2397
2410
  if p.inherits:
2398
2411
  if isinstance(p.inherits, list):
2399
2412
  for i in p.inherits:
2400
- select(str(i))
2413
+ select(str(i), {(v, p)})
2414
+ else:
2415
+ select(str(p.inherits), {(v, p)})
2416
+
2417
+ if v in result:
2418
+ if parent_profiles is None:
2419
+ result[v] = (p, None)
2401
2420
  else:
2402
- select(str(p.inherits))
2421
+ parents = result[v][1]
2422
+ if parents is not None:
2423
+ parents.update(parent_profiles)
2424
+
2425
+ else:
2426
+ result.update({v: (p, parent_profiles)})
2403
2427
 
2404
2428
  for name in names:
2405
2429
  select(name)
@@ -2438,7 +2462,7 @@ class RobotConfig(RobotExtendBaseProfile):
2438
2462
  }
2439
2463
  )
2440
2464
 
2441
- selected_profiles = self.select_profiles(
2465
+ selected_profiles = self._select_profiles(
2442
2466
  *names, verbose_callback=verbose_callback, error_callback=error_callback
2443
2467
  )
2444
2468
  if verbose_callback:
@@ -2447,14 +2471,16 @@ class RobotConfig(RobotExtendBaseProfile):
2447
2471
  else:
2448
2472
  verbose_callback("No profiles selected.")
2449
2473
 
2450
- for profile_name, profile in sorted(selected_profiles.items(), key=lambda x: x[1].precedence or 0):
2474
+ for profile_name, (profile, parent_profiles) in sorted(
2475
+ selected_profiles.items(), key=lambda x: x[1][0].precedence or 0
2476
+ ):
2451
2477
  try:
2452
- if profile.enabled is not None and not bool(profile.enabled):
2478
+ if not profile.is_enabled():
2453
2479
  if verbose_callback:
2454
2480
  verbose_callback(f'Skipping profile "{profile_name}" because it\'s disabled.')
2455
2481
  continue
2456
2482
  except EvaluationError as e:
2457
- message = f'Error evaluating "enabled" condition for profile "{profile_name}": {e}'
2483
+ message = f"Error evaluating 'enabled' condition for profile '{profile_name}': {e}"
2458
2484
 
2459
2485
  if error_callback is None:
2460
2486
  raise ValueError(message) from e
@@ -2462,6 +2488,31 @@ class RobotConfig(RobotExtendBaseProfile):
2462
2488
  error_callback(message)
2463
2489
  continue
2464
2490
 
2491
+ if parent_profiles is not None:
2492
+ disabled_profiles = []
2493
+ skip = False
2494
+ for parent_profile in parent_profiles:
2495
+ try:
2496
+ if not parent_profile[1].is_enabled():
2497
+ disabled_profiles.append(parent_profile[0])
2498
+ except EvaluationError as e:
2499
+ message = f"Error evaluating 'enabled' condition for profile '{parent_profile[0]}': {e}"
2500
+
2501
+ if error_callback is None:
2502
+ raise ValueError(message) from e
2503
+
2504
+ error_callback(message)
2505
+ skip = True
2506
+ break
2507
+
2508
+ if skip or len(disabled_profiles) == len(parent_profiles):
2509
+ if verbose_callback:
2510
+ verbose_callback(
2511
+ f"Skipping profile inherited '{profile_name}' because no parent is enabled."
2512
+ f" Disabled profiles: {', '.join(disabled_profiles)}."
2513
+ )
2514
+ continue
2515
+
2465
2516
  if verbose_callback:
2466
2517
  verbose_callback(f'Using profile "{profile_name}".')
2467
2518
 
@@ -2471,7 +2522,7 @@ class RobotConfig(RobotExtendBaseProfile):
2471
2522
  for k, v in profile.env.items():
2472
2523
  os.environ[k] = str(v)
2473
2524
  if verbose_callback:
2474
- verbose_callback(lambda: f"Set environment variable `{k}` to `{v}`")
2525
+ verbose_callback(lambda: f"Set environment variable '{k}' to '{v}'")
2475
2526
 
2476
2527
  if profile.detached:
2477
2528
  result = RobotBaseProfile()
@@ -2520,4 +2571,4 @@ class RobotConfig(RobotExtendBaseProfile):
2520
2571
  if new is not None:
2521
2572
  setattr(result, f.name, new)
2522
2573
 
2523
- return result, selected_profiles, enabled_profiles
2574
+ return result, {k: v[0] for k, v in selected_profiles.items()}, enabled_profiles
@@ -155,6 +155,9 @@ class VariableMatcher:
155
155
  if isinstance(o, str):
156
156
  match = search_variable(o, "$@&%", ignore_errors=True)
157
157
  base = match.base
158
+ if base is None:
159
+ return False
160
+
158
161
  normalized = str(normalize(base))
159
162
  return self.normalized_name == normalized
160
163
 
@@ -99,6 +99,7 @@ from .library_doc import (
99
99
  KeywordError,
100
100
  KeywordMatcher,
101
101
  LibraryDoc,
102
+ resolve_robot_variables,
102
103
  )
103
104
 
104
105
  EXTRACT_COMMENT_PATTERN = re.compile(r".*(?:^ *|\t+| {2,})#(?P<comment>.*)$")
@@ -184,22 +185,19 @@ class VariablesVisitor(Visitor):
184
185
  class BlockVariableVisitor(Visitor):
185
186
  def __init__(
186
187
  self,
187
- library_doc: LibraryDoc,
188
- global_variables: List[VariableDefinition],
189
- source: str,
188
+ namespace: "Namespace",
189
+ nodes: Optional[List[ast.AST]] = None,
190
190
  position: Optional[Position] = None,
191
191
  in_args: bool = True,
192
192
  ) -> None:
193
193
  super().__init__()
194
- self.library_doc = library_doc
195
- self.global_variables = global_variables
196
- self.source = source
194
+ self.namespace = namespace
195
+ self.nodes = nodes
197
196
  self.position = position
198
197
  self.in_args = in_args
199
198
 
200
199
  self._results: Dict[str, VariableDefinition] = {}
201
200
  self.current_kw_doc: Optional[KeywordDoc] = None
202
- self._var_statements_vars: List[VariableDefinition] = []
203
201
 
204
202
  def get(self, model: ast.AST) -> List[VariableDefinition]:
205
203
  self._results = {}
@@ -224,7 +222,7 @@ class BlockVariableVisitor(Visitor):
224
222
  name_token = node.get_token(Token.KEYWORD_NAME)
225
223
 
226
224
  if name_token is not None and name_token.value:
227
- keyword = ModelHelper.get_keyword_definition_at_token(self.library_doc, name_token)
225
+ keyword = ModelHelper.get_keyword_definition_at_token(self.namespace.get_library_doc(), name_token)
228
226
  self.current_kw_doc = keyword
229
227
 
230
228
  for variable_token in filter(
@@ -246,7 +244,7 @@ class BlockVariableVisitor(Visitor):
246
244
  col_offset=variable_token.col_offset,
247
245
  end_line_no=variable_token.lineno,
248
246
  end_col_offset=variable_token.end_col_offset,
249
- source=self.source,
247
+ source=self.namespace.source,
250
248
  keyword_doc=self.current_kw_doc,
251
249
  )
252
250
 
@@ -290,7 +288,7 @@ class BlockVariableVisitor(Visitor):
290
288
  col_offset=argument.col_offset,
291
289
  end_line_no=argument.lineno,
292
290
  end_col_offset=argument.end_col_offset,
293
- source=self.source,
291
+ source=self.namespace.source,
294
292
  keyword_doc=self.current_kw_doc,
295
293
  )
296
294
  self._results[argument.value] = arg_def
@@ -312,12 +310,48 @@ class BlockVariableVisitor(Visitor):
312
310
  col_offset=variable.col_offset,
313
311
  end_line_no=variable.lineno,
314
312
  end_col_offset=variable.end_col_offset,
315
- source=self.source,
313
+ source=self.namespace.source,
316
314
  )
317
315
 
318
316
  except VariableError:
319
317
  pass
320
318
 
319
+ def _get_var_name(self, original: str, position: Position, require_assign: bool = True) -> Optional[str]:
320
+ robot_variables = resolve_robot_variables(
321
+ str(self.namespace.imports_manager.root_folder),
322
+ str(Path(self.namespace.source).parent) if self.namespace.source else ".",
323
+ self.namespace.imports_manager.get_resolvable_command_line_variables(),
324
+ variables=self.namespace.get_resolvable_variables(),
325
+ )
326
+
327
+ try:
328
+ replaced = robot_variables.replace_string(original)
329
+ except VariableError:
330
+ replaced = original
331
+ try:
332
+ name = self._resolve_var_name(replaced, robot_variables)
333
+ except ValueError:
334
+ name = original
335
+ match = search_variable(name, identifiers="$@&")
336
+ match.resolve_base(robot_variables)
337
+ valid = match.is_assign() if require_assign else match.is_variable()
338
+ if not valid:
339
+ return None
340
+ return str(match)
341
+
342
+ def _resolve_var_name(self, name: str, variables: Any) -> str:
343
+ if name.startswith("\\"):
344
+ name = name[1:]
345
+ if len(name) < 2 or name[0] not in "$@&":
346
+ raise ValueError
347
+ if name[1] != "{":
348
+ name = f"{name[0]}{{{name[1:]}}}"
349
+ match = search_variable(name, identifiers="$@&", ignore_errors=True)
350
+ match.resolve_base(variables)
351
+ if not match.is_assign():
352
+ raise ValueError
353
+ return str(match)
354
+
321
355
  def visit_KeywordCall(self, node: Statement) -> None: # noqa: N802
322
356
  # TODO analyze "Set Local/Global/Suite Variable"
323
357
 
@@ -341,12 +375,65 @@ class BlockVariableVisitor(Visitor):
341
375
  col_offset=variable_token.col_offset,
342
376
  end_line_no=variable_token.lineno,
343
377
  end_col_offset=variable_token.end_col_offset,
344
- source=self.source,
378
+ source=self.namespace.source,
345
379
  )
346
380
 
347
381
  except VariableError:
348
382
  pass
349
383
 
384
+ keyword_token = node.get_token(Token.KEYWORD)
385
+ if keyword_token is None or not keyword_token.value:
386
+ return
387
+
388
+ keyword = self.namespace.find_keyword(keyword_token.value, raise_keyword_error=False)
389
+ if keyword is None:
390
+ return
391
+
392
+ if keyword.libtype == "LIBRARY" and keyword.libname == "BuiltIn":
393
+ var_type = None
394
+ if keyword.name == "Set Suite Variable":
395
+ var_type = VariableDefinition
396
+ elif keyword.name == "Set Global Variable":
397
+ var_type = GlobalVariableDefinition
398
+ elif keyword.name == "Set Test Variable" or keyword.name == "Set Task Variable":
399
+ var_type = TestVariableDefinition
400
+ elif keyword.name == "Set Local Variable":
401
+ var_type = LocalVariableDefinition
402
+ else:
403
+ return
404
+ try:
405
+ variable = node.get_token(Token.ARGUMENT)
406
+ if variable is None:
407
+ return
408
+
409
+ position = range_from_node(node).start
410
+ position.character = 0
411
+ var_name = self._get_var_name(variable.value, position)
412
+
413
+ if var_name is None or not is_variable(var_name):
414
+ return
415
+
416
+ var = var_type(
417
+ name=var_name,
418
+ name_token=strip_variable_token(variable),
419
+ line_no=variable.lineno,
420
+ col_offset=variable.col_offset,
421
+ end_line_no=variable.lineno,
422
+ end_col_offset=variable.end_col_offset,
423
+ source=self.namespace.source,
424
+ )
425
+
426
+ if var_name not in self._results or type(self._results[var_name]) != type(var):
427
+ if isinstance(var, LocalVariableDefinition) or not any(
428
+ l for l in self.namespace.get_global_variables() if l.matcher == var.matcher
429
+ ):
430
+ self._results[var_name] = var
431
+ else:
432
+ self._results.pop(var_name, None)
433
+
434
+ except VariableError:
435
+ pass
436
+
350
437
  def visit_InlineIfHeader(self, node: Statement) -> None: # noqa: N802
351
438
  for assign_token in node.get_tokens(Token.ASSIGN):
352
439
  variable_token = self.get_variable_token(assign_token)
@@ -368,7 +455,7 @@ class BlockVariableVisitor(Visitor):
368
455
  col_offset=variable_token.col_offset,
369
456
  end_line_no=variable_token.lineno,
370
457
  end_col_offset=variable_token.end_col_offset,
371
- source=self.source,
458
+ source=self.namespace.source,
372
459
  )
373
460
 
374
461
  except VariableError:
@@ -386,7 +473,7 @@ class BlockVariableVisitor(Visitor):
386
473
  col_offset=variable_token.col_offset,
387
474
  end_line_no=variable_token.lineno,
388
475
  end_col_offset=variable_token.end_col_offset,
389
- source=self.source,
476
+ source=self.namespace.source,
390
477
  )
391
478
 
392
479
  def visit_Var(self, node: Statement) -> None: # noqa: N802
@@ -421,14 +508,12 @@ class BlockVariableVisitor(Visitor):
421
508
  col_offset=variable.col_offset,
422
509
  end_line_no=variable.lineno,
423
510
  end_col_offset=variable.end_col_offset,
424
- source=self.source,
511
+ source=self.namespace.source,
425
512
  )
426
513
 
427
- self._var_statements_vars.append(var)
428
-
429
514
  if var_name not in self._results or type(self._results[var_name]) != type(var):
430
515
  if isinstance(var, LocalVariableDefinition) or not any(
431
- l for l in self.global_variables if l.matcher == var.matcher
516
+ l for l in self.namespace.get_global_variables() if l.matcher == var.matcher
432
517
  ):
433
518
  self._results[var_name] = var
434
519
  else:
@@ -924,9 +1009,8 @@ class Namespace:
924
1009
  (
925
1010
  (
926
1011
  BlockVariableVisitor(
927
- self.get_library_doc(),
928
- self.get_global_variables(),
929
- self.source,
1012
+ self,
1013
+ nodes,
930
1014
  position,
931
1015
  isinstance(test_or_keyword_nodes[-1], Arguments) if nodes else False,
932
1016
  ).get(test_or_keyword)
@@ -1039,6 +1123,7 @@ class Namespace:
1039
1123
  top_level: bool = False,
1040
1124
  source: Optional[str] = None,
1041
1125
  parent_import: Optional[Import] = None,
1126
+ parent_source: Optional[str] = None,
1042
1127
  ) -> Optional[LibraryEntry]:
1043
1128
  result: Optional[LibraryEntry] = None
1044
1129
  try:
@@ -1220,6 +1305,26 @@ class Namespace:
1220
1305
  source=DIAGNOSTICS_SOURCE_NAME,
1221
1306
  code=type(e).__qualname__,
1222
1307
  )
1308
+ elif parent_import is not None:
1309
+ self.append_diagnostics(
1310
+ range=parent_import.range,
1311
+ message="Import definition contains errors.",
1312
+ severity=DiagnosticSeverity.ERROR,
1313
+ source=DIAGNOSTICS_SOURCE_NAME,
1314
+ code=Error.IMPORT_CONTAINS_ERRORS,
1315
+ related_information=(
1316
+ (
1317
+ [
1318
+ DiagnosticRelatedInformation(
1319
+ location=Location(str(Uri.from_path(parent_source)), value.range),
1320
+ message=str(e),
1321
+ ),
1322
+ ]
1323
+ )
1324
+ if parent_source
1325
+ else None
1326
+ ),
1327
+ )
1223
1328
  finally:
1224
1329
  self._reset_global_variables()
1225
1330
 
@@ -1234,6 +1339,7 @@ class Namespace:
1234
1339
  variables: Optional[Dict[str, Any]] = None,
1235
1340
  source: Optional[str] = None,
1236
1341
  parent_import: Optional[Import] = None,
1342
+ parent_source: Optional[str] = None,
1237
1343
  depth: int = 0,
1238
1344
  ) -> Optional[Dict[str, Any]]:
1239
1345
 
@@ -1251,6 +1357,7 @@ class Namespace:
1251
1357
  top_level=top_level,
1252
1358
  source=source,
1253
1359
  parent_import=parent_import,
1360
+ parent_source=parent_source if parent_source else source,
1254
1361
  )
1255
1362
 
1256
1363
  if entry is not None:
@@ -1274,6 +1381,7 @@ class Namespace:
1274
1381
  variables=variables,
1275
1382
  source=entry.library_doc.source,
1276
1383
  parent_import=imp if top_level else parent_import,
1384
+ parent_source=parent_source if top_level else source,
1277
1385
  depth=depth + 1,
1278
1386
  )
1279
1387
  except (SystemExit, KeyboardInterrupt):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robotcode-robot
3
- Version: 0.77.1
3
+ Version: 0.78.1
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://github.com/sponsors/d-biehl
@@ -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.77.1
29
+ Requires-Dist: robotcode-core==0.78.1
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,18 +1,18 @@
1
1
  robotcode/robot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- robotcode/robot/__version__.py,sha256=KAGTP0ql_FPeQE1WIVlTa-PVmeudJNxVGVpT_IPdAEg,23
2
+ robotcode/robot/__version__.py,sha256=HinYe1V3FgUaLri1gy6R6_VuKh3sB-UYTNM51cV6k4I,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
6
- robotcode/robot/config/model.py,sha256=QzniYg-pxQucKJDg7_lSodWg6DKwhTaVf_wN3biUXCk,86499
6
+ robotcode/robot/config/model.py,sha256=LReuQ0Z8zYEYW9XLjnyR2hSUn8upbWzbh8VTTBIRQig,88642
7
7
  robotcode/robot/config/utils.py,sha256=c_WZg39DJgM6kXcAH_h-v68qhf1eStJ0TslTawaJoZw,2827
8
8
  robotcode/robot/diagnostics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  robotcode/robot/diagnostics/document_cache_helper.py,sha256=XLOqPl88Rbo_01pt8Zx2jMH38m5kvoOnASNDoe8BK_0,22292
10
- robotcode/robot/diagnostics/entities.py,sha256=djUbkVSLmwlg9E-jvW_jw7h6yjpSl6YmTpDDzUNB0-8,11051
10
+ robotcode/robot/diagnostics/entities.py,sha256=CrjhLHHwKCCE3YI_dcjoZADJz1urm0VGbGFdHXOuaoc,11110
11
11
  robotcode/robot/diagnostics/errors.py,sha256=VavgWYuHoW5sTT16j2rl9hxMhWxBKNSFsNmHWPzARQQ,1413
12
12
  robotcode/robot/diagnostics/imports_manager.py,sha256=eMt3Quac1hV5zq6CO45afhUOiL4usww3YTNSyt1bZrE,56185
13
13
  robotcode/robot/diagnostics/library_doc.py,sha256=ZhoJIscHIx0UaLWm56LEoa3oxR0uNZourZsnpvOg-Hs,97035
14
14
  robotcode/robot/diagnostics/model_helper.py,sha256=3-6lZluPQaT9KstHLfV0jsRUAjTfrkUOomSXiMPKoQg,29868
15
- robotcode/robot/diagnostics/namespace.py,sha256=EhbHHX2c-Yy_j1YBzC6PFxNVCY50E2LB3kGOT-qgDZ4,85145
15
+ robotcode/robot/diagnostics/namespace.py,sha256=yerha8VmX_01h8Ga7MaH4wRVk1waVQ4pJfPu55ohcYU,89792
16
16
  robotcode/robot/diagnostics/namespace_analyzer.py,sha256=tElI2NzcCRnsvPqv7wYaV2p5E22VyqEwQQ90FOOjadI,50086
17
17
  robotcode/robot/diagnostics/workspace_config.py,sha256=lWNq1KmGGJ9cHFNHn0QTCBHHzgz4AewTw0l-W4TKrj0,1803
18
18
  robotcode/robot/utils/__init__.py,sha256=OjNPMn_XSnfaMCyKd8Kmq6vlRt6mIGlzW4qiiD3ykUg,447
@@ -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.77.1.dist-info/METADATA,sha256=qvOHq_EZVfXNrKxxgy2gr2udDF06euy9IidbrVaBmYQ,2209
27
- robotcode_robot-0.77.1.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
28
- robotcode_robot-0.77.1.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
29
- robotcode_robot-0.77.1.dist-info/RECORD,,
26
+ robotcode_robot-0.78.1.dist-info/METADATA,sha256=v5pSI5CijBpAZYaOJTl0jdCgjhavFlZDydZi_LkF3JU,2209
27
+ robotcode_robot-0.78.1.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
28
+ robotcode_robot-0.78.1.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
29
+ robotcode_robot-0.78.1.dist-info/RECORD,,