4

I'm working on a silly project in python that effectively implements a semi-REPL in a web-browser, and I'm stuck on how to cleanly dynamically evaluate code on-the-fly.

Basically, I have a web-form where the user enters a function, which should be then executed on the server.

The expected entry is a single function, with defined parameters. The function name, however, is not specified.

What I want is to get a string, such as:

def function_for_xxx(param_1, param_2, param_3):
    <stuff goes here>
    return interesting_value

and somehow convert that into a normal python function object (e.g. object of type <class 'function'>).

I can limit the scope of the task somewhat:

  • The user is explicitly trusted, so I don't have to worry about sanitization.
  • There are a few environment functions that should be passed into the function globals, but I can explicitly specify them.
  • Enforcing the string being a single bare function is actually desireable.

Right now, I've experimented a bit with the compile() and exec() calls, but they appear to insert the exec()ed code into the current local scope, which is non ideal. I'd really like the exec to be done without side effects like that, and just return a module or the bare function.

2
  • Why can't you save it as a .py file and execute it? Commented Feb 27, 2017 at 4:07
  • @MotKohn - That just moves the problem around. Then I'd be having to load modules on the fly. And it's a lot less elegant. And I have a LOT of these functions that can all be changed independently (several hundreds to a few thousands). Commented Feb 27, 2017 at 4:21

1 Answer 1

3

Ok, I figured out a workaround that is kind of hackish, but does what I want.

Basically, we can exploit the fact that we can specify the execution scope to exec() calls by specifying the globals parameter.

func_container = compile(func"\n", "<dynamic_functions_xxx>", "exec")

scope = {
    <objects made available to the dynamic function>
}
exec(func_container, scope)

Objects defined in the func string are now present in the scope variable, with no side effects to the local namespace.

General comments apply here. If you can memoize the compile/exec process, doing so is probably a good idea (compiling is slow!).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.