use of exec()

lars van gemerden lars at rational-it.com
Thu Oct 18 07:41:27 EDT 2012


I am trying to implement a way to let users give a limited possibility to define functions in text, that wille be stored and executed at a later time. I use exec() to transform the text to a function. The code is as follows:

class code(str):
    def __call__(self, *args):
        try:
            return self._func_(*args)
        except AttributeError:
            self._func_ = self._creat_func_()
            return self._func_(*args)
    def __getstate__(self):
        return {}

class _lambdacode(code):
    def _creat_func_(self):
        return eval("lambda %s: %s" % (", ".join(type(self).args), self),{},{})
    
class _functioncode(code):
    def _creat_func_(self):
        exec("def function(%s):\n\t%s" % (", ".join(type(self).args), 
                                          "\n\t".join(self.split('\n'))))
        return function

def lambdatype(*argnames):
    return type('lambdacode', (_lambdacode,),{'args': argnames}) 

def functiontype(*argnames):
    return type('functioncode', (_functioncode,),{'args': argnames})
    
if __name__ == '__main__':
    f = lambdatype('a', 'b')('a ** b')
    print f
    print f(3, 4)
    print f(4, 3)
    
    g = functiontype('a', 'b')('a, b = a/b, a*b\nreturn a ** b')
    print g
    print g(3.0, 4.0) 
    print g(4.0, 3.0)

This code works. But if I replace _functioncode with:

class _functioncode(code):
    def _creat_func_(self):
        exec("def function(%s):\n\t%s" % (", ".join(type(self).args), 
                                          "\n\t".join(self.split('\n'))),{})
        return function

or

class _functioncode(code):
    def _creat_func_(self):
        exec("def function(%s):\n\t%s" % (", ".join(type(self).args), 
                                          "\n\t".join(self.split('\n'))),{},{})
        return function

to restrict access to global variables, similar to the lambda version, i get the error:

Traceback (most recent call last):
  File "D:\Documents\Code\Eclipse\workspace\FlowWare_1\toolshed\tests\mini_test.py", line 41, in <module>
    print g(3.0, 4.0)
  File "D:\Documents\Code\Eclipse\workspace\FlowWare_1\toolshed\tests\mini_test.py", line 13, in __call__
    self._func_ = self._creat_func_()
  File "D:\Documents\Code\Eclipse\workspace\FlowWare_1\toolshed\tests\mini_test.py", line 25, in _creat_func_
    return function
NameError: name 'function' is not defined

which seems an odd error, but i think some global variable is necessary for this to work (if i put in globals() instead of {}, it works).

My question is which variable or if that is not the problem, what is and how can i restrict access the user code has.

Cheers, Lars



More information about the Python-list mailing list