parameters: (param)
return_statement: return result
docstring: This is a dynamic search for params. If you try to complete a type:
      >>> def func(foo):
      >>>     # here is the completion
      >>>     foo
      >>> func(1)
      >>> func("")
  
      It is not known what the type is, because it cannot be guessed with
      recursive madness. Therefore one has to analyse the statements that are
      calling the function, as well as analyzing the incoming params.
docstring_summary: This is a dynamic search for params. If you try to complete a type:
      >>> def func(foo):
      >>>     # here is the completion
      >>>     foo
      >>> func(1)
      >>> func("")
docstring_tokens: This is a dynamic search for params . If you try to complete a type : >>> def func ( foo ) : >>> # here is the completion >>> foo >>> func ( 1 ) >>> func ( )
function: def search_params(param):
      """
      This is a dynamic search for params. If you try to complete a type:
      >>> def func(foo):
      >>>     # here is the completion
      >>>     foo
      >>> func(1)
      >>> func("")
  
      It is not known what the type is, because it cannot be guessed with
      recursive madness. Therefore one has to analyse the statements that are
      calling the function, as well as analyzing the incoming params.
      """
      if not settings.dynamic_params:
          return []
  
      def get_params_for_module(module):
          """
          Returns the values of a param, or an empty array.
          """
          @search_param_memoize
          def get_posibilities(module, func_name):
              try:
                  possible_stmts = module.used_names[func_name]
              except KeyError:
                  return []
  
              for stmt in possible_stmts:
                  if isinstance(stmt, pr.Import):
                      continue
                  calls = _scan_statement(stmt, func_name)
                  for c in calls:
                      # no execution means that params cannot be set
                      call_path = list(c.generate_call_path())
                      pos = c.start_pos
                      scope = stmt.parent
  
                      # this whole stuff is just to not execute certain parts
                      # (speed improvement), basically we could just call
                      # ``follow_call_path`` on the call_path and it would
                      # also work.
                      def listRightIndex(lst, value):
                          return len(lst) - lst[-1::-1].index(value) -1
  
                      # Need to take right index, because there could be a
                      # func usage before.
                      i = listRightIndex(call_path, func_name)
                      first, last = call_path[:i], call_path[i+1:]
                      if not last and not call_path.index(func_name) != i:
                          continue
                      scopes = [scope]
                      if first:
                          scopes = evaluate.follow_call_path(iter(first), scope, pos)
                          pos = None
                      for scope in scopes:
                          s = evaluate.find_name(scope, func_name, position=pos,
                                                 search_global=not first,
                                                 resolve_decorator=False)
  
                          c = [getattr(escope, 'base_func', None) or escope.base
                              for escope in s
                              if escope.isinstance(er.Function, er.Class)
                          ]
                          if compare in c:
                              # only if we have the correct function we execute
                              # it, otherwise just ignore it.
                              evaluate.follow_paths(iter(last), s, scope)
  
              return listener.param_possibilities
  
          result = []
          for params in get_posibilities(module, func_name):
              for p in params:
                  if str(p) == param_name:
                      result += evaluate.follow_statement(p.parent)
          return result
  
      func = param.get_parent_until(pr.Function)
      current_module = param.get_parent_until()
      func_name = str(func.name)
      compare = func
      if func_name == '__init__' and isinstance(func.parent, pr.Class):
          func_name = str(func.parent.name)
          compare = func.parent
  
      # get the param name
      if param.assignment_details:
          # first assignment details, others would be a syntax error
          commands, op = param.assignment_details[0]
      else:
          commands = param.get_commands()
      offset = 1 if commands[0] in ['*', '**'] else 0
      param_name = str(commands[offset].name)
  
      # add the listener
      listener = ParamListener()
      func.listeners.add(listener)
  
      result = []
      # This is like backtracking: Get the first possible result.
      for mod in get_directory_modules_for_name([current_module], func_name):
          result = get_params_for_module(mod)
          if result:
              break
  
      # cleanup: remove the listener; important: should not stick.
      func.listeners.remove(listener)
  
      return result
function_tokens: def search_params ( param ) : if not settings . dynamic_params : return [ ] def get_params_for_module ( module ) : """
          Returns the values of a param, or an empty array.
          """ @ search_param_memoize def get_posibilities ( module , func_name ) : try : possible_stmts = module . used_names [ func_name ] except KeyError : return [ ] for stmt in possible_stmts : if isinstance ( stmt , pr . Import ) : continue calls = _scan_statement ( stmt , func_name ) for c in calls : # no execution means that params cannot be set call_path = list ( c . generate_call_path ( ) ) pos = c . start_pos scope = stmt . parent # this whole stuff is just to not execute certain parts # (speed improvement), basically we could just call # ``follow_call_path`` on the call_path and it would # also work. def listRightIndex ( lst , value ) : return len ( lst ) - lst [ - 1 : : - 1 ] . index ( value ) - 1 # Need to take right index, because there could be a # func usage before. i = listRightIndex ( call_path , func_name ) first , last = call_path [ : i ] , call_path [ i + 1 : ] if not last and not call_path . index ( func_name ) != i : continue scopes = [ scope ] if first : scopes = evaluate . follow_call_path ( iter ( first ) , scope , pos ) pos = None for scope in scopes : s = evaluate . find_name ( scope , func_name , position = pos , search_global = not first , resolve_decorator = False ) c = [ getattr ( escope , 'base_func' , None ) or escope . base for escope in s if escope . isinstance ( er . Function , er . Class ) ] if compare in c : # only if we have the correct function we execute # it, otherwise just ignore it. evaluate . follow_paths ( iter ( last ) , s , scope ) return listener . param_possibilities result = [ ] for params in get_posibilities ( module , func_name ) : for p in params : if str ( p ) == param_name : result += evaluate . follow_statement ( p . parent ) return result func = param . get_parent_until ( pr . Function ) current_module = param . get_parent_until ( ) func_name = str ( func . name ) compare = func if func_name == '__init__' and isinstance ( func . parent , pr . Class ) : func_name = str ( func . parent . name ) compare = func . parent # get the param name if param . assignment_details : # first assignment details, others would be a syntax error commands , op = param . assignment_details [ 0 ] else : commands = param . get_commands ( ) offset = 1 if commands [ 0 ] in [ '*' , '**' ] else 0 param_name = str ( commands [ offset ] . name ) # add the listener listener = ParamListener ( ) func . listeners . add ( listener ) result = [ ] # This is like backtracking: Get the first possible result. for mod in get_directory_modules_for_name ( [ current_module ] , func_name ) : result = get_params_for_module ( mod ) if result : break # cleanup: remove the listener; important: should not stick. func . listeners . remove ( listener ) return result