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