def visit_Name(self, node): """ Replace name with full expanded name. Examples -------- >> from numpy.linalg import det >> det(a) Becomes >> numpy.linalg.det(a) """ if node.id in self.symbols: symbol = path_to_node(self.symbols[node.id]) if not getattr(symbol, 'isliteral', lambda: False)(): parent = self.ancestors[node][-1] blacklist = (ast.Tuple, ast.List, ast.Set, ast.Return) if isinstance(parent, blacklist): raise PythranSyntaxError( "Unsupported module identifier manipulation", node) new_node = path_to_attr(self.symbols[node.id]) new_node.ctx = node.ctx ast.copy_location(new_node, node) return new_node return node
def inlineFixedSizeArrayBinOp(self, node): alike = ast.List, ast.Tuple, ast.Constant if isinstance(node.left, alike) and isinstance(node.right, alike): return node lbase, lsize = self.fixedSizeArray(node.left) rbase, rsize = self.fixedSizeArray(node.right) if not lbase or not rbase: return node if rsize != 1 and lsize != 1 and rsize != lsize: raise PythranSyntaxError("Invalid numpy broadcasting", node) self.update = True operands = [ ast.BinOp(self.make_array_index(lbase, lsize, i), type(node.op)(), self.make_array_index(rbase, rsize, i)) for i in range(max(lsize, rsize)) ] res = ast.Call(path_to_attr(('numpy', 'array')), [ast.Tuple(operands, ast.Load())], []) self.aliases[res.func] = {path_to_node(('numpy', 'array'))} return res
def visit_Assign(self, node): """ Update import context using overwriting name information. Examples -------- >> import foo >> def bar(): >> foo = 2 >> print foo In this case, foo can't be used after assign. """ if isinstance(node.value, ast.Name) and node.value.id in self.symbols: symbol = path_to_node(self.symbols[node.value.id]) if not getattr(symbol, 'isliteral', lambda: False)(): for target in node.targets: if not isinstance(target, ast.Name): err = "Unsupported module aliasing" raise PythranSyntaxError(err, target) self.symbols[target.id] = self.symbols[node.value.id] return None # this assignment is no longer needed new_node = self.generic_visit(node) # no problem if targets contains a subscript, it is not a new assign. [ self.symbols.pop(t.id, None) for t in new_node.targets if isinstance(t, ast.Name) ] return new_node
def inlineFixedSizeArrayCompare(self, node): if len(node.comparators) != 1: return node node_right = node.comparators[0] alike = ast.Num, ast.List, ast.Tuple if isinstance(node.left, alike) and isinstance(node_right, alike): return node lbase, lsize = self.fixedSizeArray(node.left) rbase, rsize = self.fixedSizeArray(node_right) if not lbase or not rbase: return node if rsize != 1 and lsize != 1 and rsize != lsize: raise PythranSyntaxError("Invalid numpy broadcasting", node) self.update = True operands = [ ast.Compare(self.make_array_index(lbase, lsize, i), [type(node.ops[0])()], [self.make_array_index(rbase, rsize, i)]) for i in range(max(lsize, rsize)) ] res = ast.Call(path_to_attr(('numpy', 'array')), [ast.Tuple(operands, ast.Load())], []) self.aliases[res.func] = {path_to_node(('numpy', 'array'))} return res
def inlineFixedSizeArrayCompare(self, node): if len(node.comparators) != 1: return node node_right = node.comparators[0] alike = ast.Num, ast.List, ast.Tuple if isinstance(node.left, alike) and isinstance(node_right, alike): return node lbase, lsize = self.fixedSizeArray(node.left) rbase, rsize = self.fixedSizeArray(node_right) if not lbase or not rbase: return node if rsize != 1 and lsize != 1 and rsize != lsize: raise PythranSyntaxError("Invalid numpy broadcasting", node) self.update = True operands = [ast.Compare(self.make_array_index(lbase, lsize, i), [type(node.ops[0])()], [self.make_array_index(rbase, rsize, i)]) for i in range(max(lsize, rsize))] res = ast.Call(path_to_attr(('numpy', 'array')), [ast.Tuple(operands, ast.Load())], []) self.aliases[res.func] = {path_to_node(('numpy', 'array'))} return res
def visit_Assign(self, node): """ Update import context using overwriting name information. Examples -------- >> import foo >> def bar(): >> foo = 2 >> print foo In this case, foo can't be used after assign. """ if isinstance(node.value, ast.Name) and node.value.id in self.symbols: symbol = path_to_node(self.symbols[node.value.id]) if not getattr(symbol, 'isliteral', lambda: False)(): for target in node.targets: if not isinstance(target, ast.Name): err = "Unsupported module aliasing" raise PythranSyntaxError(err, target) self.symbols[target.id] = self.symbols[node.value.id] return None # this assignment is no longer needed new_node = self.generic_visit(node) # no problem if targets contains a subscript, it is not a new assign. [self.symbols.pop(t.id, None) for t in new_node.targets if isinstance(t, ast.Name)] return new_node
def find_matching_builtin(self, node): """ Return matched keyword. If the node alias on a correct keyword (and only it), it matches. """ for path in EQUIVALENT_ITERATORS.keys(): correct_alias = {path_to_node(path)} if self.aliases[node.func] == correct_alias: return path
def inlineFixedSizeArrayUnaryOp(self, node): if isinstance(node.operand, (ast.Num, ast.List, ast.Tuple)): return node base, size = self.fixedSizeArray(node.operand) if not base: return node self.update = True operands = [ ast.UnaryOp(type(node.op)(), self.make_array_index(base, size, i)) for i in range(size) ] res = ast.Call(path_to_attr(('numpy', 'array')), [ast.Tuple(operands, ast.Load())], []) self.aliases[res.func] = {path_to_node(('numpy', 'array'))} return res
def inlineFixedSizeArrayUnaryOp(self, node): if isinstance(node.operand, (ast.Num, ast.List, ast.Tuple)): return node base, size = self.fixedSizeArray(node.operand) if not base: return node self.update = True operands = [ast.UnaryOp(type(node.op)(), self.make_array_index(base, size, i)) for i in range(size)] res = ast.Call(path_to_attr(('numpy', 'array')), [ast.Tuple(operands, ast.Load())], []) self.aliases[res.func] = {path_to_node(('numpy', 'array'))} return res