def dynamic_param_lookup(function_value, param_index): """ A dynamic search for param values. If you try to complete a type: >>> def func(foo): ... foo >>> func(1) >>> func("") It is not known what the type ``foo`` without analysing the whole code. You have to look for all calls to ``func`` to find out what ``foo`` possibly is. """ funcdef = function_value.tree_node if not settings.dynamic_params: return NO_VALUES path = function_value.get_root_context().py__file__() if path is not None and is_stdlib_path(path): # We don't want to search for references in the stdlib. Usually people # don't work with it (except if you are a core maintainer, sorry). # This makes everything slower. Just disable it and run the tests, # you will see the slowdown, especially in 3.6. return NO_VALUES if funcdef.type == 'lambdef': string_name = _get_lambda_name(funcdef) if string_name is None: return NO_VALUES else: string_name = funcdef.name.value debug.dbg('Dynamic param search in %s.', string_name, color='MAGENTA') module_context = function_value.get_root_context() arguments_list = _search_function_arguments(module_context, funcdef, string_name) values = ValueSet.from_sets( get_executed_param_names(function_value, arguments) [param_index].infer() for arguments in arguments_list) debug.dbg('Dynamic param result finished', color='MAGENTA') return values
def infer_type_vars_for_execution(function, arguments, annotation_dict): """ Some functions use type vars that are not defined by the class, but rather only defined in the function. See for example `iter`. In those cases we want to: 1. Search for undefined type vars. 2. Infer type vars with the execution state we have. 3. Return the union of all type vars that have been found. """ context = function.get_default_param_context() annotation_variable_results = {} executed_param_names = get_executed_param_names(function, arguments) for executed_param_name in executed_param_names: try: annotation_node = annotation_dict[executed_param_name.string_name] except KeyError: continue annotation_variables = find_unknown_type_vars(context, annotation_node) if annotation_variables: # Infer unknown type var annotation_value_set = context.infer_node(annotation_node) kind = executed_param_name.get_kind() actual_value_set = executed_param_name.infer() if kind is Parameter.VAR_POSITIONAL: actual_value_set = actual_value_set.merge_types_of_iterate() elif kind is Parameter.VAR_KEYWORD: # TODO _dict_values is not public. actual_value_set = actual_value_set.try_merge('_dict_values') for ann in annotation_value_set: _merge_type_var_dicts( annotation_variable_results, _infer_type_vars(ann, actual_value_set), ) return annotation_variable_results
def get_executed_param_name(self): from jedi.inference.param import get_executed_param_names params_names = get_executed_param_names(self.function_value, self.arguments) return params_names[self._get_param_node().position_index]