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
  Add two resultant fields from python lambda function klllmmm 4 848 Jun-06-2023, 05:11 PM
Last Post: rajeshgk
  with open context inside of a recursive function billykid999 1 549 May-23-2023, 02:37 AM
Last Post: deanhystad
  Context-sensitive delimiter ZZTurn 9 1,392 May-16-2023, 07:31 AM
Last Post: Gribouillis
  Running 3rd party libs on Steam Deck (Arch Linux) with restricted access metulburr 0 1,793 Jan-07-2023, 10:41 PM
Last Post: metulburr
  How does open context manager work? deanhystad 7 1,263 Nov-08-2022, 02:45 PM
Last Post: deanhystad
  Decimal context stevendaprano 1 1,009 Apr-11-2022, 09:44 PM
Last Post: deanhystad
  How to avoid exec(), globals(), locals(), eval() paul18fr 10 4,902 Apr-21-2021, 05:53 PM
Last Post: snippsat
  Writing a lambda function that sorts dictionary GJG 1 1,985 Mar-09-2021, 06:44 PM
Last Post: buran
  int, floats, eval menator01 2 2,402 Jun-26-2020, 09:03 PM
Last Post: menator01
  translating lambda in function fabs 1 2,121 Apr-28-2020, 05:18 AM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020