Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #9
0
    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