In Lua, there’s a built-in function called setfenv(), which allows you to supply a table of variables as an environment for a function. Here’s an example that uses it:
foo = 1
function f()
print(blech) --Note that no variable named blech has been defined.
end
variableTable = {blech = foo}
setfenv(f, variableTable)
f() -- This will work and print 1, because blech has been defined as foo's value in the variableTable
My motivation for doing this is that it allows me to set up a platform so that users can write easy-to-understand scripts in Lua (they can write nullary functions and can simply trust that variables will be there for them). It also provides an elegant method of excluding modules and functions that I don’t want them to use for security reason (e.g. if you define a variable table that doesn’t have the os module defined, there’s no way a more knowledgeable user could use it maliciously).
I would like to be able to achieve the same thing in Python. Is there something similar that can be done in Python?
There’s
exec:This isn’t particularly good style (I would even say that it is particularly bad). It makes the implementation of
foodifficult to understand since it relies on knowing about the special way in which it will be called. Instead, pass arguments to functions.This does not provide any measure of security. As a first approximation, Python does not include any restricted execution capabilities. Nothing stops a user from supplying this definition of foo instead:
Just because you didn’t supply
osin the mapping doesn’t mean they can’t go get it themselves. If you really need restricted execution, then you might want to stick with Lua, or at least investigate PyPy sandboxed mode.