parameters: (compare_array, module, is_list)
return_statement: return res
docstring: Checks if a `pr.Array` has "add" statements:
      >>> a = [""]
      >>> a.append(1)
docstring_summary: Checks if a `pr.Array` has "add" statements:
      >>> a = [""]
      >>> a.append(1)
docstring_tokens: Checks if a pr . Array has add statements : >>> a = [ ] >>> a . append ( 1 )
function: def _check_array_additions(compare_array, module, is_list):
      """
      Checks if a `pr.Array` has "add" statements:
      >>> a = [""]
      >>> a.append(1)
      """
      if not settings.dynamic_array_additions or module.is_builtin():
          return []
  
      def check_calls(calls, add_name):
          """
          Calls are processed here. The part before the call is searched and
          compared with the original Array.
          """
          result = []
          for c in calls:
              call_path = list(c.generate_call_path())
              separate_index = call_path.index(add_name)
              if add_name == call_path[-1] or separate_index == 0:
                  # this means that there is no execution -> [].append
                  # or the keyword is at the start -> append()
                  continue
              backtrack_path = iter(call_path[:separate_index])
  
              position = c.start_pos
              scope = c.get_parent_until(pr.IsScope)
  
              found = evaluate.follow_call_path(backtrack_path, scope, position)
              if not compare_array in found:
                  continue
  
              params = call_path[separate_index + 1]
              if not params.values:
                  continue  # no params: just ignore it
              if add_name in ['append', 'add']:
                  for param in params:
                      result += evaluate.follow_statement(param)
              elif add_name in ['insert']:
                  try:
                      second_param = params[1]
                  except IndexError:
                      continue
                  else:
                      result += evaluate.follow_statement(second_param)
              elif add_name in ['extend', 'update']:
                  for param in params:
                      iterators = evaluate.follow_statement(param)
                  result += evaluate.get_iterator_types(iterators)
          return result
  
      def get_execution_parent(element, *stop_classes):
          """ Used to get an Instance/Execution parent """
          if isinstance(element, er.Array):
              stmt = element._array.parent
          else:
              # is an Instance with an ArrayInstance inside
              stmt = element.var_args[0].var_args.parent
          if isinstance(stmt, er.InstanceElement):
              stop_classes = list(stop_classes) + [er.Function]
          return stmt.get_parent_until(stop_classes)
  
      temp_param_add = settings.dynamic_params_for_other_modules
      settings.dynamic_params_for_other_modules = False
  
      search_names = ['append', 'extend', 'insert'] if is_list else \
          ['add', 'update']
      comp_arr_parent = get_execution_parent(compare_array, er.Execution)
  
      possible_stmts = []
      res = []
      for n in search_names:
          try:
              possible_stmts += module.used_names[n]
          except KeyError:
              continue
          for stmt in possible_stmts:
              # Check if the original scope is an execution. If it is, one
              # can search for the same statement, that is in the module
              # dict. Executions are somewhat special in jedi, since they
              # literally copy the contents of a function.
              if isinstance(comp_arr_parent, er.Execution):
                  stmt = comp_arr_parent. \
                      get_statement_for_position(stmt.start_pos)
                  if stmt is None:
                      continue
              # InstanceElements are special, because they don't get copied,
              # but have this wrapper around them.
              if isinstance(comp_arr_parent, er.InstanceElement):
                  stmt = er.InstanceElement(comp_arr_parent.instance, stmt)
  
              if evaluate.follow_statement.push_stmt(stmt):
                  # check recursion
                  continue
              res += check_calls(_scan_statement(stmt, n), n)
              evaluate.follow_statement.pop_stmt()
      # reset settings
      settings.dynamic_params_for_other_modules = temp_param_add
      return res
function_tokens: def _check_array_additions ( compare_array , module , is_list ) : if not settings . dynamic_array_additions or module . is_builtin ( ) : return [ ] def check_calls ( calls , add_name ) : """
          Calls are processed here. The part before the call is searched and
          compared with the original Array.
          """ result = [ ] for c in calls : call_path = list ( c . generate_call_path ( ) ) separate_index = call_path . index ( add_name ) if add_name == call_path [ - 1 ] or separate_index == 0 : # this means that there is no execution -> [].append # or the keyword is at the start -> append() continue backtrack_path = iter ( call_path [ : separate_index ] ) position = c . start_pos scope = c . get_parent_until ( pr . IsScope ) found = evaluate . follow_call_path ( backtrack_path , scope , position ) if not compare_array in found : continue params = call_path [ separate_index + 1 ] if not params . values : continue # no params: just ignore it if add_name in [ 'append' , 'add' ] : for param in params : result += evaluate . follow_statement ( param ) elif add_name in [ 'insert' ] : try : second_param = params [ 1 ] except IndexError : continue else : result += evaluate . follow_statement ( second_param ) elif add_name in [ 'extend' , 'update' ] : for param in params : iterators = evaluate . follow_statement ( param ) result += evaluate . get_iterator_types ( iterators ) return result def get_execution_parent ( element , * stop_classes ) : """ Used to get an Instance/Execution parent """ if isinstance ( element , er . Array ) : stmt = element . _array . parent else : # is an Instance with an ArrayInstance inside stmt = element . var_args [ 0 ] . var_args . parent if isinstance ( stmt , er . InstanceElement ) : stop_classes = list ( stop_classes ) + [ er . Function ] return stmt . get_parent_until ( stop_classes ) temp_param_add = settings . dynamic_params_for_other_modules settings . dynamic_params_for_other_modules = False search_names = [ 'append' , 'extend' , 'insert' ] if is_list else [ 'add' , 'update' ] comp_arr_parent = get_execution_parent ( compare_array , er . Execution ) possible_stmts = [ ] res = [ ] for n in search_names : try : possible_stmts += module . used_names [ n ] except KeyError : continue for stmt in possible_stmts : # Check if the original scope is an execution. If it is, one # can search for the same statement, that is in the module # dict. Executions are somewhat special in jedi, since they # literally copy the contents of a function. if isinstance ( comp_arr_parent , er . Execution ) : stmt = comp_arr_parent . get_statement_for_position ( stmt . start_pos ) if stmt is None : continue # InstanceElements are special, because they don't get copied, # but have this wrapper around them. if isinstance ( comp_arr_parent , er . InstanceElement ) : stmt = er . InstanceElement ( comp_arr_parent . instance , stmt ) if evaluate . follow_statement . push_stmt ( stmt ) : # check recursion continue res += check_calls ( _scan_statement ( stmt , n ) , n ) evaluate . follow_statement . pop_stmt ( ) # reset settings settings . dynamic_params_for_other_modules = temp_param_add return res