Coverage for src/robotide/controller/macrocontrollers.py: 88%

347 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

1# Copyright 2008-2015 Nokia Networks 

2# Copyright 2016- Robot Framework Foundation 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

13# See the License for the specific language governing permissions and 

14# limitations under the License. 

15 

16import os 1ab

17from itertools import chain 1ab

18 

19from .. import robotapi 1ab

20from .arguments import parse_arguments_to_var_dict 1ab

21from .basecontroller import ControllerWithParent, WithUndoRedoStacks 1ab

22from .settingcontrollers import (DocumentationController, FixtureController, TagsController, TimeoutController, 1ab

23 TemplateController, ArgumentsController, ReturnValueController) 

24from .stepcontrollers import ForLoopStepController, StepController, IntendedStepController 1ab

25from .tags import Tag 1ab

26from ..namespace.local_namespace import local_namespace 1ab

27from ..publish.messages import (RideItemStepsChanged, RideItemNameChanged, RideItemSettingsChanged, 1ab

28 RideUserKeywordRemoved) 

29from ..spec.iteminfo import ResourceUserKeywordInfo, TestCaseUserKeywordInfo 1ab

30from ..utils import variablematcher 1ab

31 

32KEYWORD_NAME_FIELD = 'Keyword Name' 1ab

33TESTCASE_NAME_FIELD = 'Test Case Name' 1ab

34 

35 

36def obtain_bdd_prefixes(language): 1ab

37 from robotide.lib.compat.parsing.language import Language 

38 lang = Language.from_name(language[0] if isinstance(language, list) else language) 

39 bdd_prefixes = lang.bdd_prefixes 

40 return list(bdd_prefixes) 

41 

42def _empty_step(): 1ab

43 return robotapi.Step([]) 2T ? ( 6 c U ) * + , @ - 7 8 9 ! # V W . [ j dbebfbkcgblcmchbibX Q / : l m n o p q

44 

45 

46class ItemNameController(object): 1ab

47 

48 def __init__(self, item): 1ab

49 self._item = item 2OdHc` wcncxcoce f g J IcJcKcLcK McNcFcTcG H ^ d L

50 

51 def contains_keyword(self, name): 1ab

52 # print(f"DEBUG: macrocontrollers.py ItemNameController contains_keyword: item={self._item.name} search=" 

53 # f"{name}") 

54 if isinstance(name, str): 2Hc` wcncxcoce f g J IcJcKcLcK McNcFcTcG H ^ d L

55 return self._item.name == name 2` wcncxcoce f g J IcJcKcLcK McNcFcG H ^ d L

56 return name.match(self._item.name) 2Hce f g J IcJcKcLcK McNcFcTcG H ^ d L

57 

58 def contains_variable(self, name): 1ab

59 return variablematcher.value_contains_variable(self._item.name, name) 2` wcncxcoc

60 

61 def replace_keyword(self, new_name, old_value=None): 1ab

62 # print(f"DEBUG: macrocontrollers.py replace_keyword new_name={new_name} old_value={old_value}") 

63 self._item.rename(new_name) 1efgGH^d

64 

65 def rename(self, new_name): 1ab

66 self._item.rename(new_name) 2Od

67 

68 def notify_value_changed(self, old_name=None, new_name=None): 1ab

69 # print(f"DEBUG: macrocontrollers.py notify_value_changed item={self._item.name} old_name={old_name}") 

70 if not new_name: 70 ↛ 71line 70 didn't jump to line 71 because the condition on line 70 was never true1efgGH^d

71 new_name=self._item.name 

72 self._item.notify_name_changed(old_name=old_name, new_name=new_name) 1efgGH^d

73 

74 @property 1ab

75 def parent(self): 1ab

76 return self._item 2Hcg FcTc

77 

78 

79class KeywordNameController(ItemNameController): 1ab

80 _name_field = KEYWORD_NAME_FIELD 1ab

81 

82 

83class TestCaseNameController(ItemNameController): 1ab

84 __test__ = False 1ab

85 _name_field = TESTCASE_NAME_FIELD 1ab

86 

87 

88class WithStepsController(ControllerWithParent, WithUndoRedoStacks): 1ab

89 

90 def __init__(self, parent_controller, data): 1ab

91 self._parent = parent_controller 2a *d+dc ldmdHdj Y Z 0 y z UcIdpc6dVc^b,b-b_b.bqb/b`b:b;b=b?b; = 1 {b|b@b[b]brbsb] 2 | } ~ abbbPd3 R }b$ % u M JdKdOc7dLdk h i cb~b_ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchc8dndQdt S ' pbL icjc9d!d#d$dodpdRdqdrdsdtd%dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd,d-d.d/d:d;dyczcAcBcSdTdUdCcDcEc=dVdacbcccdcyd

92 self.data = data 2a *d+dc ldmdHdj Y Z 0 y z UcIdpc6dVc^b,b-b_b.bqb/b`b:b;b=b?b; = 1 {b|b@b[b]brbsb] 2 | } ~ abbbPd3 R }b$ % u M JdKdOc7dLdk h i cb~b_ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchc8dndQdt S ' pbL icjc9d!d#d$dodpdRdqdrdsdtd%dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd,d-d.d/d:d;dyczcAcBcSdTdUdCcDcEc=dVdacbcccdcyd

93 self._init(data) 2a *d+dc ldmdHdj Y Z 0 y z UcIdpc6dVc^b,b-b_b.bqb/b`b:b;b=b?b; = 1 {b|b@b[b]brbsb] 2 | } ~ abbbPd3 R }b$ % u M JdKdOc7dLdk h i cb~b_ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchc8dndQdt S ' pbL icjc9d!d#d$dodpdRdqdrdsdtd%dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd,d-d.d/d:d;dyczcAcBcSdTdUdCcDcEc=dVdacbcccdcyd

94 self._has_steps_changed = True 2a *d+dc ldmdHdj Y Z 0 y z UcIdpc6dVc^b,b-b_b.bqb/b`b:b;b=b?b; = 1 {b|b@b[b]brbsb] 2 | } ~ abbbPd3 R }b$ % u M JdKdOc7dLdk h i cb~b_ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchc8dndQdt S ' pbL icjc9d!d#d$dodpdRdqdrdsdtd%dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd,d-d.d/d:d;dyczcAcBcSdTdUdCcDcEc=dVdacbcccdcyd

95 self._steps_cached = None 2a *d+dc ldmdHdj Y Z 0 y z UcIdpc6dVc^b,b-b_b.bqb/b`b:b;b=b?b; = 1 {b|b@b[b]brbsb] 2 | } ~ abbbPd3 R }b$ % u M JdKdOc7dLdk h i cb~b_ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchc8dndQdt S ' pbL icjc9d!d#d$dodpdRdqdrdsdtd%dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd,d-d.d/d:d;dyczcAcBcSdTdUdCcDcEc=dVdacbcccdcyd

96 self.datafile_controller.register_for_namespace_updates( 2a *d+dc ldmdHdj Y Z 0 y z UcIdpc6dVc^b,b-b_b.bqb/b`b:b;b=b?b; = 1 {b|b@b[b]brbsb] 2 | } ~ abbbPd3 R }b$ % u M JdKdOc7dLdk h i cb~b_ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchc8dndQdt S ' pbL icjc9d!d#d$dodpdRdqdrdsdtd%dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd,d-d.d/d:d;dyczcAcBcSdTdUdCcDcEc=dVdacbcccdcyd

97 self.clear_cached_steps) 

98 

99 @property 1ab

100 def source(self): 1ab

101 return os.path.basename(self.data.source) if self.data.source else '' 2a _ HcMdWde l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcTcXdYdZdG H ^ d L @d

102 

103 @property 1ab

104 def name(self): 1ab

105 return self.data.name 2a { T ? 6 c U ) * + , @ V 6cldmdHdj Y Z 0 y z UcIdpc6dVcOdrbsb] 2 | } ~ abbbPd3 R }bcedezd7dLdk h i cb~bHc[d]d^d_dMd` wcncxcoce l m n A r s B C o f p q D E F g J IcJcKcLcK McNcFcTcG H ^ d 8dndt ' L %dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd2eacbcccdc

106 

107 @property 1ab

108 def steps(self): 1ab

109 if self._has_steps_changed: 2a { T ? ( 6 c U ) qcAd* + , @ - 7 8 9 ! # V (b)b`d6c*b+bW . [ 4 5 j 7c8c9cY Z 0 kejbtbubvbwbxbybzbAbBbkbCblbDbleEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/cme:c;c=c?c@crc[csctc]cucne^chbib_c`cvc{c|c}coe~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6bpeqerese7b8b9b!b#b$b%bteuevewe'b$ % u M Gck h i ~b_ Hc[d]d^d_dMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcTcXdYdZdG H ^ d v w x t S ' pbL BdCdDdEdFdGd

110 self._recreate_steps() 2a { T ? ( 6 c U ) qc* + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b$ % u M Gck h i ~b_ ` e l m n A N O P r s B C o f p q D E F g J K G H d v w x t ' L BdCdDdEdFdGd

111 return self._steps_cached 2a { T ? ( 6 c U ) qcAd* + , @ - 7 8 9 ! # V (b)b`d6c*b+bW . [ 4 5 j 7c8c9cY Z 0 kejbtbubvbwbxbybzbAbBbkbCblbDbleEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/cme:c;c=c?c@crc[csctc]cucne^chbib_c`cvc{c|c}coe~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6bpeqerese7b8b9b!b#b$b%bteuevewe'b$ % u M Gck h i ~b_ Hc[d]d^d_dMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcTcXdYdZdG H ^ d v w x t S ' pbL BdCdDdEdFdGd

112 

113 def set_parent(self, new_parent): 1ab

114 self.clear_cached_steps() 2UcVck h i cb

115 ControllerWithParent.set_parent(self, new_parent) 2UcVck h i cb

116 

117 def _recreate_steps(self): 1ab

118 flattened_steps = [] 2a { T ? ( 6 c U ) qc* + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b$ % u M Gck h i ~b_ ` e l m n A N O P r s B C o f p q D E F g J K G H d v w x t ' L BdCdDdEdFdGd

119 for step in self.data.steps: 2a { T ? ( 6 c U ) qc* + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b$ % u M Gck h i ~b_ ` e l m n A N O P r s B C o f p q D E F g J K G H d v w x t ' L BdCdDdEdFdGd

120 if step.is_for_loop(): 120 ↛ 121line 120 didn't jump to line 121 because the condition on line 120 was never true2a { T ? ( 6 c U ) qc* + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b$ % u M Gck h i ~b_ ` e l m n A N O P r s B C o f p q D E F g J K G H d v w x t ' L BdCdDdEdFdGd

121 for_loop = ForLoopStepController(self, step) 

122 flattened_steps.append(for_loop) 

123 flattened_steps.extend(for_loop.steps) 

124 else: 

125 flattened_steps.append(StepController(self, step)) 2a { T ? ( 6 c U ) qc* + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b$ % u M Gck h i ~b_ ` e l m n A N O P r s B C o f p q D E F g J K G H d v w x t ' L BdCdDdEdFdGd

126 self._steps_cached = flattened_steps 2a { T ? ( 6 c U ) qc* + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b$ % u M Gck h i ~b_ ` e l m n A N O P r s B C o f p q D E F g J K G H d v w x t ' L BdCdDdEdFdGd

127 self._has_steps_changed = False 2a { T ? ( 6 c U ) qc* + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b$ % u M Gck h i ~b_ ` e l m n A N O P r s B C o f p q D E F g J K G H d v w x t ' L BdCdDdEdFdGd

128 

129 def clear_cached_steps(self): 1ab

130 self._has_steps_changed = True 2a c 7 8 9 ! # 4 5 j jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobrcsctcucvcX Q ec/ : PcQcUcVcI ; = 1 GbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'bk h i cbxeyezee l m n A N O P r s B C o f p q D E F g G H ^ d v w x fcgchc@d

131 self._steps_cached = None 2a c 7 8 9 ! # 4 5 j jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobrcsctcucvcX Q ec/ : PcQcUcVcI ; = 1 GbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'bk h i cbxeyezee l m n A N O P r s B C o f p q D E F g G H ^ d v w x fcgchc@d

132 

133 @property 1ab

134 def max_columns(self): 1ab

135 return max(chain((len(step) for step in self.steps), [0])) 

136 

137 def has_template(self): 1ab

138 return False 2qcAd(b)b6c*b+b

139 

140 def step(self, index): 1ab

141 return self.steps[index] 2( 6 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobdbebfbgbhbibX Q / : PcQc,b-b.bqb/bI :b;b=b?bSc; = 1 @b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'be l m n o p q

142 

143 def index_of_step(self, step): 1ab

144 return [s.step_controller_step for s in self.steps].index(step) 2{ T U qcAd- V (b)b6c*b+bW . 4 5 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobI ; = 1 GbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b

145 

146 def replace_step(self, index, new_step): 1ab

147 corrected_index = index 

148 for i in range(index): 

149 if isinstance(self.step(i), IntendedStepController): 

150 corrected_index -= 1 

151 self.data.steps[corrected_index] = new_step 

152 self._has_steps_changed = True 

153 

154 def move_step_up(self, index): 1ab

155 self.step(index).move_up() 2jbybBbkbCblbDbEbFbmbnbobI = 1 RbSbTbUbVbWbXbYbZb0b1b8b9b!b#b$b%b'b

156 self._has_steps_changed = True 2jbybBbkbCblbDbEbFbmbnbobI = 1 RbSbTbUbVbWbXbYbZb0b1b8b9b!b#b$b%b'b

157 

158 def move_step_down(self, index): 1ab

159 self.step(index).move_down() 2jbtbubvbwbxbzbAbkblbmbnbobI ; 1 GbHbIbJbKbLbMbNbObPbQb2b3b4b5b6b7b

160 self._has_steps_changed = True 2jbtbubvbwbxbzbAbkblbmbnbobI ; 1 GbHbIbJbKbLbMbNbObPbQb2b3b4b5b6b7b

161 

162 def set_steps(self, steps): 1ab

163 self.data.steps = steps 2jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobdbebfbgbhbibX Q / : y z I ; = 1 GbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b

164 self._has_steps_changed = True 2jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobdbebfbgbhbibX Q / : y z I ; = 1 GbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b

165 

166 def update_namespace(self): 1ab

167 self.datafile_controller.update_namespace() 2c pcOd] 2 3 R }bu zdk h i cbe l m n A N O P r s B C o f p q D E F g G H ^ d v w x fcgchcNd0d1d2d3d4d5dt S icjcyczcAcBcCcDcEc

168 

169 def get_local_namespace(self): 1ab

170 return local_namespace(self, self.datafile_controller.namespace) 2a @deefe3e

171 

172 def get_local_namespace_for_row(self, row): 1ab

173 # print(f"DEBUG: local namespace_for_row controller.namespace {self.datafile_controller.namespace} row {row}") 

174 return local_namespace(self, self.datafile_controller.namespace, row) 2@dBdCdDdEdFdGd

175 

176 def get_cell_info(self, row, col): 1ab

177 steps = self.steps 2{ T ? ( 6 c U ) qcAd* + , @ - 7 8 9 ! # V (b)b`d6c*b+bW . [ 4 5 I k h i v w x

178 if row < 0 or len(steps) <= row: 2{ T ? ( 6 c U ) qcAd* + , @ - 7 8 9 ! # V (b)b`d6c*b+bW . [ 4 5 I k h i v w x

179 return None 2`d

180 return steps[row].get_cell_info(col) 2{ T ? ( 6 c U ) qcAd* + , @ - 7 8 9 ! # V (b)b6c*b+bW . [ 4 5 I k h i v w x

181 

182 def get_keyword_info(self, kw_name): 1ab

183 return self.datafile_controller.keyword_info(None, kw_name) 2{ T ? ( 6 c U ) qcAd* + , @ - 7 8 9 ! # V (b)b6c*b+bW . [ 4 5 I k h i v w x

184 

185 def is_user_keyword(self, value): 1ab

186 return self.datafile_controller.is_user_keyword(None, value) 2{ T ? ( 6 c U ) qcAd* + , @ 7 8 9 ! # V (b)b6c*b+bW [ 4 5 I k h i v w x

187 

188 def is_library_keyword(self, value): 1ab

189 return self.datafile_controller.is_library_keyword(None, value) 2( 6 c ) qcAd* + , 7 8 9 ! # (b)b6c*b+bW [ 4 5 I v w x

190 

191 def delete(self): 1ab

192 self.datafile_controller.unregister_namespace_updates( 2c 2 3 R }bzdk h i cb

193 self.clear_cached_steps) 

194 self._parent.delete(self) 2c 2 3 R }bzdk h i cb

195 self.notify_keyword_removed() 2c 2 3 R }bzdk h i cb

196 

197 def rename(self, new_name): 1ab

198 # print(f"DEBUG: macrocontrollers.py WithStepsController rename BEFORE new_name={new_name} old_name={self.data.name}") 

199 self.data.name = new_name.strip() 2Odcedee f g G H ^ d AeBe

200 self.mark_dirty() 2Odcedee f g G H ^ d AeBe

201 

202 def copy(self, name): 1ab

203 new = self._parent.new(name) 2j Y Z 0 $ % u M t S ' pb

204 for orig, copied in zip(self.settings, new.settings): 2j Y Z 0 $ % u M t S ' pb

205 copied.set_from(orig) 2j Y Z 0 $ % u M t S ' pb

206 new.data.steps = [robotapi.Step(s.as_list()) for s in self.steps] 2j Y Z 0 $ % u M t S ' pb

207 new.notify_steps_changed() 2j Y Z 0 $ % u M t S ' pb

208 return new 2j Y Z 0 $ % u M t S ' pb

209 

210 def get_empty_rows(self): 1ab

211 return [index for index, step in enumerate(self.steps) 2j RcX Q ecqb

212 if self._is_empty_step(step)] 

213 

214 @staticmethod 1ab

215 def _is_empty_step(step): 1ab

216 return step.as_list() in [[], ['']] 2j RcX Q ecqb

217 

218 def remove_step(self, index): 1ab

219 self._remove_step(self.steps[index]) 2a 4 5 j rcsctcucvcX Q ec/ :

220 self._has_steps_changed = True 2a 4 5 j rcsctcucvcX Q ec/ :

221 

222 def recreate(self): 1ab

223 self._parent.add(self) 1R

224 

225 def _remove_step(self, step): 1ab

226 step.remove() 2a 4 5 j rcsctcucvcX Q ec/ :

227 self._has_steps_changed = True 2a 4 5 j rcsctcucvcX Q ec/ :

228 

229 def add_step(self, index, step=None): 1ab

230 # print(f"\nDEBUG: WithStepsController enter add_step step={step}") 

231 if step is None: 231 ↛ 233line 231 didn't jump to line 233 because the condition on line 231 was always true2T ? ( 6 c U ) * + , @ - 7 8 9 ! # V W . [ j dbebfbkcgblcmchbibX Q / : l m n o p q

232 step = _empty_step() 2T ? ( 6 c U ) * + , @ - 7 8 9 ! # V W . [ j dbebfbkcgblcmchbibX Q / : l m n o p q

233 if index == len(self.steps): 2T ? ( 6 c U ) * + , @ - 7 8 9 ! # V W . [ j dbebfbkcgblcmchbibX Q / : l m n o p q

234 self.data.steps.append(step) 2T ? ( 6 c U ) * + , @ - 7 8 9 ! # V W . [ j kclcmcQ l m n o p q

235 else: 

236 previous_step = self.step(index) 2dbebfbgbhbibX Q / :

237 previous_step.insert_before(step) 2dbebfbgbhbibX Q / :

238 self._has_steps_changed = True 2T ? ( 6 c U ) * + , @ - 7 8 9 ! # V W . [ j dbebfbkcgblcmchbibX Q / : l m n o p q

239 

240 def create_keyword(self, name, argstr): 1ab

241 name = self._remove_bdd_prefix(name) 2c rbsb] 2 | } ~ abbb3 R

242 validation = self.datafile_controller.validate_keyword_name(name) 2c rbsb] 2 | } ~ abbb3 R

243 if validation.error_message: 243 ↛ 244line 243 didn't jump to line 244 because the condition on line 243 was never true2c rbsb] 2 | } ~ abbb3 R

244 raise ValueError(validation.error_message) 

245 return self.datafile_controller.create_keyword(name, argstr) 2c rbsb] 2 | } ~ abbb3 R

246 

247 def _remove_bdd_prefix(self, name): 1ab

248 bdd_prefix = [] 2c rbsb] 2 | } ~ abbb3 R

249 language = self.language[0] if isinstance(self.language, list) else self.language 2c rbsb] 2 | } ~ abbb3 R

250 if language and language.lower() not in ['en', 'english']: 250 ↛ 251line 250 didn't jump to line 251 because the condition on line 250 was never true2c rbsb] 2 | } ~ abbb3 R

251 bdd_prefix = [f"{x.lower()} " for x in obtain_bdd_prefixes(language)] 

252 bdd_prefix += ['given ', 'when ', 'then ', 'and ', 'but '] 2c rbsb] 2 | } ~ abbb3 R

253 # print(f"DEBUG: macrocontrollers.py WithStepsController _remove_bdd_prefix bdd_prefix={bdd_prefix}") 

254 matcher = name.lower() 2c rbsb] 2 | } ~ abbb3 R

255 for match in bdd_prefix: 2c rbsb] 2 | } ~ abbb3 R

256 if matcher.startswith(match): 2c rbsb] 2 | } ~ abbb3 R

257 return name[len(match):] 2| } ~ abbb

258 return name 2c rbsb] 2 3 R

259 

260 def create_test(self, name): 1ab

261 return self.datafile_controller.create_test(name) 2Pd}b

262 

263 def extract_keyword(self, name, argstr, step_range): 1ab

264 extracted_steps = self._extract_steps(step_range) 1yz

265 self._replace_steps_with_kw(name, step_range) 1yz

266 self._create_extracted_kw(name, argstr, extracted_steps) 1yz

267 

268 def get_raw_steps(self): 1ab

269 # Reveales inner state so can't be sure if cache is up-to-date 

270 self._has_steps_changed = True 2jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobdbebfbgbhbibX Q / : I ; = 1 GbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b

271 return self.data.steps 2jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobdbebfbgbhbibX Q / : I ; = 1 GbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b

272 

273 def set_raw_steps(self, steps): 1ab

274 self.set_steps(steps) 2jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbobdbebfbgbhbibX Q / : I ; = 1 GbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b

275 

276 def _extract_steps(self, step_range): 1ab

277 rem_start, rem_end = step_range 1yz

278 extracted_steps = self.steps[rem_start:rem_end + 1] 1yz

279 return self._convert_controller_to_steps(extracted_steps) 1yz

280 

281 @staticmethod 1ab

282 def _convert_controller_to_steps(step_controllers): 1ab

283 return [robotapi.Step(s.as_list()) for s in step_controllers] 1yz

284 

285 def _replace_steps_with_kw(self, name, step_range): 1ab

286 steps_before_extraction_point = self._convert_controller_to_steps( 1yz

287 self.steps[:step_range[0]]) 

288 extracted_kw_step = [robotapi.Step([name])] 1yz

289 steps_after_extraction_point = self._convert_controller_to_steps( 1yz

290 self.steps[step_range[1] + 1:]) 

291 self.set_steps(steps_before_extraction_point + extracted_kw_step + 1yz

292 steps_after_extraction_point) 

293 

294 def _create_extracted_kw(self, name, argstr, extracted_steps): 1ab

295 controller = self.datafile_controller.create_keyword(name, argstr) 1yz

296 controller.set_steps(extracted_steps) 1yz

297 return controller 1yz

298 

299 def validate_name(self, name): 1ab

300 return self._parent.validate_name(name, self) 

301 

302 def notify_name_changed(self, old_name=None, new_name=None): 1ab

303 self.update_namespace() 2Ode f g G H ^ d

304 self.mark_dirty() 2Ode f g G H ^ d

305 RideItemNameChanged(item=self, old_name=old_name, new_name=new_name).publish() 2Ode f g G H ^ d

306 

307 def notify_keyword_removed(self): 1ab

308 self.update_namespace() 2c 2 3 R }bzdk h i cb

309 RideUserKeywordRemoved(datafile=self.datafile, name=self.name, item=self).publish() 2c 2 3 R }bzdk h i cb

310 self.notify_steps_changed() 2c 2 3 R }bzdk h i cb

311 

312 def notify_settings_changed(self, old_name=None, new_name=None): 1ab

313 _ = old_name 2c pc] u r s d v w x fcgchcNd0d1d2d3d4d5dt S icjcyczcAcBcCcDcEc

314 _ = new_name 2c pc] u r s d v w x fcgchcNd0d1d2d3d4d5dt S icjcyczcAcBcCcDcEc

315 self.update_namespace() 2c pc] u r s d v w x fcgchcNd0d1d2d3d4d5dt S icjcyczcAcBcCcDcEc

316 self._notify(RideItemSettingsChanged) 2c pc] u r s d v w x fcgchcNd0d1d2d3d4d5dt S icjcyczcAcBcCcDcEc

317 

318 def notify_steps_changed(self, old_name=None): 1ab

319 self._has_steps_changed = True 2a { T ? ( 6 c U ) * + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b2 3 R }b$ % u M zdk h i cbe l m n A B C o f p q D E F G H d t S ' pb

320 # print(f"DEBUG: macrocontrollers.py WithStepsController notify_steps_changed: ENTER old_name={old_name}" 

321 # f" {self.parent} {self.source} {self} call self._notify") 

322 self._notify(RideItemStepsChanged) 2a { T ? ( 6 c U ) * + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b2 3 R }b$ % u M zdk h i cbe l m n A B C o f p q D E F G H d t S ' pb

323 

324 def _notify(self, messageclass): 1ab

325 self.mark_dirty() 2a { T ? ( 6 c U ) * + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQcpc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b] 2 3 R }b$ % u M zdk h i cbe l m n A r s B C o f p q D E F G H d v w x fcgchcNd0d1d2d3d4d5dt S ' pbicjcyczcAcBcCcDcEc

326 messageclass(item=self).publish() 2a { T ? ( 6 c U ) * + , @ - 7 8 9 ! # V (b)b*b+bW . [ 4 5 j 7c8c9cY Z 0 jbtbubvbwbxbybzbAbBbkbCblbDbEbFbmbnbob!c#cRcdbebfbkcgblc$c%c'cmc(c)c*c+c,c-c.c/c:c;c=c?c@crc[csctc]cuc^chbib_c`cvc{c|c}c~cadX Q ecbdcdddedfdgdhd/ idjd: y z PcQcpc^b,b-b_b.bqb/bI `b:b;b=b?bSc; = 1 {bkd|b@b[b]bGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b] 2 3 R }b$ % u M zdk h i cbe l m n A r s B C o f p q D E F G H d v w x fcgchcNd0d1d2d3d4d5dt S ' pbicjcyczcAcBcCcDcEc

327 

328 

329class TestCaseController(WithStepsController): 1ab

330 __test__ = False 1ab

331 

332 _populator = robotapi.TestCasePopulator 1ab

333 filename = "" 1ab

334 

335 def _init(self, test): 1ab

336 self._test = test 2a *d+dldmdHdj Y Z 0 Uc6dVc^b,b-b_b.bqb/b`b:b;b=b?b; = 1 {b|b@b[b]bPd}b$ % Oc7dk cb~be l m n A N O P r s B C o f p q D E F g J K d 8dndQd' pbL icjc9d!d#d$dRd%dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd,d-d.d/d:d;d=dacbcccdcyd

337 self._run_passed = None 2a *d+dldmdHdj Y Z 0 Uc6dVc^b,b-b_b.bqb/b`b:b;b=b?b; = 1 {b|b@b[b]bPd}b$ % Oc7dk cb~be l m n A N O P r s B C o f p q D E F g J K d 8dndQd' pbL icjc9d!d#d$dRd%dWc'dudXcYcvd(dZc0c)d1c2c3cwd4c5cxd,d-d.d/d:d;d=dacbcccdcyd

338 

339 def __eq__(self, other): 1ab

340 if self is other: 2ldmdHdOccbN O P r s ndQdacbcccdc

341 return True 2ldmdHdOcQd

342 if other.__class__ != self.__class__: 2cbN O P r s ndacbcccdc

343 return False 2N O P ndacbcccdc

344 return self._test == other._test 2cbr s

345 

346 def __hash__(self): 1ab

347 return hash(repr(self)) 24e5e6e7e8e{ T U - V W . 4 5 icjc9d!d#d$d9e@d!e#e$e%e'e(eeeRd

348 

349 @property 1ab

350 def longname(self): 1ab

351 return self.parent.parent.longname + '.' + self.data.name 2ldmd

352 

353 @property 1ab

354 def test_name(self): 1ab

355 return TestCaseNameController(self) 2Od

356 

357 @property 1ab

358 def tags(self): 1ab

359 return TagsController(self, self._test.tags) 2a j Y Z 0 Ce$ % ge~b_ Hc[d]d^d_dMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcXdYdZdG H ^ d Nd0d1d2d3d4d{d|d}d~dhe5die' pbL icjcaebejeWcudXcYcvdZc0c1c2c3cwd4c5cxd

360 

361 @property 1ab

362 def force_tags(self): 1ab

363 return self.datafile_controller.force_tags 2j Y Z 0 $ % Nd0d1d2d3d4d{d|d}d~dhe5die' pbicjcaebejeWcudXcYcvdZc0c1c2c3cwd4c5cxd

364 

365 @property 1ab

366 def test_tags(self): 1ab

367 return self.datafile_controller.test_tags 2j Y Z 0 $ % Nd0d1d2d3d4d{d|d}d~dhe5die' pbicjcaebejeWcudXcYcvdZc0c1c2c3cwd4c5cxd

368 

369 @property 1ab

370 def default_tags(self): 1ab

371 return self.datafile_controller.default_tags 2j Y Z 0 $ % Nd{d|d}d~dicjcaebe

372 

373 def add_tag(self, name): 1ab

374 self.tags.add(Tag(name)) 2Ce

375 

376 @property 1ab

377 def settings(self): 1ab

378 return [ 2j Y Z 0 $ % ge~b_ Hc[d]d^d_dMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcXdYdZdG H ^ d ' pbL

379 self.documentation, 

380 FixtureController(self, self._test.setup), 

381 FixtureController(self, self._test.teardown), 

382 TimeoutController(self, self._test.timeout), 

383 TemplateController(self, self._test.template), 

384 self.tags 

385 ] 

386 

387 @property 1ab

388 def documentation(self): 1ab

389 return DocumentationController(self, self._test.doc) 2j Y Z 0 $ % ge~b_ Hc[d]d^d_dMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcXdYdZdG H ^ d ' pbL WcXcYcZc0c1c2c3c4c5c

390 

391 def move_up(self): 1ab

392 return self._parent.move_up(self._test) 

393 

394 def move_down(self): 1ab

395 return self._parent.move_down(self._test) 

396 

397 def validate_test_name(self, name): 1ab

398 return self._parent.validate_name(name) 2acbcDeccdc

399 

400 def validate_keyword_name(self, name): 1ab

401 return self.datafile_controller.validate_keyword_name(name) 

402 

403 @staticmethod 1ab

404 def get_local_variables(): 1ab

405 return {} 2{ T U - V W . 4 5 ` wcncxcoc@deeRd

406 

407 def has_template(self): 1ab

408 template = self._get_template() 1{T?(6cU)*+,@-789!#VW.[45Ikhivwx

409 if not template: 409 ↛ 410line 409 didn't jump to line 410 because the condition on line 409 was never true1{T?(6cU)*+,@-789!#VW.[45Ikhivwx

410 return False 

411 return bool(template.value) 1{T?(6cU)*+,@-789!#VW.[45Ikhivwx

412 

413 def _get_template(self): 1ab

414 template = self._test.template 1{T?(6cU)*+,@-789!#VW.[45Ikhivwx

415 if template.value is not None: 415 ↛ 416line 415 didn't jump to line 416 because the condition on line 415 was never true1{T?(6cU)*+,@-789!#VW.[45Ikhivwx

416 return template 

417 return self.datafile_controller.get_template() 1{T?(6cU)*+,@-789!#VW.[45Ikhivwx

418 

419 @property 1ab

420 def run_passed(self): 1ab

421 return self._run_passed 

422 

423 @run_passed.setter 1ab

424 def run_passed(self, value): 1ab

425 if value not in [True, False, None]: 

426 self._run_passed = None # Test did not run 

427 if value: 

428 self._run_passed = True # Test execution passed 

429 else: 

430 self._run_passed = False # Test execution failed 

431 

432 

433class UserKeywordController(WithStepsController): 1ab

434 _populator = robotapi.UserKeywordPopulator 1ab

435 _TEARDOWN_NOT_SET = object() 1ab

436 _teardown = _TEARDOWN_NOT_SET 1ab

437 _SETUP_NOT_SET = object() 1ab

438 _setup = _SETUP_NOT_SET 1ab

439 

440 def _init(self, kw): 1ab

441 self.kw = kw 2a c y z Idpcrbsb] 2 | } ~ abbb3 R u M JdKdOcLdk h i _ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchct S L odpdqdrdsdtdyczcAcBcSdTdUdCcDcEcVdacbcccdcyd

442 # Needed for API compatibility in tag search 

443 self.force_tags = [] 2a c y z Idpcrbsb] 2 | } ~ abbb3 R u M JdKdOcLdk h i _ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchct S L odpdqdrdsdtdyczcAcBcSdTdUdCcDcEcVdacbcccdcyd

444 self.default_tags = [] 2a c y z Idpcrbsb] 2 | } ~ abbb3 R u M JdKdOcLdk h i _ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchct S L odpdqdrdsdtdyczcAcBcSdTdUdCcDcEcVdacbcccdcyd

445 self.test_tags = [] 2a c y z Idpcrbsb] 2 | } ~ abbb3 R u M JdKdOcLdk h i _ e l m n A N O P r s B C o f p q D E F g J K d v w x fcgchct S L odpdqdrdsdtdyczcAcBcSdTdUdCcDcEcVdacbcccdcyd

446 

447 def __eq__(self, other): 1ab

448 if self is other: 2c | } ~ abbbOch i acbcccdc

449 return True 2Oc

450 if other.__class__ != self.__class__: 2c | } ~ abbbh i acbcccdc

451 return False 2c | } ~ abbbacbcccdc

452 return self.kw == other.kw 1hi

453 

454 def __hash__(self): 1ab

455 return hash(repr(self)) 2qcAd(b)b6c*b+bfeBdCdDdEdFdGdEeFeGeHeIeJeKeLeMeNeOePeodQeReSeTeUeVeWeXeYeZe0epdqdrd1esdtd

456 

457 @property 1ab

458 def info(self): 1ab

459 if isinstance(self.datafile, robotapi.ResourceFile): 459 ↛ 461line 459 didn't jump to line 461 because the condition on line 459 was always true1^

460 return ResourceUserKeywordInfo(self.data) 1^

461 return TestCaseUserKeywordInfo(self.data) 

462 

463 @property 1ab

464 def keyword_name(self): 1ab

465 return KeywordNameController(self) 2Hc` wcncxcoce f g J IcJcKcLcK McNcFcTcG H ^ d L

466 

467 def move_up(self): 1ab

468 return self._parent.move_up(self.kw) 2Kd

469 

470 def move_down(self): 1ab

471 return self._parent.move_down(self.kw) 2Jd

472 

473 @property 1ab

474 def settings(self): 1ab

475 result = [ 2u M Gc?d` wcncxcoct S

476 DocumentationController(self, self.kw.doc), 

477 ArgumentsController(self, self.kw.args), 

478 self.setup, 

479 self.teardown, 

480 ReturnValueController(self, self.kw.return_), 

481 TimeoutController(self, self.kw.timeout), 

482 TagsController(self, self.kw.tags), 

483 ] 

484 return result 2u M Gc?d` wcncxcoct S

485 

486 @property 1ab

487 def setup(self): 1ab

488 if self._setup == self._SETUP_NOT_SET: 2u M Gc?d_ HcMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcTcXdYdZdG H ^ d t S L

489 self._setup = FixtureController(self, self.kw.setup_) 2u M Gc?d_ ` e l m n A N O P r s B C o f p q D E F g J K d t S L

490 return self._setup 2u M Gc?d_ HcMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcTcXdYdZdG H ^ d t S L

491 

492 @property 1ab

493 def teardown(self): 1ab

494 if self._teardown == self._TEARDOWN_NOT_SET: 2u M Gc?d_ HcMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcTcXdYdZdG H ^ d t S L

495 self._teardown = FixtureController(self, self.kw.teardown) 2u M Gc?d_ ` e l m n A N O P r s B C o f p q D E F g J K d t S L

496 return self._teardown 2u M Gc?d_ HcMdWd` wcncxcoce l m n A N O P r s B C o f p q D E F g J IcJcKcLcK McNcFcTcXdYdZdG H ^ d t S L

497 

498 @property 1ab

499 def arguments(self): 1ab

500 return ArgumentsController(self, self.kw.args) 2c pcrbsb] | } ~ abbbv w x fcgchcyczcAcBcCcDcEc

501 

502 def validate_keyword_name(self, name): 1ab

503 return self._parent.validate_name(name) 2acbcDeccdc

504 

505 def get_local_variables(self): 1ab

506 return parse_arguments_to_var_dict(self.kw.args.value, self.kw.name) 2qcAd(b)b6c*b+b` ncocfeBdCdDdEdFdGdEeFeGeHeIeJeKeLeMeNeOePeodQeReSeTeUeVeWeXeYeZe0epdqdrd1esdtd