Search code examples
pythoneval

Safely using eval to calculate using the math module in python


I want to get a calculation result from a user-inputted string, while using math functions such as sin or ceil. I also would like to be able to do it as sin(30), not math.sin(30). I thought doing

from math import *

would work, because when I import all, it shows as a built-in function, and built-in functions are imported. However, when I ran the code, it showed that the math functions didn't work inside eval()

>>> from math import *
>>> sin
<built-in function sin>
>>> print
<built-in function print>
>>> eval("sin(30)", {}, {})
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    eval("sin(30)", {}, {})
  File "<string>", line 1, in <module>
NameError: name 'sin' is not defined

Would I have to add in all of the math functions manually, or is there an easier way to do this?


Solution

  • Regarding "safely", it depends on what you mean. You can provide access to your global environment easily enough, giving the expression access to whatever you've imported. But there is nothing to stop a user from entering an expression that can do unintended things, so if the expression is coming from an untrusted user, then you should avoid the use of eval.

    That having been said, you can make your example work as follows:

    >>> from math import *
    >>> eval("sin(30)", globals())
    -0.9880316240928618
    >>> 
    

    Note that in this example, 30 is being interpreted as radians rather than degrees.