Robot Framework
finders.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 re
17 
18 from robot.errors import DataError, VariableError
19 from robot.utils import (get_env_var, get_env_vars, get_error_message, normalize,
20  NormalizedDict)
21 
22 from .evaluation import evaluate_expression
23 from .notfound import variable_not_found
24 from .search import search_variable, VariableMatch
25 
26 
27 NOT_FOUND = object()
28 
29 
31 
32  def __init__(self, variable_store):
33  self._finders_finders = (StoredFinder(variable_store),
34  NumberFinder(),
35  EmptyFinder(),
36  InlinePythonFinder(variable_store),
38  ExtendedFinder(self))
39  self._store_store = variable_store
40 
41  def find(self, variable):
42  match = self._get_match_get_match(variable)
43  name = match.name
44  for finder in self._finders_finders:
45  if match.identifier in finder.identifiers:
46  result = finder.find(name)
47  if result is not NOT_FOUND:
48  return result
49  variable_not_found(name, self._store_store.data)
50 
51  def _get_match(self, variable):
52  if isinstance(variable, VariableMatch):
53  return variable
54  match = search_variable(variable)
55  if not match.is_variable() or match.items:
56  raise DataError("Invalid variable name '%s'." % variable)
57  return match
58 
59 
61  identifiers = '$@&'
62 
63  def __init__(self, store):
64  self._store_store = store
65 
66  def find(self, name):
67  return self._store_store.get(name, NOT_FOUND)
68 
69 
71  identifiers = '$'
72 
73  def find(self, name):
74  number = normalize(name)[2:-1]
75  for converter in self._get_int_get_int, float:
76  try:
77  return converter(number)
78  except ValueError:
79  pass
80  return NOT_FOUND
81 
82  def _get_int(self, number):
83  bases = {'0b': 2, '0o': 8, '0x': 16}
84  if number.startswith(tuple(bases)):
85  return int(number[2:], bases[number[:2]])
86  return int(number)
87 
88 
90  identifiers = '$@&'
91  empty = NormalizedDict({'${EMPTY}': '', '@{EMPTY}': (), '&{EMPTY}': {}}, ignore='_')
92 
93  def find(self, name):
94  return self.emptyempty.get(name, NOT_FOUND)
95 
96 
98  identifiers = '$@&'
99 
100  def __init__(self, variables):
101  self._variables_variables = variables
102 
103  def find(self, name):
104  base = name[2:-1]
105  if not base or base[0] != '{' or base[-1] != '}':
106  return NOT_FOUND
107  try:
108  return evaluate_expression(base[1:-1].strip(), self._variables_variables)
109  except DataError as err:
110  raise VariableError("Resolving variable '%s' failed: %s" % (name, err))
111 
112 
114  identifiers = '$@&'
115 
118  _match_extended = re.compile(r'''
119  (.+?) # base name (group 1)
120  ([^\s\w].+) # extended part (group 2)
121  ''', re.UNICODE|re.VERBOSE).match
122 
123  def __init__(self, finder):
124  self._find_variable_find_variable = finder.find
125 
126  def find(self, name):
127  match = self._match_extended_match_extended(name[2:-1])
128  if match is None:
129  return NOT_FOUND
130  base_name, extended = match.groups()
131  try:
132  variable = self._find_variable_find_variable('${%s}' % base_name)
133  except DataError as err:
134  raise VariableError("Resolving variable '%s' failed: %s"
135  % (name, err.message))
136  try:
137  return eval('_BASE_VAR_' + extended, {'_BASE_VAR_': variable})
138  except:
139  raise VariableError("Resolving variable '%s' failed: %s"
140  % (name, get_error_message()))
141 
142 
144  identifiers = '%'
145 
146  def find(self, name):
147  var_name, has_default, default_value = name[2:-1].partition('=')
148  value = get_env_var(var_name)
149  if value is not None:
150  return value
151  if has_default:
152  return default_value
154  "Environment variable '%s' not found." % name)
Used when variable does not exist.
Definition: errors.py:72
Custom dictionary implementation automatically normalizing keys.
Definition: normalizing.py:50
def _get_match(self, variable)
Definition: finders.py:51
def __init__(self, variable_store)
Definition: finders.py:32
def get_error_message()
Returns error message of the last occurred exception.
Definition: error.py:34
def normalize(string, ignore=(), caseless=True, spaceless=True)
Normalizes given string according to given spec.
Definition: normalizing.py:27
def get_env_var(name, default=None)
Definition: robotenv.py:21
def get_env_vars(upper=os.sep !='/')
Definition: robotenv.py:41
def evaluate_expression(expression, variable_store, modules=None, namespace=None)
Definition: evaluation.py:31
def variable_not_found(name, candidates, message=None, deco_braces=True)
Raise DataError for missing variable name.
Definition: notfound.py:26
def search_variable(string, identifiers='$@&% *', ignore_errors=False)
Definition: search.py:22