Exemple #1
0
class ReversedRangePattern(Pattern):
    # __builtin__.reversed(__builtin__.xrange(X)) =>
    # __builtin__.xrange(X-1, -1, -1)
    # FIXME : We should do it even when begin/end/step are given
    pattern = ast.Call(func=ast.Attribute(value=ast.Name(id='__builtin__',
                                                         ctx=ast.Load(),
                                                         annotation=None,
                                                         type_comment=None),
                                          attr="reversed", ctx=ast.Load()),
                       args=[ast.Call(
                           func=ast.Attribute(
                               value=ast.Name(id='__builtin__',
                                              ctx=ast.Load(), annotation=None,
                                              type_comment=None),
                               attr=range_name, ctx=ast.Load()),
                           args=[Placeholder(0)],
                           keywords=[])],
                       keywords=[])

    @staticmethod
    def sub():
        return ast.Call(
            func=ast.Attribute(value=ast.Name(id='__builtin__',
                                              ctx=ast.Load(), annotation=None,
                                              type_comment=None),
                               attr=range_name, ctx=ast.Load()),
            args=[ast.BinOp(left=Placeholder(0), op=ast.Sub(),
                            right=ast.Constant(1, None)),
                  ast.Constant(-1, None),
                  ast.Constant(-1, None)],
            keywords=[])
Exemple #2
0
    def visit_Raise(self, node):
        ntype = self._visit(node.type)
        ninst = self._visit(node.inst)
        ntback = self._visit(node.tback)

        what = ntype

        if ninst is not None:
            what = gast.Call(ntype, [ninst], [])
            gast.copy_location(what, node)
            what.end_lineno = what.end_col_offset = None

        if ntback is not None:
            attr = gast.Attribute(what, 'with_traceback', gast.Load())
            gast.copy_location(attr, node)
            attr.end_lineno = attr.end_col_offset = None

            what = gast.Call(attr, [ntback], [])
            gast.copy_location(what, node)
            what.end_lineno = what.end_col_offset = None

        new_node = gast.Raise(what, None)

        gast.copy_location(new_node, node)
        new_node.end_lineno = new_node.end_col_offset = None
        return new_node
Exemple #3
0
class TupleListPattern(Pattern):
    # __builtin__.tuple(__builtin__.list(X)) => __builtin__.tuple(X)

    pattern = ast.Call(
        func=ast.Attribute(value=ast.Name('__builtin__', ast.Load(), None,
                                          None),
                           attr="tuple",
                           ctx=ast.Load()),
        args=[
            ast.Call(func=ast.Attribute(value=ast.Name('__builtin__',
                                                       ast.Load(), None, None),
                                        attr="list",
                                        ctx=ast.Load()),
                     args=[Placeholder(0)],
                     keywords=[])
        ],
        keywords=[])

    @staticmethod
    def sub():
        return ast.Call(func=ast.Attribute(value=ast.Name(id='__builtin__',
                                                          ctx=ast.Load(),
                                                          annotation=None,
                                                          type_comment=None),
                                           attr="tuple",
                                           ctx=ast.Load()),
                        args=[Placeholder(0)],
                        keywords=[])
Exemple #4
0
class AbsSqrPattern(Pattern):
    # __builtin__.abs(X) ** 2 => __builtin__.pythran.abssqr(X)

    pattern = ast.Call(func=ast.Attribute(value=ast.Name(id=mangle('numpy'),
                                                         ctx=ast.Load(),
                                                         annotation=None,
                                                         type_comment=None),
                                          attr="square",
                                          ctx=ast.Load()),
                       args=[
                           ast.Call(func=ast.Attribute(value=ast.Name(
                               id='__builtin__',
                               ctx=ast.Load(),
                               annotation=None,
                               type_comment=None),
                                                       attr="abs",
                                                       ctx=ast.Load()),
                                    args=[Placeholder(0)],
                                    keywords=[])
                       ],
                       keywords=[])

    @staticmethod
    def sub():
        return ast.Call(func=ast.Attribute(value=ast.Attribute(value=ast.Name(
            id='__builtin__',
            ctx=ast.Load(),
            annotation=None,
            type_comment=None),
                                                               attr="pythran",
                                                               ctx=ast.Load()),
                                           attr="abssqr",
                                           ctx=ast.Load()),
                        args=[Placeholder(0)],
                        keywords=[])
Exemple #5
0
class LenRangePattern(Pattern):
    # builtins.len(builtins.range(X)) => max(0, X)
    pattern = ast.Call(
        func=ast.Attribute(value=ast.Name('builtins', ast.Load(), None, None),
                           attr="len",
                           ctx=ast.Load()),
        args=[
            ast.Call(func=ast.Attribute(value=ast.Name('builtins', ast.Load(),
                                                       None, None),
                                        attr="range",
                                        ctx=ast.Load()),
                     args=[Placeholder(0)],
                     keywords=[])
        ],
        keywords=[])

    @staticmethod
    def sub():
        return ast.Call(func=ast.Attribute(value=ast.Name(
            'builtins', ast.Load(), None, None),
                                           attr="max",
                                           ctx=ast.Load()),
                        args=[ast.Constant(0, None),
                              Placeholder(0)],
                        keywords=[])
Exemple #6
0
    def visit_Raise(self, node):
        ntype = self._visit(node.type)
        ninst = self._visit(node.inst)
        ntback = self._visit(node.tback)

        what = ntype

        if ninst is not None:
            what = gast.Call(ntype, [ninst], [])
            ast.copy_location(what, node)

        if ntback is not None:
            attr = gast.Attribute(what, 'with_traceback', gast.Load())
            ast.copy_location(attr, node)

            what = gast.Call(
                attr,
                [ntback],
                []
            )
            ast.copy_location(what, node)

        new_node = gast.Raise(what, None)

        ast.copy_location(new_node, node)
        return new_node
Exemple #7
0
class LenSetPattern(Pattern):
    # __builtin__.len(__builtin__.set(X)) => __builtin__.pythran.len_set(X)
    pattern = ast.Call(
        func=ast.Attribute(value=ast.Name('__builtin__', ast.Load(), None,
                                          None),
                           attr="len",
                           ctx=ast.Load()),
        args=[
            ast.Call(func=ast.Attribute(value=ast.Name('__builtin__',
                                                       ast.Load(), None, None),
                                        attr="set",
                                        ctx=ast.Load()),
                     args=[Placeholder(0)],
                     keywords=[])
        ],
        keywords=[])

    @staticmethod
    def sub():
        return ast.Call(func=ast.Attribute(value=ast.Attribute(value=ast.Name(
            '__builtin__', ast.Load(), None, None),
                                                               attr="pythran",
                                                               ctx=ast.Load()),
                                           attr="len_set",
                                           ctx=ast.Load()),
                        args=[Placeholder(0)],
                        keywords=[])
Exemple #8
0
 def visit_loop(self, node, update_mask=gast.NameConstant(value=None)):
     node = FuseAttributes().visit(node)
     loads, stores = defaultdict(list), set()
     for child in node.body:
         for n in gast.walk(child):
             if isinstance(n, gast.Name) and isinstance(n.ctx, gast.Load):
                 loads[n.id].append(n)
         if isinstance(child, gast.Assign):
             if len(child.targets) > 1:
                 raise NotImplementedError("cannot process LCD that is "
                                           "part of multiple assignment")
             name = child.targets[0].id
             if name in loads:
                 if name in stores:
                     raise NotImplementedError("cannot process LCD "
                                               "stored to twice")
                 # $var = $expr -> $var = $var._update($expr)
                 child.value = gast.Call(
                     gast.Attribute(gast.Name(name, gast.Load(), None),
                                    gast.Name('_update', gast.Load(), None),
                                    None), [child.value, update_mask], [])
                 stores.add(name)
     node = SplitAttributes().visit(node)
     synchronizes = []
     for name in stores:
         synchronize = gast.Assign(
             [gast.Name(name, gast.Store(), None)],
             gast.Call(
                 gast.Attribute(
                     gast.Name(name, gast.Load(), None),
                     gast.Name('_synchronize', gast.Load(), None), None),
                 [], []))
         synchronizes.append(synchronize)
     node.body.extend(synchronizes)
     return node
Exemple #9
0
 def visit_Assign(self, node):
     if len(node.targets) > 1:
         raise NotImplementedError("cannot process multiple assignment")
     if not isinstance(node.targets[0], gast.Name):
         raise NotImplementedError("cannot process indexed assignment")
     # $lhs = $lhs.update_($rhs, matchbox.EXECUTION_MASK) if (lhs in vars()
     # or lhs in globals()) and isinstance($lhs, (matchbox.MaskedBatch,
     # matchbox.TENSOR_TYPE)) else $rhs
     node.value = gast.IfExp(
         gast.BoolOp(
             gast.And(),
             [
                 gast.BoolOp(gast.Or(), [
                     gast.Compare(gast.Str(
                         node.targets[0].id), [gast.In()], [
                             gast.Call(gast.Name('vars', gast.Load, None),
                                       [], [])
                         ]),
                     gast.Compare(gast.Str(
                         node.targets[0].id), [gast.In()], [
                             gast.Call(
                                 gast.Name('globals', gast.Load, None), [],
                                 [])
                         ])
                 ]),
                 # gast.Compare(
                 #    gast.Attribute(
                 #      gast.Name('matchbox', gast.Load(), None),
                 #      gast.Name('EXECUTION_MASK', gast.Load(), None),
                 #      gast.Load()),
                 #    [gast.IsNot()],
                 #    [gast.NameConstant(None)]),
                 gast.Call(gast.Name('isinstance', gast.Load(), None), [
                     node.targets[0],
                     gast.Tuple([
                         gast.Attribute(
                             gast.Name('matchbox', gast.Load(), None),
                             gast.Name('MaskedBatch', gast.Load(), None),
                             gast.Load()),
                         gast.Attribute(
                             gast.Name('matchbox', gast.Load(), None),
                             gast.Name('TENSOR_TYPE', gast.Load(), None),
                             gast.Load())
                     ], gast.Load())
                 ], [])
             ]),
         gast.Call(
             gast.Attribute(
                 gast.Name(node.targets[0].id, gast.Load(), None),
                 gast.Name('_update', gast.Load(), None), gast.Load()), [
                     node.value,
                     gast.Attribute(
                         gast.Name('matchbox', gast.Load(), None),
                         gast.Name('EXECUTION_MASK', gast.Load(), None),
                         gast.Load())
                 ], []),
         node.value)
     return node
    def visit_Attribute(self, node):
        node = self.generic_visit(node)
        # method name -> not a getattr
        if node.attr in methods:

            # Make sure parent is'nt a call, it's already handled in visit_Call
            for parent in reversed(self.ancestors.get(node, ())):
                if isinstance(parent, ast.Attribute):
                    continue
                if isinstance(parent, ast.Call):
                    return node
                break

            # we have a bound method which is not a call
            obj = self.baseobj(node)
            if obj is not None:
                self.update = True
                mod = methods[node.attr][0]
                self.to_import.add(mangle(mod[0]))
                func = self.attr_to_func(node)
                z = ast.Call(
                    ast.Attribute(
                        ast.Name(mangle('functools'), ast.Load(), None, None),
                        "partial", ast.Load()), [func, obj], [])
                return z
            else:
                return node
        # imported module -> not a getattr
        elif (isinstance(node.value, ast.Name)
              and node.value.id in self.imports):
            module_id = self.imports[node.value.id]
            if node.attr not in MODULES[self.renamer(module_id, MODULES)[1]]:
                msg = ("`" + node.attr + "' is not a member of " +
                       demangle(module_id) + " or Pythran does not support it")
                raise PythranSyntaxError(msg, node)
            node.value.id = module_id  # patch module aliasing
            self.update = True
            return node
        # not listed as attributed -> not a getattr
        elif node.attr not in attributes:
            return node
        # A getattr !
        else:
            self.update = True
            call = ast.Call(
                ast.Attribute(ast.Name('builtins', ast.Load(), None, None),
                              'getattr', ast.Load()),
                [node.value, ast.Constant(node.attr, None)], [])
            if isinstance(node.ctx, ast.Store):
                # the only situation where this arises is for real/imag of
                # a ndarray. As a call is not valid for a store, add a slice
                # to ends up with a valid lhs
                assert node.attr in ('real', 'imag'), "only store to imag/real"
                return ast.Subscript(call, ast.Slice(None, None, None),
                                     node.ctx)
            else:
                return call
 def makeattr(*args):
     r = ast.Attribute(value=ast.Name(id='builtins',
                                      ctx=ast.Load(),
                                      annotation=None,
                                      type_comment=None),
                       attr='map',
                       ctx=ast.Load())
     r = ast.Call(r, list(args), [])
     r = ast.Call(
         ast.Attribute(ast.Name('builtins', ast.Load(), None, None),
                       'list', ast.Load()), [r], [])
     return r
Exemple #12
0
 def visit_Assert(self, node):
     if not self.static_analysis_visitor.is_tensor_node(node.test):
         return node
     cast_node = gast.Call(
         func=gast.parse("fluid.layers.cast").body[0].value,
         args=[node.test, gast.Constant(value="bool", kind=None)],
         keywords=[])
     assert_node = gast.Call(
         func=gast.parse("fluid.layers.Assert").body[0].value,
         args=[cast_node],
         keywords=[])
     return gast.Expr(value=assert_node)
Exemple #13
0
 def makeattr(*args):
     r = ast.Attribute(value=ast.Name(id='__builtin__',
                                      ctx=ast.Load(),
                                      annotation=None),
                       attr='map',
                       ctx=ast.Load())
     r = ast.Call(r, list(args), [])
     if sys.version_info.major == 3:
         r = ast.Call(
             ast.Attribute(ast.Name('__builtin__', ast.Load(), None),
                           'list', ast.Load()), [r], [])
     return r
 def build(maxval, body):
     return gast.For(target=make_name(fresh_name),
                     iter=gast.Call(func=make_name("range"),
                                    args=[
                                        gast.Call(func=make_name("int"),
                                                  args=[maxval],
                                                  keywords=[])
                                    ],
                                    keywords=[]),
                     body=body,
                     orelse=[],
                     type_comment=None)
Exemple #15
0
def size_container_folding(value):
    """
    Convert value to ast expression if size is not too big.

    Converter for sized container.
    """
    def size(x):
        return len(getattr(x, 'flatten', lambda: x)())

    if size(value) < MAX_LEN:
        if isinstance(value, list):
            return ast.List([to_ast(elt) for elt in value], ast.Load())
        elif isinstance(value, tuple):
            return ast.Tuple([to_ast(elt) for elt in value], ast.Load())
        elif isinstance(value, set):
            if value:
                return ast.Set([to_ast(elt) for elt in value])
            else:
                return ast.Call(func=ast.Attribute(
                    ast.Name(mangle('builtins'), ast.Load(), None, None),
                    'set', ast.Load()),
                                args=[],
                                keywords=[])
        elif isinstance(value, dict):
            keys = [to_ast(elt) for elt in value.keys()]
            values = [to_ast(elt) for elt in value.values()]
            return ast.Dict(keys, values)
        elif isinstance(value, np.ndarray):
            if len(value) == 0:
                return ast.Call(
                    func=ast.Attribute(
                        ast.Name(mangle('numpy'), ast.Load(), None, None),
                        'empty', ast.Load()),
                    args=[to_ast(value.shape),
                          dtype_to_ast(value.dtype.name)],
                    keywords=[])
            else:
                return ast.Call(func=ast.Attribute(
                    ast.Name(mangle('numpy'), ast.Load(), None, None), 'array',
                    ast.Load()),
                                args=[
                                    to_ast(totuple(value.tolist())),
                                    dtype_to_ast(value.dtype.name)
                                ],
                                keywords=[])
        else:
            raise ConversionError()
    else:
        raise ToNotEval()
    def visit_AnyComp(self, node, comp_type, *path):
        self.update = True
        node.elt = self.visit(node.elt)
        name = "{0}_comprehension{1}".format(comp_type, self.count)
        self.count += 1
        args = self.gather(ImportedIds, node)
        self.count_iter = 0

        starget = "__target"
        body = reduce(self.nest_reducer,
                      reversed(node.generators),
                      ast.Expr(
                          ast.Call(
                              reduce(lambda x, y: ast.Attribute(x, y,
                                                                ast.Load()),
                                     path[1:],
                                     ast.Name(path[0], ast.Load(),
                                              None, None)),
                              [ast.Name(starget, ast.Load(), None, None),
                               node.elt],
                              [],
                              )
                          )
                      )
        # add extra metadata to this node
        metadata.add(body, metadata.Comprehension(starget))
        init = ast.Assign(
            [ast.Name(starget, ast.Store(), None, None)],
            ast.Call(
                ast.Attribute(
                    ast.Name('builtins', ast.Load(), None, None),
                    comp_type,
                    ast.Load()
                    ),
                [], [],)
            )
        result = ast.Return(ast.Name(starget, ast.Load(), None, None))
        sargs = [ast.Name(arg, ast.Param(), None, None) for arg in args]
        fd = ast.FunctionDef(name,
                             ast.arguments(sargs, [], None, [], [], None, []),
                             [init, body, result],
                             [], None, None)
        metadata.add(fd, metadata.Local())
        self.ctx.module.body.append(fd)
        return ast.Call(
            ast.Name(name, ast.Load(), None, None),
            [ast.Name(arg.id, ast.Load(), None, None) for arg in sargs],
            [],
            )  # no sharing !
Exemple #17
0
    def can_use_c_for(self, node):
        """
        Check if a for loop can use classic C syntax.

        To use C syntax:
            - target should not be assign in the loop
            - range should be use as iterator
            - order have to be known at compile time
        """
        assert isinstance(node.target, ast.Name)
        pattern_range = ast.Call(func=ast.Attribute(value=ast.Name(
            'builtins', ast.Load(), None, None),
                                                    attr='range',
                                                    ctx=ast.Load()),
                                 args=AST_any(),
                                 keywords=[])
        is_assigned = set()
        for stmt in node.body:
            is_assigned.update({n.id for n in self.gather(IsAssigned, stmt)})

        nodes = ASTMatcher(pattern_range).search(node.iter)
        if node.iter not in nodes or node.target.id in is_assigned:
            return False

        args = node.iter.args
        if len(args) < 3:
            return True
        if isnum(args[2]):
            return True
        return False
Exemple #18
0
    def visit_Call(self, node):
        # try to get all aliases of the function, if possible
        # else use [] as a fallback
        func_aliases = self.aliases[node.func]
        # expand argument if any
        func_aliases = reduce(
            # all funcs
            lambda x, y: x + (list(self.node_to_functioneffect.keys())
                              if isinstance(y, ast.Name) else [y]),
            func_aliases,
            list())
        for func_alias in func_aliases:
            # special hook for bound functions
            if isinstance(func_alias, ast.Call):
                fake_call = ast.Call(func_alias.args[0],
                                     func_alias.args[1:], [])
                self.visit(fake_call)
                continue

            # conservative choice
            if func_alias not in self.node_to_functioneffect:
                func_alias = intrinsic.UnboundValue

            func_alias = self.node_to_functioneffect[func_alias]
            self.result.add_edge(self.current_function, func_alias)
        self.generic_visit(node)
Exemple #19
0
    def can_use_c_for(self, node):
        """
        Check if a for loop can use classic C syntax.

        To use C syntax:
            - target should not be assign in the loop
            - xrange should be use as iterator
            - order have to be known at compile time
        """
        assert isinstance(node.target, ast.Name)
        pattern = ast.Call(func=ast.Attribute(value=ast.Name(id='__builtin__',
                                                             ctx=ast.Load(),
                                                             annotation=None),
                                              attr='xrange',
                                              ctx=ast.Load()),
                           args=AST_any(),
                           keywords=[])
        is_assigned = {node.target.id: False}
        [
            is_assigned.update(self.passmanager.gather(IsAssigned, stmt))
            for stmt in node.body
        ]

        if (node.iter not in ASTMatcher(pattern).search(node.iter)
                or is_assigned[node.target.id]):
            return False

        args = node.iter.args
        if len(args) < 3:
            return True
        if isinstance(args[2], ast.Num):
            return True
        return False
Exemple #20
0
def create_while_node(condition_name, body_name, loop_var_names):
    while_args = []
    while_args.append(
        gast.Name(id=condition_name,
                  ctx=gast.Param(),
                  annotation=None,
                  type_comment=None))
    while_args.append(
        gast.Name(id=body_name,
                  ctx=gast.Param(),
                  annotation=None,
                  type_comment=None))
    assign_targets = [
        gast.Name(id=var_name,
                  ctx=gast.Param(),
                  annotation=None,
                  type_comment=None) for var_name in loop_var_names
    ]
    while_args.append(gast.List(elts=assign_targets, ctx=gast.Param()))

    while_func_id = gast.parse('fluid.layers.while_loop').body[0].value
    while_node = gast.Call(func=while_func_id, args=while_args, keywords=[])
    assign_node = gast.Assign(
        targets=[gast.Tuple(elts=assign_targets, ctx=gast.Store())],
        value=while_node)
    return assign_node
Exemple #21
0
    def can_use_c_for(self, node):
        """
        Check if a for loop can use classic C syntax.

        To use C syntax:
            - target should not be assign in the loop
            - xrange should be use as iterator
            - order have to be known at compile time
        """
        assert isinstance(node.target, ast.Name)
        if sys.version_info.major == 3:
            range_name = 'range'
        else:
            range_name = 'xrange'
        pattern_range = ast.Call(func=ast.Attribute(value=ast.Name(
            id='__builtin__', ctx=ast.Load(), annotation=None),
                                                    attr=range_name,
                                                    ctx=ast.Load()),
                                 args=AST_any(),
                                 keywords=[])
        is_assigned = set()
        for stmt in node.body:
            is_assigned.update(self.gather(IsAssigned, stmt))

        nodes = ASTMatcher(pattern_range).search(node.iter)
        if node.iter not in nodes or node.target.id in is_assigned:
            return False

        args = node.iter.args
        if len(args) < 3:
            return True
        if isinstance(args[2], ast.Num):
            return True
        return False
 def visit_Attribute(self, node):
     node = self.generic_visit(node)
     # storing in an attribute -> not a getattr
     if not isinstance(node.ctx, ast.Load):
         return node
     # method name -> not a getattr
     elif node.attr in methods:
         return node
     # imported module -> not a getattr
     elif (isinstance(node.value, ast.Name)
           and node.value.id in self.imports):
         module_id = self.imports[node.value.id]
         if node.attr not in MODULES[self.renamer(module_id, MODULES)[1]]:
             msg = ("`" + node.attr + "' is not a member of " + module_id +
                    " or Pythran does not support it")
             raise PythranSyntaxError(msg, node)
         node.value.id = module_id  # patch module aliasing
         self.update = True
         return node
     # not listed as attributed -> not a getattr
     elif node.attr not in attributes:
         return node
     # A getattr !
     else:
         self.update = True
         return ast.Call(
             ast.Attribute(ast.Name('__builtin__', ast.Load(), None),
                           'getattr', ast.Load()),
             [node.value, ast.Str(node.attr)], [])
 def visit_UnaryOp(self, node):
   node = self.generic_visit(node)
   if isinstance(node.op, gast.Not):
     tf_function = parser.parse_str(self.op_mapping[type(
         node.op)]).body[0].value
     node = gast.Call(func=tf_function, args=[node.operand], keywords=[])
   return node
 def visit_Attribute(self, node):
     node = self.generic_visit(node)
     # method name -> not a getattr
     if node.attr in methods:
         return node
     # imported module -> not a getattr
     elif (isinstance(node.value, ast.Name)
           and node.value.id in self.imports):
         module_id = self.imports[node.value.id]
         if node.attr not in MODULES[self.renamer(module_id, MODULES)[1]]:
             msg = ("`" + node.attr + "' is not a member of " + module_id +
                    " or Pythran does not support it")
             raise PythranSyntaxError(msg, node)
         node.value.id = module_id  # patch module aliasing
         self.update = True
         return node
     # not listed as attributed -> not a getattr
     elif node.attr not in attributes:
         return node
     # A getattr !
     else:
         self.update = True
         call = ast.Call(
             ast.Attribute(ast.Name('builtins', ast.Load(), None, None),
                           'getattr', ast.Load()),
             [node.value, ast.Constant(node.attr, None)], [])
         if isinstance(node.ctx, ast.Store):
             # the only situation where this arises is for real/imag of
             # a ndarray. As a call is not valid for a store, add a slice
             # to ends up with a valid lhs
             assert node.attr in ('real', 'imag'), "only store to imag/real"
             return ast.Subscript(call, ast.Slice(None, None, None),
                                  node.ctx)
         else:
             return call
Exemple #25
0
def size_container_folding(value):
    """
    Convert value to ast expression if size is not too big.

    Converter for sized container.
    """
    if len(value) < MAX_LEN:
        if isinstance(value, list):
            return ast.List([to_ast(elt) for elt in value], ast.Load())
        elif isinstance(value, tuple):
            return ast.Tuple([to_ast(elt) for elt in value], ast.Load())
        elif isinstance(value, set):
            return ast.Set([to_ast(elt) for elt in value])
        elif isinstance(value, dict):
            keys = [to_ast(elt) for elt in value.keys()]
            values = [to_ast(elt) for elt in value.values()]
            return ast.Dict(keys, values)
        elif isinstance(value, numpy.ndarray):
            return ast.Call(func=ast.Attribute(
                ast.Name(mangle('numpy'), ast.Load(), None), 'array',
                ast.Load()),
                            args=[to_ast(value.tolist())],
                            keywords=[])
        else:
            raise ConversionError()
    else:
        raise ToNotEval()
    def visit_FunctionDef(self, node):
        self.update = True
        if MODULES['functools'] not in self.global_declarations.values():
            import_ = ast.Import([ast.alias('functools', mangle('functools'))])
            self.ctx.module.body.insert(0, import_)
            functools_module = MODULES['functools']
            self.global_declarations[mangle('functools')] = functools_module

        self.ctx.module.body.append(node)

        former_name = node.name
        seed = 0
        new_name = "pythran_{}{}"

        while new_name.format(former_name, seed) in self.identifiers:
            seed += 1

        new_name = new_name.format(former_name, seed)
        self.identifiers.add(new_name)

        ii = self.gather(ImportedIds, node)
        binded_args = [
            ast.Name(iin, ast.Load(), None, None) for iin in sorted(ii)
        ]
        node.args.args = (
            [ast.Name(iin, ast.Param(), None, None)
             for iin in sorted(ii)] + node.args.args)

        metadata.add(node, metadata.Local())

        class Renamer(ast.NodeTransformer):
            def visit_Call(self, node):
                self.generic_visit(node)
                if (isinstance(node.func, ast.Name)
                        and node.func.id == former_name):
                    node.func.id = new_name
                    node.args = ([
                        ast.Name(iin, ast.Load(), None, None)
                        for iin in sorted(ii)
                    ] + node.args)
                return node

        Renamer().visit(node)

        node.name = new_name
        self.global_declarations[node.name] = node
        proxy_call = ast.Name(new_name, ast.Load(), None, None)

        new_node = ast.Assign([ast.Name(former_name, ast.Store(), None, None)],
                              ast.Call(
                                  ast.Attribute(
                                      ast.Name(mangle('functools'), ast.Load(),
                                               None, None), "partial",
                                      ast.Load()),
                                  [proxy_call] + binded_args,
                                  [],
                              ))

        self.generic_visit(node)
        return new_node
Exemple #27
0
        def visit_Call(self, node):
            if sys.version_info.minor < 5:
                if node.starargs:
                    star = gast.Starred(self._visit(node.starargs),
                                        gast.Load())
                    gast.copy_location(star, node)
                    starred = [star]
                else:
                    starred = []

                if node.kwargs:
                    kw = gast.keyword(None, self._visit(node.kwargs))
                    gast.copy_location(kw, node.kwargs)
                    kwargs = [kw]
                else:
                    kwargs = []
            else:
                starred = kwargs = []

            new_node = gast.Call(
                self._visit(node.func),
                self._visit(node.args) + starred,
                self._visit(node.keywords) + kwargs,
            )
            gast.copy_location(new_node, node)
            return new_node
    def visit_ListComp(self, node):
        def makeattr(*args):
            r = ast.Attribute(value=ast.Name(id='builtins',
                                             ctx=ast.Load(),
                                             annotation=None,
                                             type_comment=None),
                              attr='map',
                              ctx=ast.Load())
            r = ast.Call(r, list(args), [])
            r = ast.Call(
                ast.Attribute(ast.Name('builtins', ast.Load(), None, None),
                              'list', ast.Load()), [r], [])
            return r

        if isinstance(node.elt, ast.Constant) and len(node.generators) == 1:
            gen = node.generators[0]
            if not gen.ifs and isinstance(gen.iter, ast.Call):
                try:
                    path = attr_to_path(gen.iter.func)[1]
                    range_path = 'pythonic', 'builtins', 'functor', 'range'
                    if path == range_path and len(gen.iter.args) == 1:
                        self.update = True
                        return ast.BinOp(
                            ast.List([node.elt], ast.Load()), ast.Mult(),
                            ast.Call(path_to_attr(('builtins', 'len')),
                                     [gen.iter], []))
                except TypeError:
                    pass

        return self.visitComp(node, makeattr)
Exemple #29
0
 def trivialize_slice(self, node):
     if isinstance(node, gast.Slice):
         name = self.namer.name(node)
         target = gast.Name(id=name, ctx=gast.Store(), annotation=None)
         stmt = gast.Assign(targets=[target], value=None)
         self.prepend(stmt)
         stmt.value = gast.Call(
             func=gast.Name(id='slice', ctx=gast.Load(), annotation=None),
             args=[
                 self.trivialize(arg) if arg else gast.Name(
                     id='None', ctx=gast.Load(), annotation=None)
                 for arg in [node.lower, node.upper, node.step]
             ],
             keywords=[])
         return gast.Name(id=name, ctx=gast.Load(), annotation=None)
     elif isinstance(node, gast.ExtSlice):
         name = self.namer.name(node)
         target = gast.Name(id=name, ctx=gast.Store(), annotation=None)
         stmt = gast.Assign(targets=[target], value=None)
         self.prepend(stmt)
         dim_names = [self.trivialize_slice(s).id for s in node.dims]
         stmt.value = gast.Tuple(elts=[
             gast.Name(id=n, ctx=gast.Load(), annotation=None)
             for n in dim_names
         ],
                                 ctx=gast.Load())
         return gast.Name(id=name, ctx=gast.Load(), annotation=None)
     elif isinstance(node, gast.Index):
         return self.trivialize(node.value)
     else:
         raise ValueError(node)
Exemple #30
0
    def visit_Lambda(self, node):
        if MODULES['functools'] not in self.global_declarations.values():
            import_ = ast.Import([ast.alias('functools', mangle('functools'))])
            self.imports.append(import_)
            functools_module = MODULES['functools']
            self.global_declarations[mangle('functools')] = functools_module

        self.generic_visit(node)
        forged_name = "{0}_lambda{1}".format(self.prefix,
                                             len(self.lambda_functions))

        ii = self.passmanager.gather(ImportedIds, node, self.ctx)
        ii.difference_update(self.lambda_functions)  # remove current lambdas

        binded_args = [ast.Name(iin, ast.Load(), None) for iin in sorted(ii)]
        node.args.args = (
            [ast.Name(iin, ast.Param(), None)
             for iin in sorted(ii)] + node.args.args)
        forged_fdef = ast.FunctionDef(forged_name, copy(node.args),
                                      [ast.Return(node.body)], [], None)
        self.lambda_functions.append(forged_fdef)
        self.global_declarations[forged_name] = forged_fdef
        proxy_call = ast.Name(forged_name, ast.Load(), None)
        if binded_args:
            return ast.Call(
                ast.Attribute(ast.Name(mangle('functools'), ast.Load(), None),
                              "partial", ast.Load()),
                [proxy_call] + binded_args, [])
        else:
            return proxy_call