I want to evaluate an expression in Python 3.7 that is read as string from a config file. The application is a Datalogger and the user shall be able to define his own conversion of the raw ADC value in the config file. Using eval()
and compile()
is handy, but is considered to be unsafe. I tried to use ast.literal_eval()
but it does not work with Python 3.7, because it doesn't allows using operators like +-*/
. Finally I came up with something like this:
def convert(code, value):
try:
return eval(code, {'__builtins__': {}}, {'value': value})
except RecursionError as e:
print(str(e))
except NameError as e:
print(str(e))
def compile_expression(expr):
if '__' in expr: # check for double underscore
print('expression contains illegal characters')
return None
try:
code = compile(expr, '<String>', 'eval') # compile it for use with eval
except SyntaxError as e:
print('Invalid Syntax in expression. Using default value.')
code = compile('value', '<String>', 'eval')
return code
expr = '(value-1)/0.005' # string is read from a config file
code = compile_expression(expr) # compile string
if code is not None:
t = convert(code, 1.1) # convert ADC value to temperature
print(t)
At least I tried to make it as safe as I can. Does anyone have a suggestion how to do better or has a suitable alternative to eval()
and compile()
?