Search code examples
pythoneval

Add functions to context when using python eval


I'd like to define some contextual functions that can then be used later, as per the example below.

def add(x, y):
    return x + y

def g(x):
    u = my_func(x, 4 ** x)
    return my_func(u, u // 2)

eval('g(1)', globals() | {'my_func': add})

This code throws NameError: name 'my_func' is not defined. Is there any way to achieve this (ideally without changing the functions add and g)?


Solution

  • When a function executes it looks up a name in the global namespace referenced by the function's __globals__ attribute, rather than the global namespace in which the call is made, so you would have to inject my_func into the function's __globals__ dict instead:

    def add(x, y):
        return x + y
    
    def g(x):
        u = my_func(x, 4 ** x)
        return my_func(u, u // 2)
    
    g.__globals__['my_func'] = add
    eval('g(1)')
    

    Demo: https://ideone.com/JVFRYE