import math import re print sorted(dir(math)) print sorted(dir(globals()['__builtins__'])) print vars(math) print __import__ print repr g = globals() g = {} g['__builtins__'] = {} def GenSet(l): def Set(k, v): l[k] = v return Set l = dict(a=1, b=2, c=3,) l['Set']=GenSet(l) l['L']=l l['G']=g exec """ #globals() #import math def Foo(): #import math return 'diabled' #return math.sin(4) """ in g, l print eval("""( Set('x', 24), x*x, L, G, `G`, #Foo(), )""", g, l) class RhubarbPy(object): MATCH_ERROR = re.compile('^[A-Z][A-Za-z]+Error$').match SAFE_LIST_BUILTINS = [ 'True', 'False', 'None', 'bool', 'int', 'long', 'float', 'str', 'complex', 'dict', 'list', 'tuple', 'set', 'hex', 'type', 'chr', 'ord', 'repr', 'sorted', 'cmp', 'divmod', 'hash', 'enumerate', 'iter', 'range', 'xrange', 'len', 'map', 'reduce', 'filter', 'zip', 'max', 'min', 'any', 'all', 'Exception', 'RuntimeError', 'StopIteration', 'GeneratorExit', ] SAFE_LIST_MATH = [ 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' ] def __init__(self, additions): self.g = additions import math math_vars = vars(math) b = vars(globals()['__builtins__']) for i in self.SAFE_LIST_BUILTINS: self.g[i] = b[i] for i in filter(self.MATCH_ERROR, globals().keys()): self.g[i] = b[i] for i in self.SAFE_LIST_MATH: self.g[i] = math_vars[i] # Obliterate the builtins: self.g['__builtins__'] = None def Exec(self, suite): self.g['__builtins__'] = None exec suite in self.g, self.g self.g['__builtins__'] = None def GenSet(self, l): def Set(k, v): l[k] = v return Set def GenIf(self, l): def If(cond, block_t, block_f): if cond: return block_t() else: return block_f() return If def GenMap(self, l): def Map(vec, block): return (block(x) for x in vec) return Map def Eval(self, expression): l = {} l['Set'] = self.GenSet(l) g['If'] = self.GenIf(l) g['For'] = self.GenMap(l) g['Map'] = self.GenMap(l) l['Locals'] = l g['Globals'] = self.g self.g['__builtins__'] = None #self.g['__getitem__'] = lambda a, b: l[b] return eval(expression, self.g, l) def Repl(self): import sys print >>sys.stderr, "<<<<", #for line in open('/dev/stdin', 'r', 0): while True: line =sys.stdin.readline() if not line: break z = self.Eval(line.strip()) print >>sys.stderr, ">>>", z print >>sys.stderr, "<<<<", r = RhubarbPy(g) print sorted(r.Eval('Globals').keys()) r.Repl() # (Set('z', range(10)), list(For(z, lambda x: x*x))) # (Set('z', range(10)), list(For(z, lambda x: x*If(x<5, lambda: 10*x, lambda: x)))) # (Set('z', range(10)), list(For(z, lambda x: x*If(x<5, lambda: len(z)*x, lambda: x))))