Beispiel #1
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=[])
Beispiel #2
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=[])
Beispiel #3
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=[])
Beispiel #4
0
def dtype_to_ast(name):
    if name in ('bool', ):
        return ast.Attribute(ast.Name('__builtin__', ast.Load(), None, None),
                             name, ast.Load())
    else:
        return ast.Attribute(ast.Name(mangle('numpy'), ast.Load(), None, None),
                             name, ast.Load())
Beispiel #5
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()),
                    ast.Attribute(ast.Name(mangle('numpy'), ast.Load(), None),
                                  value.dtype.name, ast.Load())
                ],
                keywords=[])
        else:
            raise ConversionError()
    else:
        raise ToNotEval()
Beispiel #6
0
def to_ast(value):
    """
    Turn a value into ast expression.

    >>> a = 1
    >>> print(ast.dump(to_ast(a)))
    Num(n=1)
    >>> a = [1, 2, 3]
    >>> print(ast.dump(to_ast(a)))
    List(elts=[Num(n=1), Num(n=2), Num(n=3)], ctx=Load())
    """

    if any(value is t for t in (bool, int, float)):
        iinfo = np.iinfo(int)
        if isinstance(value, int) and not (iinfo.min <= value <= iinfo.max):
            from pythran.syntax import PythranSyntaxError
            raise PythranSyntaxError("constant folding results in big int")
        return builtin_folding(value)
    elif isinstance(value, np.generic):
        return to_ast(value.item())
    elif isinstance(value, (numbers.Number, str, bool, type(None))):
        return ast.Constant(value, None)
    elif isinstance(value, (list, tuple, set, dict, np.ndarray)):
        return size_container_folding(value)
    elif hasattr(value, "__module__") and value.__module__ == "builtins":
        # TODO Can be done the same way for others modules
        return builtin_folding(value)
    # only meaningful for python3
    elif isinstance(value, (filter, map, zip)):
        return to_ast(list(value))
    elif isinstance(value, np._globals._NoValueType):
        return ast.Attribute(
            ast.Attribute(ast.Name('numpy', ast.Load(), None, None),
                          '_globals', ast.Load()), '_NoValueType', ast.Load())
    raise ToNotEval()
Beispiel #7
0
def to_static_ast(node, class_node):
    assert isinstance(node, gast.Call)
    assert isinstance(class_node, gast.Call)
    static_api = to_static_api(class_node.func.attr)

    node.func = gast.Attribute(attr=static_api,
                               ctx=gast.Load(),
                               value=gast.Attribute(attr='layers',
                                                    ctx=gast.Load(),
                                                    value=gast.Name(
                                                        ctx=gast.Load(),
                                                        id='fluid',
                                                        annotation=None,
                                                        type_comment=None)))

    update_args_of_func(node, class_node, 'forward')

    node.args.extend(class_node.args)
    node.keywords.extend(class_node.keywords)
    _add_keywords_to(node, class_node.func.attr)
    _delete_keywords_from(node)

    gast.fix_missing_locations(node)

    return node
Beispiel #8
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=[])
Beispiel #9
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=[])
Beispiel #10
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
Beispiel #11
0
    def visit_Lambda(self, node):
        op = issimpleoperator(node)
        if op is not None:
            if mangle('operator') not in self.global_declarations:
                import_ = ast.Import(
                    [ast.alias('operator', mangle('operator'))])
                self.imports.append(import_)
                operator_module = MODULES['operator']
                self.global_declarations[mangle('operator')] = operator_module
            return ast.Attribute(
                ast.Name(mangle('operator'), ast.Load(), None, None), op,
                ast.Load())

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

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

        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)
        for patternname, pattern in self.patterns.items():
            if issamelambda(pattern, node):
                proxy_call = ast.Name(patternname, ast.Load(), None, None)
                break
        else:
            duc = ExtendedDefUseChains()
            nodepattern = deepcopy(node)
            duc.visit(ast.Module([ast.Expr(nodepattern)], []))
            self.patterns[forged_name] = nodepattern, duc

            forged_fdef = ast.FunctionDef(forged_name, copy(node.args),
                                          [ast.Return(node.body)], [], None,
                                          None)
            metadata.add(forged_fdef, metadata.Local())
            self.lambda_functions.append(forged_fdef)
            self.global_declarations[forged_name] = forged_fdef
            proxy_call = ast.Name(forged_name, ast.Load(), None, None)

        if binded_args:
            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

            return ast.Call(
                ast.Attribute(
                    ast.Name(mangle('functools'), ast.Load(), None, None),
                    "partial", ast.Load()), [proxy_call] + binded_args, [])
        else:
            return proxy_call
Beispiel #12
0
    def handle_keywords(self, func, node, offset=0):
        '''
        Gather keywords to positional argument information

        Assumes the named parameter exist, raises a KeyError otherwise
        '''
        func_argument_names = {}
        for i, arg in enumerate(func.args.args[offset:]):
            assert isinstance(arg, ast.Name)
            func_argument_names[arg.id] = i

        func_argument_kwonly_names = {}
        for i, arg in enumerate(func.args.kwonlyargs):
            assert isinstance(arg, ast.Name)
            func_argument_kwonly_names[arg.id] = i

        nargs = len(func.args.args) - offset
        defaults = func.args.defaults
        keywords = {func_argument_names[kw.arg]: kw.value
                    for kw in node.keywords
                    if kw.arg not in func_argument_kwonly_names}

        keywords_only = []
        nb_kw = len(node.keywords)
        for i, kw in enumerate(list(reversed(node.keywords))):
            if kw.arg in func_argument_kwonly_names:
                keywords_only.append((func_argument_kwonly_names[kw.arg],
                                      kw.value))
                node.keywords.pop(nb_kw - i - 1)

        keywords_only = [v for _, v in sorted(keywords_only)]

        extra_keyword_offset = max(keywords.keys()) if keywords else 0
        node.args.extend([None] * (1 + extra_keyword_offset - len(node.args)))

        replacements = {}
        for index, arg in enumerate(node.args):
            if arg is None:
                if index in keywords:
                    replacements[index] = deepcopy(keywords[index])
                else:  # must be a default value
                    replacements[index] = deepcopy(defaults[index - nargs])

        if not keywords_only:
            return replacements

        node.args.append(ast.Call(
            ast.Attribute(
                ast.Attribute(
                    ast.Name("builtins", ast.Load(), None, None),
                    "pythran",
                    ast.Load()),
                "kwonly",
                ast.Load()),
            [], [])
        )
        node.args.extend(keywords_only)

        return replacements
Beispiel #13
0
 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=[])
Beispiel #14
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
Beispiel #16
0
 def sub():
     return ast.Call(func=ast.Attribute(value=ast.Attribute(value=ast.Name(
         id='builtins', ctx=ast.Load(), annotation=None, type_comment=None),
                                                            attr="pythran",
                                                            ctx=ast.Load()),
                                        attr="abssqr",
                                        ctx=ast.Load()),
                     args=[Placeholder(0)],
                     keywords=[])
Beispiel #17
0
 def sub():
     return ast.Call(
         func=ast.Attribute(
             ast.Attribute(ast.Name('__builtin__', ast.Load(), None, None),
                           'str', ast.Load()), 'join', ast.Load()),
         args=[
             ast.Constant(Placeholder(1), None),
             ast.Tuple([Placeholder(0), Placeholder(2)], ast.Load())
         ],
         keywords=[])
 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
Beispiel #19
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
Beispiel #20
0
    def visit_Return(self, node):
        if node is self.guard:
            holder = "StaticIfNoReturn"
        else:
            holder = "StaticIfReturn"

        return ast.Return(
            ast.Call(
                ast.Attribute(
                    ast.Attribute(ast.Name("__builtin__", ast.Load(), None),
                                  "pythran", ast.Load()), holder, ast.Load()),
                [node.value], []))
Beispiel #21
0
    def visit_Return(self, node):
        if node is self.guard:
            holder = "StaticIfNoReturn"
        else:
            holder = "StaticIfReturn"

        value = node.value

        return ast.Return(
            ast.Call(
                ast.Attribute(
                    ast.Attribute(ast.Name("builtins", ast.Load(), None, None),
                                  "pythran", ast.Load()), holder, ast.Load()),
                [value] if value else [ast.Constant(None, None)], []))
Beispiel #22
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()
Beispiel #23
0
    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 !
Beispiel #24
0
    def visit_Compare(self, node):
        self.generic_visit(node)
        noned_var, negated = self.match_is_none(node)
        if noned_var is None:
            return node
        call = ast.Call(
            ast.Attribute(
                ast.Attribute(ast.Name('__builtin__', ast.Load(), None),
                              'pythran', ast.Load()), 'is_none', ast.Load()),
            [noned_var], [])

        if negated:
            return ast.UnaryOp(ast.Not(), call)
        else:
            return call
Beispiel #25
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
 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_BinOp(self, node):
     # replace "str" % (...) by __builtin__.str.__mod__(...)
     # the reason why we do this is that % formatting is handled by
     # a third party library that's relatively costly to load, so using a
     # function name instead of an operator overload makes it possible to
     # load it only when needed. The drawback is that % formatting is no
     # longer supported when lhs is not a literal
     self.generic_visit(node)
     if isinstance(node.op, ast.Mod) and isinstance(node.left, ast.Str):
         self.update = True
         return ast.Call(
             ast.Attribute(
                 ast.Attribute(ast.Name('__builtin__', ast.Load(), None),
                               'str', ast.Load()), '__mod__', ast.Load()),
             [node.left, node.right], [])
     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
Beispiel #29
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
Beispiel #30
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