def compile_let(builder, args, kw, star, dstar): """Compile the let() function""" if args or star or dstar: raise TypeError("let() only accepts inline keyword arguments") for k,v in kw: k = build(builder, k) assert type(k) is Const and isinstance(k.value, basestring) k = k.value v = build(builder, v) builder.bind({k:v}) return True
def compile_let(builder, args, kw, star, dstar): """Compile the let() function""" if args or star or dstar: raise TypeError("let() only accepts inline keyword arguments") for k, v in kw: k = build(builder, k) assert type(k) is Const and isinstance(k.value, basestring) k = k.value v = build(builder, v) builder.bind({k: v}) return True
def build_pattern(builder, node): old = builder.__class__ builder.__class__ = SyntaxBuilder try: return build(builder, node) finally: builder.__class__ = old
def expand(builder, *args): builder.push(bindings) # globals, locals, etc. builder.bind(apply_meta(builder, (getargs, {}, arginfo), *args)) # build in the newly-isolated namespace result = build(builder, parsed) builder.pop() return result
def _expand_as(func, predicate_string, *namespaces): """Pre-parse predicate string and register meta function""" args, varargs, kw, defaults = arginfo = inspect.getargspec(func) argnames = list(flatten(filter(None, [args, varargs, kw]))) parsed = parser.expr(predicate_string).totuple(1)[1] builder = CriteriaBuilder( dict([(arg,Local(arg)) for arg in argnames]), *namespaces ) bindings = {} for b in builder.bindings[-len(namespaces):][::-1]: bindings.update(b) # Make a function that just gets the arguments we want c = Code.from_function(func) c.return_(Call(Const(locals),fold=False)) getargs = new.function( c.code(), func.func_globals, func.func_name, func.func_defaults, func.func_closure ) def expand(builder, *args): builder.push(bindings) # globals, locals, etc. builder.bind(apply_meta(builder, (getargs, {}, arginfo), *args)) # build in the newly-isolated namespace result = build(builder, parsed) builder.pop() return result meta_functions[func] = expand c = Code.from_function(func) c.return_() if func.func_code.co_code == c.code().co_code: # function body is empty c = Code.from_function(func) c.return_(build(builder, parsed)) func.func_code = c.code() return func
def _expand_as(func, predicate_string, *namespaces): """Pre-parse predicate string and register meta function""" args, varargs, kw, defaults = arginfo = inspect.getargspec(func) argnames = list(flatten(filter(None, [args, varargs, kw]))) parsed = parser.expr(predicate_string).totuple(1)[1] builder = CriteriaBuilder(dict([(arg, Local(arg)) for arg in argnames]), *namespaces) bindings = {} for b in builder.bindings[-len(namespaces):][::-1]: bindings.update(b) # Make a function that just gets the arguments we want c = Code.from_function(func) c.return_(Call(Const(locals), fold=False)) getargs = new.function(c.code(), func.func_globals, func.func_name, func.func_defaults, func.func_closure) def expand(builder, *args): builder.push(bindings) # globals, locals, etc. builder.bind(apply_meta(builder, (getargs, {}, arginfo), *args)) # build in the newly-isolated namespace result = build(builder, parsed) builder.pop() return result meta_functions[func] = expand func.__doc__ # workaround for PyPy issue #1293 c = Code.from_function(func) c.return_() if func.func_code.co_code == c.code().co_code: # function body is empty c = Code.from_function(func) c.return_(build(builder, parsed)) func.func_code = c.code() return func
def Compare(self, expr, ops): return Compare(build(self, expr), [(op == '<>' and '!=' or op, build(self, arg)) for op, arg in ops])
elif name=='__dstar__': data[name] = parse(name, dstar) else: break offset += 1 for k, v in zip(argnames[offset:], args): data[k] = parse(k, v) varargpos = len(argnames)-offset if len(args)> varargpos: if not varargs: raise TypeError("Too many arguments for %r" % (func,)) extra.extend([parse(varargs, node) for node in args[varargpos:]]) for k,v in kw: k = build(builder, k) assert type(k) is Const and isinstance(k.value, basestring) k = k.value if k in data: raise TypeError("Duplicate keyword %s for %r" % (k,func)) if varkw and k not in argnames and k not in parsers: data[k] = parse(varkw, v) else: data[k] = parse(k, v) if star and '__star__' not in data: raise TypeError("%r does not support parsing *args" % (func,)) if dstar and '__dstar__' not in data: raise TypeError("%r does not support parsing **kw" % (func,))
def build_with(self, expr): self.push() try: return build(self, expr) finally: self.pop()
def method(self, items): result = build(self,items[0]) for item in items[1:]: result = nt(result, build(self,item)) return result
def Getattr(self, expr, attr): return Getattr(build(self,expr), attr)
def method(self, expr): return nt(build(self,expr))
def Slice2(self, start, stop): start = start and build(self, start) or Pass stop = stop and build(self, stop ) or Pass return GetSlice(Pass, start, stop)
def Subscript(self, left, right): expr = build(self, left) key = build(self, right) if isinstance(key, GetSlice): return GetSlice(expr, key.start, key.stop) return Getitem(expr, key)
def Getattr(self, expr, attr): return Getattr(build(self, expr), attr)
def Slice3(self, start, stop, stride): start = start and build(self, start) or Pass stop = stop and build(self, stop) or Pass stride = stride and build(self, stride) or Pass return BuildSlice(start, stop, stride)
def Slice2(self, start, stop): start = start and build(self, start) or Pass stop = stop and build(self, stop) or Pass return GetSlice(Pass, start, stop)
def Subscript(self, left, right): expr = build(self,left) key = build(self,right) if isinstance(key, GetSlice): return GetSlice(expr, key.start, key.stop) return Getitem(expr, key)
def method(self, expr): return nt(build(self, expr))
def Slice3(self, start, stop, stride): start = start and build(self, start ) or Pass stop = stop and build(self, stop ) or Pass stride = stride and build(self, stride) or Pass return BuildSlice(start, stop, stride)
def method(self, left, right): return nt(build(self, left), build(self, right))
def Compare(self, expr, ops): return Compare( build(self, expr), [(op=='<>' and '!=' or op, build(self,arg)) for op, arg in ops] )
def method(self, items): result = build(self, items[0]) for item in items[1:]: result = nt(result, build(self, item)) return result
def method(self, left, right): return nt(build(self,left), build(self,right))
def IfElse(self, tval, cond, fval): return IfElse(build(self, tval), build(self, cond), build(self, fval))
def IfElse(self, tval, cond, fval): return IfElse(build(self,tval), build(self,cond), build(self,fval))
elif name == '__dstar__': data[name] = parse(name, dstar) else: break offset += 1 for k, v in zip(argnames[offset:], args): data[k] = parse(k, v) varargpos = len(argnames) - offset if len(args) > varargpos: if not varargs: raise TypeError("Too many arguments for %r" % (func, )) extra.extend([parse(varargs, node) for node in args[varargpos:]]) for k, v in kw: k = build(builder, k) assert type(k) is Const and isinstance(k.value, basestring) k = k.value if k in data: raise TypeError("Duplicate keyword %s for %r" % (k, func)) if varkw and k not in argnames and k not in parsers: data[k] = parse(varkw, v) else: data[k] = parse(k, v) if star and '__star__' not in data: raise TypeError("%r does not support parsing *args" % (func, )) if dstar and '__dstar__' not in data: raise TypeError("%r does not support parsing **kw" % (func, ))