18 from collections.abc
import MutableMapping
19 from io
import StringIO
20 from tokenize
import generate_tokens, untokenize
23 from robot.utils import get_error_message, type_name
25 from .notfound
import variable_not_found
28 PYTHON_BUILTINS = set(builtins.__dict__)
33 if not isinstance(expression, str):
34 raise TypeError(f
'Expression must be string, got {type_name(expression)}.')
36 raise ValueError(
'Expression cannot be empty.')
37 return _evaluate(expression, variable_store, modules, namespace)
39 raise DataError(f
"Evaluating expression '{expression}' failed: "
40 f
"{get_error_message()}")
43 def _evaluate(expression, variable_store, modules=None, namespace=None):
51 namespace = dict(namespace)
if namespace
else {}
55 return eval(expression, namespace, local_ns)
59 variable_started =
False
60 variable_found =
False
62 for toknum, tokval, _, _, _
in generate_tokens(StringIO(expression).readline):
64 if toknum == token.NAME:
65 if tokval
not in variable_store:
67 variable_store.as_dict(decoration=
False),
69 tokval =
'RF_VAR_' + tokval
72 tokens.append((token.ERRORTOKEN,
'$'))
73 variable_started =
False
74 if toknum == token.ERRORTOKEN
and tokval ==
'$':
75 variable_started =
True
77 tokens.append((toknum, tokval))
78 return untokenize(tokens).strip()
if variable_found
else expression
83 for name
in module_names.replace(
' ',
'').split(
','):
86 modules[name] = __import__(name)
89 name, _ = name.rsplit(
'.', 1)
90 modules[name] = __import__(name)
101 if key.startswith(
'RF_VAR_'):
114 if name
in PYTHON_BUILTINS:
117 return __import__(name)
119 raise NameError(f
"name '{name}' is not defined nor importable as module")
def __delitem__(self, key)
def __getitem__(self, key)
def __init__(self, variable_store, namespace)
def __setitem__(self, key, value)
def _import_module(self, name)
def evaluate_expression(expression, variable_store, modules=None, namespace=None)
def _import_modules(module_names)
def _evaluate(expression, variable_store, modules=None, namespace=None)
def _decorate_variables(expression, variable_store)
def variable_not_found(name, candidates, message=None, deco_braces=True)
Raise DataError for missing variable name.