Robot Framework Integrated Development Environment (RIDE)
scopes.py
Go to the documentation of this file.
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 
16 import os
17 import tempfile
18 
19 from robotide.lib.robot.errors import DataError
20 from robotide.lib.robot.output import LOGGER
21 from robotide.lib.robot.utils import abspath, find_file, get_error_details, NormalizedDict
22 
23 from .variables import Variables
24 
25 
27 
28  def __init__(self, settings):
29  self._global_global = GlobalVariables(settings)
30  self._suite_suite = None
31  self._test_test = None
32  self._scopes_scopes = [self._global_global]
33  self._variables_set_variables_set = SetVariables()
34 
35  @property
36  current = property
37 
38  def current(self):
39  return self._scopes_scopes[-1]
40 
41  @property
42  _all_scopes = property
43 
44  def _all_scopes(self):
45  return reversed(self._scopes_scopes)
46 
47  @property
48  _scopes_until_suite = property
49 
51  for scope in self._all_scopes_all_scopes_all_scopes:
52  yield scope
53  if scope is self._suite_suite:
54  break
55 
56  @property
57  _scopes_until_test = property
58 
59  def _scopes_until_test(self):
60  for scope in self._scopes_until_suite_scopes_until_suite_scopes_until_suite:
61  yield scope
62  if scope is self._test_test:
63  break
64 
65  def start_suite(self):
66  self._suite_suite = self._global_global.copy()
67  self._scopes_scopes.append(self._suite_suite)
68  self._variables_set_variables_set.start_suite()
69  self._variables_set_variables_set.update(self._suite_suite)
70 
71  def end_suite(self):
72  self._scopes_scopes.pop()
73  self._suite_suite = self._scopes_scopes[-1] if len(self._scopes_scopes) > 1 else None
74  self._variables_set_variables_set.end_suite()
75 
76  def start_test(self):
77  self._test_test = self._suite_suite.copy()
78  self._scopes_scopes.append(self._test_test)
79  self._variables_set_variables_set.start_test()
80 
81  def end_test(self):
82  self._scopes_scopes.pop()
83  self._test_test = None
84  self._variables_set_variables_set.end_test()
85 
86  def start_keyword(self):
87  kw = self._suite_suite.copy()
88  self._variables_set_variables_set.start_keyword()
89  self._variables_set_variables_set.update(kw)
90  self._scopes_scopes.append(kw)
91 
92  def end_keyword(self):
93  self._scopes_scopes.pop()
94  self._variables_set_variables_set.end_keyword()
95 
96  def __getitem__(self, name):
97  return self.currentcurrentcurrent[name]
98 
99  def __setitem__(self, name, value):
100  self.currentcurrentcurrent[name] = value
101 
102  def __contains__(self, name):
103  return name in self.currentcurrentcurrent
104 
105  def replace_list(self, items, replace_until=None, ignore_errors=False):
106  return self.currentcurrentcurrent.replace_list(items, replace_until, ignore_errors)
107 
108  def replace_scalar(self, items, ignore_errors=False):
109  return self.currentcurrentcurrent.replace_scalar(items, ignore_errors)
110 
111  def replace_string(self, string, ignore_errors=False):
112  return self.currentcurrentcurrent.replace_string(string, ignore_errors=ignore_errors)
113 
114  def set_from_file(self, path, args, overwrite=False):
115  variables = None
116  for scope in self._scopes_until_suite_scopes_until_suite_scopes_until_suite:
117  if variables is None:
118  variables = scope.set_from_file(path, args, overwrite)
119  else:
120  scope.set_from_file(variables, overwrite=overwrite)
121 
122  def set_from_variable_table(self, variables, overwrite=False):
123  for scope in self._scopes_until_suite_scopes_until_suite_scopes_until_suite:
124  scope.set_from_variable_table(variables, overwrite)
125 
126  def resolve_delayed(self):
127  for scope in self._scopes_until_suite_scopes_until_suite_scopes_until_suite:
128  scope.resolve_delayed()
129 
130  def set_global(self, name, value):
131  for scope in self._all_scopes_all_scopes_all_scopes:
132  name, value = self._set_global_suite_or_test_set_global_suite_or_test(scope, name, value)
133  self._variables_set_variables_set.set_global(name, value)
134 
135  def _set_global_suite_or_test(self, scope, name, value):
136  scope[name] = value
137  # Avoid creating new list/dict objects in different scopes.
138  if name[0] != '$':
139  name = '$' + name[1:]
140  value = scope[name]
141  return name, value
142 
143  def set_suite(self, name, value, top=False, children=False):
144  if top:
145  self._scopes_scopes[1][name] = value
146  return
147  for scope in self._scopes_until_suite_scopes_until_suite_scopes_until_suite:
148  name, value = self._set_global_suite_or_test_set_global_suite_or_test(scope, name, value)
149  if children:
150  self._variables_set_variables_set.set_suite(name, value)
151 
152  def set_test(self, name, value):
153  if self._test_test is None:
154  raise DataError('Cannot set test variable when no test is started.')
155  for scope in self._scopes_until_test_scopes_until_test_scopes_until_test:
156  name, value = self._set_global_suite_or_test_set_global_suite_or_test(scope, name, value)
157  self._variables_set_variables_set.set_test(name, value)
158 
159  def set_keyword(self, name, value):
160  self.currentcurrentcurrent[name] = value
161  self._variables_set_variables_set.set_keyword(name, value)
162 
163  def as_dict(self, decoration=True):
164  return self.currentcurrentcurrent.as_dict(decoration=decoration)
165 
166 
168 
169  def __init__(self, settings):
170  Variables.__init__(self)
171  self._set_cli_variables_set_cli_variables(settings)
172  self._set_built_in_variables_set_built_in_variables(settings)
173 
174  def _set_cli_variables(self, settings):
175  for path, args in settings.variable_files:
176  try:
177  path = find_file(path, file_type='Variable file')
178  self.set_from_fileset_from_file(path, args)
179  except:
180  msg, details = get_error_details()
181  LOGGER.error(msg)
182  LOGGER.info(details)
183  for varstr in settings.variables:
184  try:
185  name, value = varstr.split(':', 1)
186  except ValueError:
187  name, value = varstr, ''
188  self['${%s}' % name] = value
189 
190  def _set_built_in_variables(self, settings):
191  for name, value in [('${TEMPDIR}', abspath(tempfile.gettempdir())),
192  ('${EXECDIR}', abspath('.')),
193  ('${/}', os.sep),
194  ('${:}', os.pathsep),
195  ('${\\n}', os.linesep),
196  ('${SPACE}', ' '),
197  ('${True}', True),
198  ('${False}', False),
199  ('${None}', None),
200  ('${null}', None),
201  ('${OUTPUT_DIR}', settings.output_directory),
202  ('${OUTPUT_FILE}', settings.output or 'NONE'),
203  ('${REPORT_FILE}', settings.report or 'NONE'),
204  ('${LOG_FILE}', settings.log or 'NONE'),
205  ('${DEBUG_FILE}', settings.debug_file or 'NONE'),
206  ('${LOG_LEVEL}', settings.log_level),
207  ('${PREV_TEST_NAME}', ''),
208  ('${PREV_TEST_STATUS}', ''),
209  ('${PREV_TEST_MESSAGE}', '')]:
210  self[name] = value
211 
212 
213 class SetVariables():
214 
215  def __init__(self):
216  self._suite_suite = None
217  self._test_test = None
218  self._scopes_scopes = []
219 
220  def start_suite(self):
221  if not self._scopes_scopes:
222  self._suite_suite = NormalizedDict(ignore='_')
223  else:
224  self._suite_suite = self._scopes_scopes[-1].copy()
225  self._scopes_scopes.append(self._suite_suite)
226 
227  def end_suite(self):
228  self._scopes_scopes.pop()
229  self._suite_suite = self._scopes_scopes[-1] if self._scopes_scopes else None
230 
231  def start_test(self):
232  self._test_test = self._scopes_scopes[-1].copy()
233  self._scopes_scopes.append(self._test_test)
234 
235  def end_test(self):
236  self._test_test = None
237  self._scopes_scopes.pop()
238 
239  def start_keyword(self):
240  self._scopes_scopes.append(self._scopes_scopes[-1].copy())
241 
242  def end_keyword(self):
243  self._scopes_scopes.pop()
244 
245  def set_global(self, name, value):
246  for scope in self._scopes_scopes:
247  if name in scope:
248  scope.pop(name)
249 
250  def set_suite(self, name, value):
251  self._suite_suite[name] = value
252 
253  def set_test(self, name, value):
254  for scope in reversed(self._scopes_scopes):
255  scope[name] = value
256  if scope is self._test_test:
257  break
258 
259  def set_keyword(self, name, value):
260  self._scopes_scopes[-1][name] = value
261 
262  def update(self, variables):
263  for name, value in self._scopes_scopes[-1].items():
264  variables[name] = value
Used when variable does not exist.
Definition: errors.py:67
Custom dictionary implementation automatically normalizing keys.
Definition: normalizing.py:58
def replace_scalar(self, items, ignore_errors=False)
Definition: scopes.py:108
def _set_global_suite_or_test(self, scope, name, value)
Definition: scopes.py:135
def replace_string(self, string, ignore_errors=False)
Definition: scopes.py:111
def set_from_variable_table(self, variables, overwrite=False)
Definition: scopes.py:122
def set_suite(self, name, value, top=False, children=False)
Definition: scopes.py:143
def replace_list(self, items, replace_until=None, ignore_errors=False)
Definition: scopes.py:105
def set_from_file(self, path, args, overwrite=False)
Definition: scopes.py:114
Represents a set of variables.
Definition: variables.py:31
def set_from_file(self, path_or_variables, args=None, overwrite=False)
Definition: variables.py:61
def get_error_details(exclude_robot_traces=EXCLUDE_ROBOT_TRACES)
Returns error message and details of the last occurred exception.
Definition: error.py:46
def abspath(path, case_normalize=False)
Replacement for os.path.abspath with some enhancements and bug fixes.
Definition: robotpath.py:87
def find_file(path, basedir='.', file_type=None)
Definition: robotpath.py:146