class_docstr: Turns built in method calls into function calls.
  
  >>> import gast as ast
  >>> from pythran import passmanager, backend
  >>> node = ast.parse("[].append(12)")
  >>> pm = passmanager.PassManager("test")
  >>> _, node = pm.apply(NormalizeMethodCalls, node)
  >>> print(pm.dump(backend.Python, node))
  builtins.list.append([], 12)
class_docstr_tok: ["Turns","built","in","method","calls","into","function","calls",".",">",">",">","import","gast","as","ast",">",">",">","from","pythran","import","passmanager",",","backend",">",">",">","node","=","ast.parse","(","``","[","]",".append","(","12",")","''",")",">",">",">","pm","=","passmanager.PassManager","(","``","test","''",")",">",">",">","_",",","node","=","pm.apply","(","NormalizeMethodCalls",",","node",")",">",">",">","print","(","pm.dump","(","backend.Python",",","node",")",")","builtins.list.append","(","[","]",",","12",")"]
code: 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]))
              self.to_import.add(mangle("functools"))
              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
  
imports: from pythran.analyses import Globals, Ancestors
  from pythran.passmanager import Transformation
  from pythran.syntax import PythranSyntaxError
  from pythran.tables import attributes, functions, methods, MODULES
  from pythran.tables import duplicated_methods
  from pythran.conversion import mangle, demangle
  from pythran.utils import isstr
  import gast
  from functools import reduce
label_desc: Use image node_id 10 for calling the NormalizeMethodCalls obj's underlying member method code with example usage: obj.visit_Attribute(node) and returns: z, node, node, node, node, ast, call