Safely evaluate simple string equation

One way would be to use . It’s mostly a module for optimizing (and multithreading) operations but it can also handle mathematical python expressions:

>>> import numexpr
>>> numexpr.evaluate('2 + 4.1 * 3')
array(14.299999999999999)

You can call .item on the result to get a python-like type:

>>> numexpr.evaluate('17 / 3').item()
5.666666666666667

It’s a 3rd party extension module so it may be total overkill here but it’s definetly safer than eval and supports quite a number of functions (including numpy and math operations). If also supports “variable substitution”:

>>> b = 10
>>> numexpr.evaluate('exp(17) / b').item()
2415495.27535753

One way with the python standard library, although very limited is ast.literal_eval. It works for the most basic data types and literals in Python:

>>> import ast
>>> ast.literal_eval('1+2')
3

But fails with more complicated expressions like:

>>> ast.literal_eval('import os')
SyntaxError: invalid syntax

>>> ast.literal_eval('exec(1+2)')
ValueError: malformed node or string: <_ast.Call object at 0x0000023BDEADB400>

Unfortunatly any operator besides + and - isn’t possible:

>>> ast.literal_eval('1.2 * 2.3')
ValueError: malformed node or string: <_ast.BinOp object at 0x0000023BDEF24B70>

I copied part of the documentation here that contains the supported types:

Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None.

Leave a Comment