Robot Framework
tablesetter.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 from contextlib import contextmanager
17 
18 from robot.errors import DataError
19 from robot.utils import DotDict, is_string, split_from_equals
20 
21 from .resolvable import Resolvable
22 from .search import is_assign, is_list_variable, is_dict_variable
23 
24 
26 
27  def __init__(self, store):
28  self._store_store = store
29 
30  def set(self, variables, overwrite=False):
31  for name, value in self._get_items_get_items(variables):
32  self._store_store.add(name, value, overwrite, decorated=False)
33 
34  def _get_items(self, variables):
35  for var in variables:
36  if var.error:
37  var.report_invalid_syntax(var.error)
38  continue
39  try:
40  value = VariableTableValue(var.value, var.name,
41  var.report_invalid_syntax)
42  except DataError as err:
43  var.report_invalid_syntax(err)
44  else:
45  yield var.name[2:-1], value
46 
47 
48 def VariableTableValue(value, name, error_reporter=None):
49  if not is_assign(name):
50  raise DataError("Invalid variable name '%s'." % name)
51  VariableTableValue = {'$': ScalarVariableTableValue,
52  '@': ListVariableTableValue,
53  '&': DictVariableTableValue}[name[0]]
54  return VariableTableValue(value, error_reporter)
55 
56 
58 
59  def __init__(self, values, error_reporter=None):
60  self._values_values = self._format_values_format_values(values)
61  self._error_reporter_error_reporter = error_reporter
62  self._resolving_resolving = False
63 
64  def _format_values(self, values):
65  return values
66 
67  def resolve(self, variables):
68  with self._avoid_recursion_avoid_recursion_avoid_recursion:
69  return self._replace_variables_replace_variables(self._values_values, variables)
70 
71  @property
72  @contextmanager
73  _avoid_recursion = property
74 
75  def _avoid_recursion(self):
76  if self._resolving_resolving:
77  raise DataError('Recursive variable definition.')
78  self._resolving_resolving = True
79  try:
80  yield
81  finally:
82  self._resolving_resolving = False
83 
84  def _replace_variables(self, value, variables):
85  raise NotImplementedError
86 
87  def report_error(self, error):
88  if self._error_reporter_error_reporter:
89  self._error_reporter_error_reporter(str(error))
90 
91 
93 
94  def _format_values(self, values):
95  separator = None
96  if is_string(values):
97  values = [values]
98  elif values and values[0].startswith('SEPARATOR='):
99  separator = values[0][10:]
100  values = values[1:]
101  return separator, values
102 
103  def _replace_variables(self, values, variables):
104  separator, values = values
105  # Avoid converting single value to string.
106  if self._is_single_value_is_single_value(separator, values):
107  return variables.replace_scalar(values[0])
108  if separator is None:
109  separator = ' '
110  separator = variables.replace_string(separator)
111  values = variables.replace_list(values)
112  return separator.join(str(item) for item in values)
113 
114  def _is_single_value(self, separator, values):
115  return (separator is None and len(values) == 1 and
116  not is_list_variable(values[0]))
117 
118 
120 
121  def _replace_variables(self, values, variables):
122  return variables.replace_list(values)
123 
124 
126 
127  def _format_values(self, values):
128  return list(self._yield_formatted_yield_formatted(values))
129 
130  def _yield_formatted(self, values):
131  for item in values:
132  if is_dict_variable(item):
133  yield item
134  else:
135  name, value = split_from_equals(item)
136  if value is None:
137  raise DataError(
138  "Invalid dictionary variable item '%s'. "
139  "Items must use 'name=value' syntax or be dictionary "
140  "variables themselves." % item
141  )
142  yield name, value
143 
144  def _replace_variables(self, values, variables):
145  try:
146  return DotDict(self._yield_replaced_yield_replaced(values,
147  variables.replace_scalar))
148  except TypeError as err:
149  raise DataError('Creating dictionary failed: %s' % err)
150 
151  def _yield_replaced(self, values, replace_scalar):
152  for item in values:
153  if isinstance(item, tuple):
154  key, values = item
155  yield replace_scalar(key), replace_scalar(values)
156  else:
157  for key, values in replace_scalar(item).items():
158  yield key, values
def _yield_replaced(self, values, replace_scalar)
Definition: tablesetter.py:151
def _replace_variables(self, values, variables)
Definition: tablesetter.py:144
def _replace_variables(self, values, variables)
Definition: tablesetter.py:121
def set(self, variables, overwrite=False)
Definition: tablesetter.py:30
def _replace_variables(self, value, variables)
Definition: tablesetter.py:84
def __init__(self, values, error_reporter=None)
Definition: tablesetter.py:59
def split_from_equals(string)
Definition: escaping.py:105
def is_list_variable(string)
Definition: search.py:42
def is_dict_variable(string)
Definition: search.py:46
def is_assign(string, identifiers='$@&', allow_assign_mark=False)
Definition: search.py:50
def VariableTableValue(value, name, error_reporter=None)
Definition: tablesetter.py:48