Python Forum
eval lambda function with restricted context
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
Reply
#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
Reply
#3
My code is of course a minimal working example. Instead of "exp(1)" there will be an abritray expression supplied by the user.
Reply
#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
Reply
#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?"
Reply
#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
Reply
#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.
Reply
#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
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PROBLEM] Removing IDLE from context menu WebSpider 1 1,677 Sep-28-2023, 03:35 PM
Last Post: deanhystad
  Add two resultant fields from python lambda function klllmmm 4 2,529 Jun-06-2023, 05:11 PM
Last Post: rajeshgk
  with open context inside of a recursive function billykid999 1 1,923 May-23-2023, 02:37 AM
Last Post: deanhystad
  Context-sensitive delimiter ZZTurn 9 4,424 May-16-2023, 07:31 AM
Last Post: Gribouillis
  Running 3rd party libs on Steam Deck (Arch Linux) with restricted access metulburr 0 4,453 Jan-07-2023, 10:41 PM
Last Post: metulburr
  How does open context manager work? deanhystad 7 3,855 Nov-08-2022, 02:45 PM
Last Post: deanhystad
  Decimal context stevendaprano 1 1,952 Apr-11-2022, 09:44 PM
Last Post: deanhystad
  How to avoid exec(), globals(), locals(), eval() paul18fr 10 9,856 Apr-21-2021, 05:53 PM
Last Post: snippsat
  Writing a lambda function that sorts dictionary GJG 1 3,088 Mar-09-2021, 06:44 PM
Last Post: buran
  int, floats, eval menator01 2 3,642 Jun-26-2020, 09:03 PM
Last Post: menator01

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020
This forum uses Lukasz Tkacz MyBB addons.
Forum use Krzysztof "Supryk" Supryczynski addons.