Esempio n. 1
0
 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
    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