72
72
)
73
73
from .id_manager import IdManager
74
74
75
+ if get_robot_version () >= (5 , 0 ):
76
+ from robot .running .model import Try
77
+ from robot .utils import Matcher as RobotMatcher
78
+
75
79
if get_robot_version () >= (7 , 0 ):
76
80
from robot .running import UserKeyword as UserKeywordHandler
77
81
else :
@@ -1202,12 +1206,8 @@ def _get_matcher(self, pattern_type: str) -> Optional[Callable[[str, str], bool]
1202
1206
1203
1207
def _glob_matcher (self , message : str , pattern : str ) -> bool :
1204
1208
"""Optimized glob matcher with cached Robot Matcher."""
1205
- if self .__robot_matcher is None :
1206
- from robot .utils import Matcher
1207
-
1208
- self .__robot_matcher = Matcher
1209
1209
1210
- return bool (self . __robot_matcher (pattern , spaceless = False , caseless = False ).match (message ))
1210
+ return bool (RobotMatcher (pattern , spaceless = False , caseless = False ).match (message ))
1211
1211
1212
1212
def _regexp_matcher (self , message : str , pattern : str ) -> bool :
1213
1213
"""Optimized regex matcher with LRU caching (max 25 entries)."""
@@ -1259,14 +1259,21 @@ def _get_step_data(self, step: Any) -> Any:
1259
1259
def _get_step_data (self , step : Any ) -> Any :
1260
1260
return step .data
1261
1261
1262
- def is_not_caugthed_by_except (self , message : Optional [str ]) -> bool :
1263
- if not message :
1264
- return True
1262
+ if get_robot_version () < (5 , 0 ):
1263
+
1264
+ def is_not_caugthed_by_except (self , message : Optional [str ]) -> bool :
1265
+ if not message :
1266
+ return True
1267
+ return False
1268
+ else :
1265
1269
1266
- if self . debug_logger :
1267
- if get_robot_version () >= ( 5 , 0 ) :
1268
- from robot . running . model import Try
1270
+ def is_not_caugthed_by_except ( self , message : Optional [ str ]) -> bool :
1271
+ if not message :
1272
+ return True
1269
1273
1274
+ # TODO resolve variables in exception message
1275
+
1276
+ if self .debug_logger :
1270
1277
if self .debug_logger .steps :
1271
1278
for branch in [
1272
1279
self ._get_step_data (f )
@@ -1276,7 +1283,7 @@ def is_not_caugthed_by_except(self, message: Optional[str]) -> bool:
1276
1283
for except_branch in branch .except_branches :
1277
1284
if self ._should_run_except (except_branch , message ):
1278
1285
return False
1279
- return True
1286
+ return True
1280
1287
1281
1288
def end_keyword (self , name : str , attributes : AttributeDict ) -> None :
1282
1289
if self .state == State .CallKeyword :
@@ -1610,131 +1617,143 @@ def get_variables(
1610
1617
count : Optional [int ] = None ,
1611
1618
format : Optional [ValueFormat ] = None ,
1612
1619
) -> List [Variable ]:
1613
- result : MutableMapping [str , Any ] = {}
1614
-
1615
1620
if filter is None :
1616
- entry = next (
1617
- (
1618
- v
1619
- for v in self .stack_frames
1620
- if variables_reference in [v .global_id , v .suite_id , v .test_id , v .local_id ]
1621
- ),
1622
- None ,
1623
- )
1624
- if entry is not None :
1625
- context = entry .context ()
1626
- if context is not None :
1627
- if entry .global_id == variables_reference :
1628
- result .update (
1629
- {k : self ._create_variable (k , v ) for k , v in context .variables ._global .as_dict ().items ()}
1630
- )
1631
- elif entry .suite_id == variables_reference :
1632
- globals = context .variables ._global .as_dict ()
1633
- vars = entry .get_first_or_self ().variables ()
1634
- vars_dict = vars .as_dict () if vars is not None else {}
1635
- result .update (
1636
- {
1637
- k : self ._create_variable (k , v )
1638
- for k , v in context .variables ._suite .as_dict ().items ()
1639
- if (k not in globals or globals [k ] != v ) and (k in vars_dict )
1640
- }
1641
- )
1642
- elif entry .test_id == variables_reference :
1643
- globals = context .variables ._suite .as_dict ()
1644
- vars = entry .get_first_or_self ().variables ()
1645
- vars_dict = vars .as_dict () if vars is not None else {}
1646
- result .update (
1647
- {
1648
- k : self ._create_variable (k , v )
1649
- for k , v in context .variables ._test .as_dict ().items ()
1650
- if (k not in globals or globals [k ] != v ) and (k in vars_dict )
1651
- }
1652
- )
1653
- elif entry .local_id == variables_reference :
1654
- vars = entry .get_first_or_self ().variables ()
1655
-
1656
- if self ._current_exception is not None :
1657
- result ["${EXCEPTION}" ] = self ._create_variable (
1658
- "${EXCEPTION}" ,
1659
- self ._current_exception ,
1660
- VariablePresentationHint (kind = "virtual" ),
1661
- )
1662
-
1663
- if vars is not None :
1664
- p = entry .parent () if entry .parent else None
1665
-
1666
- globals = (
1667
- (p .get_first_or_self ().variables () if p is not None else None )
1668
- or context .variables ._test
1669
- or context .variables ._suite
1670
- or context .variables ._global
1671
- ).as_dict ()
1672
-
1673
- suite_vars = (context .variables ._suite or context .variables ._global ).as_dict ()
1674
-
1675
- result .update (
1676
- {
1677
- k : self ._create_variable (k , v )
1678
- for k , v in vars .as_dict ().items ()
1679
- if (k not in globals or globals [k ] != v )
1680
- and (entry .handler is None or k not in suite_vars or suite_vars [k ] != v )
1681
- }
1682
- )
1683
-
1684
- if entry .handler is not None and self .get_handler_args (entry .handler ):
1685
- for argument in self .get_handler_args (entry .handler ).argument_names :
1686
- name = f"${{{ argument } }}"
1687
- try :
1688
- value = vars [name ]
1689
- except (SystemExit , KeyboardInterrupt ):
1690
- raise
1691
- except BaseException as e :
1692
- value = str (e )
1693
-
1694
- result [name ] = self ._create_variable (name , value )
1695
- else :
1696
- value = self ._variables_cache .get (variables_reference , None )
1621
+ return self ._get_variables_no_filter (variables_reference )
1622
+ if filter == "indexed" :
1623
+ return self ._get_variables_indexed (variables_reference , start , count )
1624
+ if filter == "named" :
1625
+ return self ._get_variables_named (variables_reference , start , count )
1697
1626
1698
- if value is not None and isinstance (value , Mapping ):
1699
- result .update ({"len()" : self ._create_variable ("len()" , len (value ))})
1627
+ raise ValueError (f"Unknown filter: { filter } " )
1700
1628
1701
- for i , (k , v ) in enumerate (value .items (), start or 0 ):
1702
- result [repr (i )] = self ._create_variable (repr (k ), v )
1703
- if i >= MAX_VARIABLE_ITEMS_DISPLAY :
1704
- result ["Unable to handle" ] = self ._create_variable (
1705
- "Unable to handle" ,
1706
- f"Maximum number of items ({ MAX_VARIABLE_ITEMS_DISPLAY } ) reached." ,
1707
- )
1708
- break
1709
-
1710
- elif value is not None and isinstance (value , Sequence ) and not isinstance (value , str ):
1711
- result .update ({"len()" : self ._create_variable ("len()" , len (value ))})
1712
-
1713
- elif filter == "indexed" :
1629
+ def _get_variables_no_filter (self , variables_reference : int ) -> List [Variable ]:
1630
+ result : MutableMapping [str , Any ] = {}
1631
+ entry = next (
1632
+ (v for v in self .stack_frames if variables_reference in [v .global_id , v .suite_id , v .test_id , v .local_id ]),
1633
+ None ,
1634
+ )
1635
+ if entry is not None :
1636
+ context = entry .context ()
1637
+ if context is not None :
1638
+ if entry .global_id == variables_reference :
1639
+ result .update (
1640
+ {k : self ._create_variable (k , v ) for k , v in context .variables ._global .as_dict ().items ()}
1641
+ )
1642
+ elif entry .suite_id == variables_reference :
1643
+ result .update (self ._get_suite_variables (context , entry ))
1644
+ elif entry .test_id == variables_reference :
1645
+ result .update (self ._get_test_variables (context , entry ))
1646
+ elif entry .local_id == variables_reference :
1647
+ result .update (self ._get_local_variables (context , entry ))
1648
+ else :
1714
1649
value = self ._variables_cache .get (variables_reference , None )
1650
+ result .update (self ._get_cached_variables (value ))
1651
+ return list (result .values ())
1715
1652
1716
- if value is not None :
1717
- c = 0
1653
+ def _get_suite_variables (self , context : Any , entry : Any ) -> MutableMapping [str , Variable ]:
1654
+ result : MutableMapping [str , Variable ] = {}
1655
+ globals = context .variables ._global .as_dict ()
1656
+ vars = entry .get_first_or_self ().variables ()
1657
+ vars_dict = vars .as_dict () if vars is not None else {}
1658
+ for k , v in context .variables ._suite .as_dict ().items ():
1659
+ if (k not in globals or globals [k ] != v ) and (k in vars_dict ):
1660
+ result [k ] = self ._create_variable (k , v )
1661
+ return result
1718
1662
1719
- padding = len (str (len (value )))
1663
+ def _get_test_variables (self , context : Any , entry : Any ) -> MutableMapping [str , Variable ]:
1664
+ result : MutableMapping [str , Variable ] = {}
1665
+ globals = context .variables ._suite .as_dict ()
1666
+ vars = entry .get_first_or_self ().variables ()
1667
+ vars_dict = vars .as_dict () if vars is not None else {}
1668
+ for k , v in context .variables ._test .as_dict ().items ():
1669
+ if (k not in globals or globals [k ] != v ) and (k in vars_dict ):
1670
+ result [k ] = self ._create_variable (k , v )
1671
+ return result
1720
1672
1721
- for i , v in enumerate (value [start :], start or 0 ):
1722
- result [str (i )] = self ._create_variable (str (i ).zfill (padding ), v )
1723
- c += 1
1724
- if count is not None and c >= count :
1725
- break
1673
+ def _get_local_variables (self , context : Any , entry : Any ) -> MutableMapping [str , Variable ]:
1674
+ result : MutableMapping [str , Variable ] = {}
1675
+ vars = entry .get_first_or_self ().variables ()
1676
+ if self ._current_exception is not None :
1677
+ result ["${EXCEPTION}" ] = self ._create_variable (
1678
+ "${EXCEPTION}" ,
1679
+ self ._current_exception ,
1680
+ VariablePresentationHint (kind = "virtual" ),
1681
+ )
1682
+ if vars is not None :
1683
+ p = entry .parent () if entry .parent else None
1684
+ globals = (
1685
+ (p .get_first_or_self ().variables () if p is not None else None )
1686
+ or context .variables ._test
1687
+ or context .variables ._suite
1688
+ or context .variables ._global
1689
+ ).as_dict ()
1690
+ suite_vars = (context .variables ._suite or context .variables ._global ).as_dict ()
1691
+ for k , v in vars .as_dict ().items ():
1692
+ if (k not in globals or globals [k ] != v ) and (
1693
+ entry .handler is None or k not in suite_vars or suite_vars [k ] != v
1694
+ ):
1695
+ result [k ] = self ._create_variable (k , v )
1696
+ if entry .handler is not None and self .get_handler_args (entry .handler ):
1697
+ for argument in self .get_handler_args (entry .handler ).argument_names :
1698
+ name = f"${{{ argument } }}"
1699
+ try :
1700
+ value = vars [name ]
1701
+ except (SystemExit , KeyboardInterrupt ):
1702
+ raise
1703
+ except BaseException as e :
1704
+ value = str (e )
1705
+ result [name ] = self ._create_variable (name , value )
1706
+ return result
1726
1707
1727
- elif filter == "named" :
1728
- value = self ._variables_cache .get (variables_reference , None )
1708
+ def _get_cached_variables (self , value : Any ) -> MutableMapping [str , Variable ]:
1709
+ result : MutableMapping [str , Variable ] = {}
1710
+ if value is not None and isinstance (value , Mapping ):
1711
+ result ["len()" ] = self ._create_variable ("len()" , len (value ))
1712
+ for i , (k , v ) in enumerate (value .items ()):
1713
+ result [repr (i )] = self ._create_variable (repr (k ), v )
1714
+ if i >= MAX_VARIABLE_ITEMS_DISPLAY :
1715
+ result ["Unable to handle" ] = self ._create_variable (
1716
+ "Unable to handle" ,
1717
+ f"Maximum number of items ({ MAX_VARIABLE_ITEMS_DISPLAY } ) reached." ,
1718
+ )
1719
+ break
1720
+ elif value is not None and isinstance (value , Sequence ) and not isinstance (value , str ):
1721
+ result ["len()" ] = self ._create_variable ("len()" , len (value ))
1722
+ return result
1729
1723
1730
- if value is not None and isinstance (value , Mapping ):
1731
- for i , (k , v ) in enumerate (value .items (), start or 0 ):
1732
- result [repr (i )] = self ._create_variable (repr (k ), v )
1733
- if count is not None and i >= count :
1734
- break
1735
- elif value is not None and isinstance (value , Sequence ) and not isinstance (value , str ):
1736
- result .update ({"len()" : self ._create_variable ("len()" , len (value ))})
1724
+ def _get_variables_indexed (
1725
+ self ,
1726
+ variables_reference : int ,
1727
+ start : Optional [int ],
1728
+ count : Optional [int ],
1729
+ ) -> List [Variable ]:
1730
+ result : MutableMapping [str , Any ] = {}
1731
+ value = self ._variables_cache .get (variables_reference , None )
1732
+ if value is not None :
1733
+ c = 0
1734
+ padding = len (str (len (value )))
1735
+ for i , v in enumerate (value [start :], start or 0 ):
1736
+ result [str (i )] = self ._create_variable (str (i ).zfill (padding ), v )
1737
+ c += 1
1738
+ if count is not None and c >= count :
1739
+ break
1740
+ return list (result .values ())
1737
1741
1742
+ def _get_variables_named (
1743
+ self ,
1744
+ variables_reference : int ,
1745
+ start : Optional [int ],
1746
+ count : Optional [int ],
1747
+ ) -> List [Variable ]:
1748
+ result : MutableMapping [str , Any ] = {}
1749
+ value = self ._variables_cache .get (variables_reference , None )
1750
+ if value is not None and isinstance (value , Mapping ):
1751
+ for i , (k , v ) in enumerate (value .items (), start or 0 ):
1752
+ result [repr (i )] = self ._create_variable (repr (k ), v )
1753
+ if count is not None and i >= count :
1754
+ break
1755
+ elif value is not None and isinstance (value , Sequence ) and not isinstance (value , str ):
1756
+ result ["len()" ] = self ._create_variable ("len()" , len (value ))
1738
1757
return list (result .values ())
1739
1758
1740
1759
IS_VARIABLE_RE : ClassVar = re .compile (r"^[$@&]\{.*\}(\[[^\]]*\])?$" )
0 commit comments