parameters: (self)
return_statement: return node
docstring: Tries to map keyword arguments to declared positional arguments.
          Returns self to try a Python call, None to report an error
          or a SimpleCallNode if the mapping succeeds.
docstring_summary: Tries to map keyword arguments to declared positional arguments.
          Returns self to try a Python call, None to report an error
          or a SimpleCallNode if the mapping succeeds.
docstring_tokens: Tries to map keyword arguments to declared positional arguments . Returns self to try a Python call None to report an error or a SimpleCallNode if the mapping succeeds .
function: def map_to_simple_call_node(self):
          """
          Tries to map keyword arguments to declared positional arguments.
          Returns self to try a Python call, None to report an error
          or a SimpleCallNode if the mapping succeeds.
          """
          if not isinstance(self.positional_args, TupleNode):
              # has starred argument
              return self
          if not self.keyword_args.is_dict_literal:
              # keywords come from arbitrary expression => nothing to do here
              return self
          function = self.function
          entry = getattr(function, 'entry', None)
          if not entry:
              return self
          function_type = entry.type
          if function_type.is_ptr:
              function_type = function_type.base_type
          if not function_type.is_cfunction:
              return self
  
          pos_args = self.positional_args.args
          kwargs = self.keyword_args
          declared_args = function_type.args
          if entry.is_cmethod:
              declared_args = declared_args[1:] # skip 'self'
  
          if len(pos_args) > len(declared_args):
              error(self.pos, "function call got too many positional arguments, "
                              "expected %d, got %s" % (len(declared_args),
                                                       len(pos_args)))
              return None
  
          matched_args = set([ arg.name for arg in declared_args[:len(pos_args)]
                               if arg.name ])
          unmatched_args = declared_args[len(pos_args):]
          matched_kwargs_count = 0
          args = list(pos_args)
  
          # check for duplicate keywords
          seen = set(matched_args)
          has_errors = False
          for arg in kwargs.key_value_pairs:
              name = arg.key.value
              if name in seen:
                  error(arg.pos, "argument '%s' passed twice" % name)
                  has_errors = True
                  # continue to report more errors if there are any
              seen.add(name)
  
          # match keywords that are passed in order
          for decl_arg, arg in zip(unmatched_args, kwargs.key_value_pairs):
              name = arg.key.value
              if decl_arg.name == name:
                  matched_args.add(name)
                  matched_kwargs_count += 1
                  args.append(arg.value)
              else:
                  break
  
          # match keyword arguments that are passed out-of-order, but keep
          # the evaluation of non-simple arguments in order by moving them
          # into temps
          from .UtilNodes import EvalWithTempExprNode, LetRefNode
          temps = []
          if len(kwargs.key_value_pairs) > matched_kwargs_count:
              unmatched_args = declared_args[len(args):]
              keywords = dict([ (arg.key.value, (i+len(pos_args), arg))
                                for i, arg in enumerate(kwargs.key_value_pairs) ])
              first_missing_keyword = None
              for decl_arg in unmatched_args:
                  name = decl_arg.name
                  if name not in keywords:
                      # missing keyword argument => either done or error
                      if not first_missing_keyword:
                          first_missing_keyword = name
                      continue
                  elif first_missing_keyword:
                      if entry.as_variable:
                          # we might be able to convert the function to a Python
                          # object, which then allows full calling semantics
                          # with default values in gaps - currently, we only
                          # support optional arguments at the end
                          return self
                      # wasn't the last keyword => gaps are not supported
                      error(self.pos, "C function call is missing "
                                      "argument '%s'" % first_missing_keyword)
                      return None
                  pos, arg = keywords[name]
                  matched_args.add(name)
                  matched_kwargs_count += 1
                  if arg.value.is_simple():
                      args.append(arg.value)
                  else:
                      temp = LetRefNode(arg.value)
                      assert temp.is_simple()
                      args.append(temp)
                      temps.append((pos, temp))
  
              if temps:
                  # may have to move preceding non-simple args into temps
                  final_args = []
                  new_temps = []
                  first_temp_arg = temps[0][-1]
                  for arg_value in args:
                      if arg_value is first_temp_arg:
                          break  # done
                      if arg_value.is_simple():
                          final_args.append(arg_value)
                      else:
                          temp = LetRefNode(arg_value)
                          new_temps.append(temp)
                          final_args.append(temp)
                  if new_temps:
                      args = final_args
                  temps = new_temps + [ arg for i,arg in sorted(temps) ]
  
          # check for unexpected keywords
          for arg in kwargs.key_value_pairs:
              name = arg.key.value
              if name not in matched_args:
                  has_errors = True
                  error(arg.pos,
                        "C function got unexpected keyword argument '%s'" %
                        name)
  
          if has_errors:
              # error was reported already
              return None
  
          # all keywords mapped to positional arguments
          # if we are missing arguments, SimpleCallNode will figure it out
          node = SimpleCallNode(self.pos, function=function, args=args)
          for temp in temps[::-1]:
              node = EvalWithTempExprNode(temp, node)
          return node
function_tokens: def map_to_simple_call_node ( self ) : if not isinstance ( self . positional_args , TupleNode ) : # has starred argument return self if not self . keyword_args . is_dict_literal : # keywords come from arbitrary expression => nothing to do here return self function = self . function entry = getattr ( function , 'entry' , None ) if not entry : return self function_type = entry . type if function_type . is_ptr : function_type = function_type . base_type if not function_type . is_cfunction : return self pos_args = self . positional_args . args kwargs = self . keyword_args declared_args = function_type . args if entry . is_cmethod : declared_args = declared_args [ 1 : ] # skip 'self' if len ( pos_args ) > len ( declared_args ) : error ( self . pos , "function call got too many positional arguments, " "expected %d, got %s" % ( len ( declared_args ) , len ( pos_args ) ) ) return None matched_args = set ( [ arg . name for arg in declared_args [ : len ( pos_args ) ] if arg . name ] ) unmatched_args = declared_args [ len ( pos_args ) : ] matched_kwargs_count = 0 args = list ( pos_args ) # check for duplicate keywords seen = set ( matched_args ) has_errors = False for arg in kwargs . key_value_pairs : name = arg . key . value if name in seen : error ( arg . pos , "argument '%s' passed twice" % name ) has_errors = True # continue to report more errors if there are any seen . add ( name ) # match keywords that are passed in order for decl_arg , arg in zip ( unmatched_args , kwargs . key_value_pairs ) : name = arg . key . value if decl_arg . name == name : matched_args . add ( name ) matched_kwargs_count += 1 args . append ( arg . value ) else : break # match keyword arguments that are passed out-of-order, but keep # the evaluation of non-simple arguments in order by moving them # into temps from . UtilNodes import EvalWithTempExprNode , LetRefNode temps = [ ] if len ( kwargs . key_value_pairs ) > matched_kwargs_count : unmatched_args = declared_args [ len ( args ) : ] keywords = dict ( [ ( arg . key . value , ( i + len ( pos_args ) , arg ) ) for i , arg in enumerate ( kwargs . key_value_pairs ) ] ) first_missing_keyword = None for decl_arg in unmatched_args : name = decl_arg . name if name not in keywords : # missing keyword argument => either done or error if not first_missing_keyword : first_missing_keyword = name continue elif first_missing_keyword : if entry . as_variable : # we might be able to convert the function to a Python # object, which then allows full calling semantics # with default values in gaps - currently, we only # support optional arguments at the end return self # wasn't the last keyword => gaps are not supported error ( self . pos , "C function call is missing " "argument '%s'" % first_missing_keyword ) return None pos , arg = keywords [ name ] matched_args . add ( name ) matched_kwargs_count += 1 if arg . value . is_simple ( ) : args . append ( arg . value ) else : temp = LetRefNode ( arg . value ) assert temp . is_simple ( ) args . append ( temp ) temps . append ( ( pos , temp ) ) if temps : # may have to move preceding non-simple args into temps final_args = [ ] new_temps = [ ] first_temp_arg = temps [ 0 ] [ - 1 ] for arg_value in args : if arg_value is first_temp_arg : break # done if arg_value . is_simple ( ) : final_args . append ( arg_value ) else : temp = LetRefNode ( arg_value ) new_temps . append ( temp ) final_args . append ( temp ) if new_temps : args = final_args temps = new_temps + [ arg for i , arg in sorted ( temps ) ] # check for unexpected keywords for arg in kwargs . key_value_pairs : name = arg . key . value if name not in matched_args : has_errors = True error ( arg . pos , "C function got unexpected keyword argument '%s'" % name ) if has_errors : # error was reported already return None # all keywords mapped to positional arguments # if we are missing arguments, SimpleCallNode will figure it out node = SimpleCallNode ( self . pos , function = function , args = args ) for temp in temps [ : : - 1 ] : node = EvalWithTempExprNode ( temp , node ) return node