def _compile_call(self, text, attribute_handlers=None): import compiler import types from compiler import ast, misc, pycodegen raise NotImplementedError('Incomplete') # TODO Make this work? def _generate(node): if node.type == node.TERM: return ast.Compare(ast.Const(node.value), [('in', ast.Name('text'))]) elif node.type == node.AND: return ast.And([_generate(node.left), _generate(node.right)]) elif node.type == node.OR: return ast.Or([_generate(node.left), _generate(node.right)]) elif node.type == node.NOT: return ast.Not(_generate(node.left)) elif node.type == node.ATTR: raise NotImplementedError qast = ast.Expression( ast.Lambda(['self', 'text', 'attribute_handlers'], [ast.Name('None')], 0, _generate(self))) misc.set_filename('<%s compiled query>' % self.__class__.__name__, qast) gen = pycodegen.ExpressionCodeGenerator(qast) self.__call__ = types.MethodType(eval(gen.getCode()), self, Query) return self.__call__(text)
def eval(self, frame): # fall-back for unknown expression nodes try: expr = ast.Expression(self.__obj__) expr.filename = '<eval>' self.__obj__.filename = '<eval>' co = pycodegen.ExpressionCodeGenerator(expr).getCode() result = frame.eval(co) except passthroughex: raise except: raise Failure(self) self.result = result self.explanation = self.explanation or frame.repr(self.result)