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",")"]
docstr: Transform call site to have normal function call.
  
  Examples
  --------
  For methods:
  >> a = [1, 2, 3]
  
  >> a.append(1)
  
  Becomes
  
  >> __list__.append(a, 1)
  
  
  For functions:
  >> builtins.dict.fromkeys([1, 2, 3])
  
  Becomes
  
  >> builtins.__dict__.fromkeys([1, 2, 3])
docstr_tok: ["Transform","call","site","to","have","normal","function","call",".","Examples","--","--","--","--","For","methods",":",">",">","a","=","[","1",",","2",",","3","]",">",">","a.append","(","1",")","Becomes",">",">","__list__.append","(","a",",","1",")","For","functions",":",">",">","builtins.dict.fromkeys","(","[","1",",","2",",","3","]",")","Becomes",">",">","builtins.__dict__.fromkeys","(","[","1",",","2",",","3","]",")"]
code: def visit_Call(self, node):
      """
      Transform call site to have normal function call.
  
      Examples
      --------
      For methods:
      >> a = [1, 2, 3]
  
      >> a.append(1)
  
      Becomes
  
      >> __list__.append(a, 1)
  
  
      For functions:
      >> builtins.dict.fromkeys([1, 2, 3])
  
      Becomes
  
      >> builtins.__dict__.fromkeys([1, 2, 3])
      """
      node = self.generic_visit(node)
  
      # Only attributes function can be Pythonic and should be normalized
      if isinstance(node.func, ast.Attribute):
          if node.func.attr in methods:
              # Check object targeted by methods
              if self.baseobj(node.func) is not None:
                  self.update = True
                  # As it was a methods call, push targeted object as first
                  # arguments and add correct module prefix
                  node.args.insert(0, node.func.value)
                  mod = methods[node.func.attr][0]
                  # Submodules import full module
                  self.to_import.add(mangle(mod[0]))
                  node.func = self.attr_to_func(node.func)
              # else methods have been called using function syntax
  
          ismethod = node.func.attr in methods
          isfunction = node.func.attr in functions
          if ismethod or isfunction:  # i.e. if it's callable
              if not ismethod and self.baseobj(node.func.value):
                  raise PythranSyntaxError(
                      "'{}' called as a method while it's a function".format(
                          node.func.attr
                      ),
                      node,
                  )
  
              # Now, methods and function have both function syntax
              def rec(path, cur_module):
                  """
                  Recursively rename path content looking in matching module.
  
                  Prefers __module__ to module if it exists.
                  This recursion is done as modules are visited top->bottom
                  while attributes have to be visited bottom->top.
                  """
                  err = "Function path is chained attributes and name"
                  assert isinstance(
                      path, (ast.Name, ast.Attribute)
                  ), err
                  if isinstance(path, ast.Attribute):
                      new_node, cur_module = rec(path.value, cur_module)
                      new_id, mname = self.renamer(
                          path.attr, cur_module
                      )
                      return (
                          ast.Attribute(new_node, new_id, ast.Load()),
                          cur_module[mname],
                      )
                  else:
                      new_id, mname = self.renamer(path.id, cur_module)
                      return (
                          ast.Name(new_id, ast.Load(), None, None),
                          cur_module[mname],
                      )
  
              # Rename module path to avoid naming issue.
              node.func.value, _ = rec(node.func.value, MODULES)
              self.update = True
          self.keyword_based_disambiguification(node)
  
      return node
  
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 12 for calling the NormalizeMethodCalls obj's underlying member method code with example usage: obj.visit_Call(node) and returns: node, ast,  cur_module, ast,  cur_module