robotcode-robot 0.93.1__py3-none-any.whl → 0.94.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,7 +6,9 @@ import token as python_token
6
6
  from io import StringIO
7
7
  from tokenize import TokenError, generate_tokens
8
8
  from typing import (
9
+ TYPE_CHECKING,
9
10
  Any,
11
+ Callable,
10
12
  Iterator,
11
13
  List,
12
14
  Optional,
@@ -17,6 +19,7 @@ from typing import (
17
19
  Union,
18
20
  )
19
21
 
22
+ from robot.errors import VariableError
20
23
  from robot.parsing.lexer.tokens import Token
21
24
  from robot.utils.escaping import split_from_equals, unescape
22
25
  from robot.variables.finders import NOT_FOUND, NumberFinder
@@ -37,13 +40,16 @@ from .entities import (
37
40
  VariableDefinition,
38
41
  VariableNotFoundDefinition,
39
42
  )
43
+ from .keyword_finder import DEFAULT_BDD_PREFIXES
40
44
  from .library_doc import (
41
45
  ArgumentInfo,
42
46
  KeywordArgumentKind,
43
47
  KeywordDoc,
44
48
  LibraryDoc,
45
49
  )
46
- from .namespace import DEFAULT_BDD_PREFIXES, Namespace
50
+
51
+ if TYPE_CHECKING:
52
+ from .namespace import Namespace
47
53
 
48
54
 
49
55
  class ModelHelper:
@@ -52,7 +58,7 @@ class ModelHelper:
52
58
  cls,
53
59
  keyword_doc: Optional[KeywordDoc],
54
60
  argument_tokens: List[Token],
55
- namespace: Namespace,
61
+ namespace: "Namespace",
56
62
  position: Position,
57
63
  ) -> Tuple[Optional[Tuple[Optional[KeywordDoc], Token]], List[Token]]:
58
64
  if keyword_doc is None or not keyword_doc.is_any_run_keyword():
@@ -200,7 +206,7 @@ class ModelHelper:
200
206
  keyword_name: Optional[str],
201
207
  keyword_token: Token,
202
208
  argument_tokens: List[Token],
203
- namespace: Namespace,
209
+ namespace: "Namespace",
204
210
  position: Position,
205
211
  analyse_run_keywords: bool = True,
206
212
  ) -> Optional[Tuple[Optional[KeywordDoc], Token]]:
@@ -222,7 +228,7 @@ class ModelHelper:
222
228
 
223
229
  @classmethod
224
230
  def get_namespace_info_from_keyword_token(
225
- cls, namespace: Namespace, keyword_token: Token
231
+ cls, namespace: "Namespace", keyword_token: Token
226
232
  ) -> Tuple[Optional[LibraryEntry], Optional[str]]:
227
233
  lib_entry: Optional[LibraryEntry] = None
228
234
  kw_namespace: Optional[str] = None
@@ -243,7 +249,7 @@ class ModelHelper:
243
249
 
244
250
  return lib_entry, kw_namespace
245
251
 
246
- __match_extended = re.compile(
252
+ match_extended = re.compile(
247
253
  r"""
248
254
  (.+?) # base name (group 1)
249
255
  ([^\s\w].+) # extended part (group 2)
@@ -254,7 +260,7 @@ class ModelHelper:
254
260
  @staticmethod
255
261
  def iter_expression_variables_from_token(
256
262
  expression: Token,
257
- namespace: Namespace,
263
+ namespace: "Namespace",
258
264
  nodes: Optional[List[ast.AST]],
259
265
  position: Optional[Position] = None,
260
266
  skip_commandline_variables: bool = False,
@@ -354,27 +360,36 @@ class ModelHelper:
354
360
  ignore_errors: bool = False,
355
361
  *,
356
362
  extra_types: Optional[Set[str]] = None,
363
+ exception_handler: Optional[Callable[[Exception, Token], None]] = None,
357
364
  ) -> Iterator[Token]:
358
- for t in tokenize_variables(token, identifiers, ignore_errors, extra_types=extra_types):
359
- if t.type == Token.VARIABLE:
360
- var, rest = cls.remove_index_from_variable_token(t)
361
- if var is not None:
362
- yield var
363
- if rest is not None:
364
- yield from cls.tokenize_variables(
365
- rest,
366
- identifiers,
367
- ignore_errors,
368
- extra_types=extra_types,
369
- )
370
- else:
371
- yield t
365
+ if exception_handler is not None:
366
+ ignore_errors = False
367
+ try:
368
+ for t in tokenize_variables(token, identifiers, ignore_errors, extra_types=extra_types):
369
+ if t.type == Token.VARIABLE:
370
+ var, rest = cls.remove_index_from_variable_token(t)
371
+ if var is not None:
372
+ yield var
373
+ if rest is not None:
374
+ yield from cls.tokenize_variables(
375
+ rest,
376
+ identifiers,
377
+ ignore_errors,
378
+ extra_types=extra_types,
379
+ )
380
+ else:
381
+ yield t
382
+ except VariableError as e:
383
+ if exception_handler is not None:
384
+ exception_handler(e, token)
385
+ elif not ignore_errors:
386
+ raise
372
387
 
373
388
  @classmethod
374
389
  def iter_variables_from_token(
375
390
  cls,
376
391
  token: Token,
377
- namespace: Namespace,
392
+ namespace: "Namespace",
378
393
  nodes: Optional[List[ast.AST]],
379
394
  position: Optional[Position] = None,
380
395
  skip_commandline_variables: bool = False,
@@ -413,7 +428,7 @@ class ModelHelper:
413
428
  ):
414
429
  yield v
415
430
  elif base == "" and return_not_found:
416
- yield (
431
+ yield ( # TODO: robotframework ignores this case, should we do the same or raise an error/hint?
417
432
  sub_token,
418
433
  VariableNotFoundDefinition(
419
434
  sub_token.lineno,
@@ -481,7 +496,7 @@ class ModelHelper:
481
496
  and sub_token.value[1:2] == "{"
482
497
  and sub_token.value[-1:] == "}"
483
498
  ):
484
- match = cls.__match_extended.match(name[2:-1])
499
+ match = cls.match_extended.match(name[2:-1])
485
500
  if match is not None:
486
501
  base_name, _ = match.groups()
487
502
  name = f"{name[0]}{{{base_name.strip()}}}"
@@ -557,7 +572,7 @@ class ModelHelper:
557
572
  BDD_TOKEN = re.compile(r"^(Given|When|Then|And|But)$", flags=re.IGNORECASE)
558
573
 
559
574
  @classmethod
560
- def split_bdd_prefix(cls, namespace: Namespace, token: Token) -> Tuple[Optional[Token], Optional[Token]]:
575
+ def split_bdd_prefix(cls, namespace: "Namespace", token: Token) -> Tuple[Optional[Token], Optional[Token]]:
561
576
  bdd_token = None
562
577
 
563
578
  parts = token.value.split()
@@ -590,7 +605,7 @@ class ModelHelper:
590
605
  return bdd_token, token
591
606
 
592
607
  @classmethod
593
- def strip_bdd_prefix(cls, namespace: Namespace, token: Token) -> Token:
608
+ def strip_bdd_prefix(cls, namespace: "Namespace", token: Token) -> Token:
594
609
  if get_robot_version() < (6, 0):
595
610
  bdd_match = cls.BDD_TOKEN_REGEX.match(token.value)
596
611
  if bdd_match:
@@ -627,7 +642,7 @@ class ModelHelper:
627
642
  return token
628
643
 
629
644
  @classmethod
630
- def is_bdd_token(cls, namespace: Namespace, token: Token) -> bool:
645
+ def is_bdd_token(cls, namespace: "Namespace", token: Token) -> bool:
631
646
  if get_robot_version() < (6, 0):
632
647
  bdd_match = cls.BDD_TOKEN.match(token.value)
633
648
  return bool(bdd_match)
@@ -651,7 +666,7 @@ class ModelHelper:
651
666
  @classmethod
652
667
  def get_keyword_definition_at_line(cls, library_doc: LibraryDoc, value: str, line: int) -> Optional[KeywordDoc]:
653
668
  return next(
654
- (k for k in library_doc.keywords.get_all(value) if k.line_no == line),
669
+ (k for k in library_doc.keywords.iter_all(value) if k.line_no == line),
655
670
  None,
656
671
  )
657
672