Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
 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]