Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 eval lambda function with restricted context
#1
Hello,

I would like to create a lambda function accessing Numpy functions, and only them. I can do the following:

import numpy
eval('exp(1)', {'__builtins__': None}, numpy.__dict__)
Output:
2.7182818284590451
However, I get an error when I create a lambda function in that way:

f = eval('lambda x:exp(1)', {'__builtins__': None}, numpy.__dict__)
f(0)
Error:
TypeError: 'NoneType' object is not subscriptable
Could you explain why and provide a working example?

Olivier
Quote
#2
Can you explain why you would want to do this? Why not just use lambda x: numpy.exp(1)? And why evaluate a lambda anyway?
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures

Quote
#3
My code is of course a minimal working example. Instead of "exp(1)" there will be an abritray expression supplied by the user.
Quote
#4
Then I think it would be better to do this with a dictionary of the necessary functions. Parse out the function name and the parameters, find the actual function in the dictionary, and apply the parameters.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures

Quote
#5
Sorry, my browser sent the message while I was writing it, against my will. I start again.

You want me to write a general parser for mathematical expressions? I won't do that! First, it is a huge work (I expect arbitrary mathematical expressions to be treated). Second, I already have the parser in the computer, and it is called Python! There should be a way to use it properly. The following way does what I want, but is not clean.
from numpy import *
f = eval('lambda x:exp(1)')
f(0)
Output:
2.718281828459045
It is not clean because, first, it clutters the namespace, second, it doesn't restrict the functions that can be accessed. My initial question can be rephrased into: "why does the example in this message work? and why does the code in the initial message doesn't work?"
Quote
#6
You want to allow the user to enter arbitrarily complicated expressions and get the result? I would just have them use the Python interpreter. If you really want to do this, I think you need to make built-ins a dictionary. Making it an empty dictionary is probably going to cause problems evaluating things. You might want to copy the actual built-ins and delete what you don't want. I would only do this if the context is that the user is running the program on his own machine. Otherwise it is a huge security hole.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures

Quote
#7
(Mar-04-2019, 08:02 PM)Olivier Wrote: why does the code in the initial message doesn't work?
The function you're creating doesn't have any locals, so python tries getting exp form globals.
Since you've defined globals as {'__builtins__': None}, you get an error.

One way to make this "work" would be:
f = eval('lambda x, exp=exp: exp(1)', {'__builtins__': None}, numpy.__dict__)
Note that, other than being awful code, this doesn't actually limit what functionality a user can access.
There are many ways to access functions and objects in python which don't require actually using their name.
Therefore, if you let a knowledgeable user eval arbitrary code, they can access pretty much any part of the language, no matter what args you use.
ichabod801 likes this post
Quote
#8
Regarding security, I know that it is not absolutely safe. But IMO it's better to do something partly than do nothing.

I think that Stranac gave a good hint! Use the globals! Accordingly, the following code is functional and seems to be satisfying for my need:

import numpy
symbol_table = numpy.__dict__.copy()
symbol_table['__builtins__'] = None         # remove built-in functions
f = eval('lambda x:exp(1)', symbol_table)
In my first post, I was not understanding the use of locals in the eval() function. I still do not understand exactly what it is meant to be used for, but I think that in the context of my question, the globals should be used.

Thank you for the help.

Olivier
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  Question about using lambda hikerguy62 4 172 Aug-18-2019, 09:04 AM
Last Post: ThomasL
  Using map and lambda in a matrix ricardodepaula 3 142 Jul-21-2019, 03:42 PM
Last Post: ricardodepaula
  Lambda function Uchikago 3 178 Jul-16-2019, 08:56 AM
Last Post: perfringo
  Is it OK to use a context manager to simplify attribute access? nholtz 0 154 Jun-11-2019, 01:19 AM
Last Post: nholtz
  AssertionError: View function mapping is overwriting an existing endpoint function Zhavi221 7 1,284 Apr-17-2019, 01:07 PM
Last Post: Zhavi221
  Smtplib: What does context argument means? Pythenx 1 247 Mar-27-2019, 06:25 PM
Last Post: nilamo
  How can I prevent context switching when calling an async function? AlekseyPython 1 288 Feb-20-2019, 10:37 AM
Last Post: AlekseyPython
  AWS lambda script help - Listing untagged volumes jutler 0 306 Feb-13-2019, 02:36 PM
Last Post: jutler
  Restricted pip xxp2 0 170 Feb-13-2019, 06:25 AM
Last Post: xxp2
  Visual Studio Code - PEP8 Lambda Issue Qui_Ten 1 269 Jan-28-2019, 08:17 AM
Last Post: buran

Forum Jump:


Users browsing this thread: 1 Guest(s)