コード例 #1
0
    def _imitate_items(self, arguments):
        lazy_values = [
            LazyKnownValue(
                FakeTuple(self.inference_state,
                          (LazyTreeValue(self._defining_context, key_node),
                           LazyTreeValue(self._defining_context, value_node))))
            for key_node, value_node in self.get_tree_entries()
        ]

        return ValueSet([FakeList(self.inference_state, lazy_values)])
コード例 #2
0
    def _imitate_items(self, arguments):
        lazy_values = [
            LazyKnownValue(
                FakeTuple(self.inference_state,
                          [LazyKnownValues(key),
                           LazyKnownValues(value)]))
            for key, value in self._iterate()
        ]

        return ValueSet([FakeList(self.inference_state, lazy_values)])
コード例 #3
0
 def unpack(self, funcdef=None):
     unpacked = self._partial_arguments.unpack(funcdef)
     # Ignore this one, it's the function. It was checked before that it's
     # there.
     next(unpacked, None)
     if self._instance is not None:
         yield None, LazyKnownValue(self._instance)
     for key_lazy_value in unpacked:
         yield key_lazy_value
     for key_lazy_value in self._call_arguments.unpack(funcdef):
         yield key_lazy_value
コード例 #4
0
ファイル: value.py プロジェクト: jiaoranpan/jedi
    def py__iter__(self, contextualized_node=None):
        if not self.access_handle.has_iter():
            yield from super().py__iter__(contextualized_node)

        access_path_list = self.access_handle.py__iter__list()
        if access_path_list is None:
            # There is no __iter__ method on this object.
            return

        for access in access_path_list:
            yield LazyKnownValue(
                create_from_access_path(self.inference_state, access))
コード例 #5
0
    def _get_yield_lazy_value(self, yield_expr):
        if yield_expr.type == 'keyword':
            # `yield` just yields None.
            ctx = compiled.builtin_from_name(self.inference_state, 'None')
            yield LazyKnownValue(ctx)
            return

        node = yield_expr.children[1]
        if node.type == 'yield_arg':  # It must be a yield from.
            cn = ContextualizedNode(self, node.children[1])
            yield from cn.infer().iterate(cn)
        else:
            yield LazyTreeValue(self, node)
コード例 #6
0
 def py__iter__(self, contextualized_node=None):
     """
     While values returns the possible values for any array field, this
     function returns the value for a certain index.
     """
     for node in self.get_tree_entries():
         if node == ':' or node.type == 'subscript':
             # TODO this should probably use at least part of the code
             #      of infer_subscript_list.
             yield LazyKnownValue(
                 Slice(self._defining_context, None, None, None))
         else:
             yield LazyTreeValue(self._defining_context, node)
     yield from check_array_additions(self._defining_context, self)
コード例 #7
0
ファイル: value.py プロジェクト: hienha/dot-emacs-dot-d
    def py__iter__(self, contextualized_node=None):
        # Python iterators are a bit strange, because there's no need for
        # the __iter__ function as long as __getitem__ is defined (it will
        # just start with __getitem__(0). This is especially true for
        # Python 2 strings, where `str.__iter__` is not even defined.
        if not self.access_handle.has_iter():
            for x in super(CompiledValue, self).py__iter__(contextualized_node):
                yield x

        access_path_list = self.access_handle.py__iter__list()
        if access_path_list is None:
            # There is no __iter__ method on this object.
            return

        for access in access_path_list:
            yield LazyKnownValue(create_from_access_path(self.inference_state, access))
コード例 #8
0
    def unpack(self, funcdef=None):
        named_args = []
        for star_count, el in unpack_arglist(self.argument_node):
            if star_count == 1:
                arrays = self.context.infer_node(el)
                iterators = [
                    _iterate_star_args(self.context, a, el, funcdef)
                    for a in arrays
                ]
                for values in list(zip_longest(*iterators)):
                    # TODO zip_longest yields None, that means this would raise
                    # an exception?
                    yield None, get_merged_lazy_value(
                        [v for v in values if v is not None])
            elif star_count == 2:
                arrays = self.context.infer_node(el)
                for dct in arrays:
                    for key, values in _star_star_dict(self.context, dct, el,
                                                       funcdef):
                        yield key, values
            else:
                if el.type == 'argument':
                    c = el.children
                    if len(c) == 3:  # Keyword argument.
                        named_args.append((
                            c[0].value,
                            LazyTreeValue(self.context, c[2]),
                        ))
                    else:  # Generator comprehension.
                        # Include the brackets with the parent.
                        sync_comp_for = el.children[1]
                        if sync_comp_for.type == 'comp_for':
                            sync_comp_for = sync_comp_for.children[1]
                        comp = iterable.GeneratorComprehension(
                            self._inference_state,
                            defining_context=self.context,
                            sync_comp_for_node=sync_comp_for,
                            entry_node=el.children[0],
                        )
                        yield None, LazyKnownValue(comp)
                else:
                    yield None, LazyTreeValue(self.context, el)

        # Reordering arguments is necessary, because star args sometimes appear
        # after named argument, but in the actual order it's prepended.
        for named_arg in named_args:
            yield named_arg
コード例 #9
0
 def unpack(self, func=None):
     yield None, LazyKnownValue(self.instance)
     for values in self._wrapped_arguments.unpack(func):
         yield values
コード例 #10
0
 def unpack(self, func=None):
     yield None, LazyKnownValue(self.instance)
     yield from self._wrapped_arguments.unpack(func)
コード例 #11
0
 def py__iter__(self, contextualized_node=None):
     for key in self._dct:
         yield LazyKnownValue(
             compiled.create_simple_object(self.inference_state, key))
コード例 #12
0
def get_executed_param_names_and_issues(function_value, arguments):
    """
    Return a tuple of:
      - a list of `ExecutedParamName`s corresponding to the arguments of the
        function execution `function_value`, containing the inferred value of
        those arguments (whether explicit or default)
      - a list of the issues encountered while building that list

    For example, given:
    ```
    def foo(a, b, c=None, d='d'): ...

    foo(42, c='c')
    ```

    Then for the execution of `foo`, this will return a tuple containing:
      - a list with entries for each parameter a, b, c & d; the entries for a,
        c, & d will have their values (42, 'c' and 'd' respectively) included.
      - a list with a single entry about the lack of a value for `b`
    """
    def too_many_args(argument):
        m = _error_argument_count(funcdef, len(unpacked_va))
        # Just report an error for the first param that is not needed (like
        # cPython).
        if arguments.get_calling_nodes():
            # There might not be a valid calling node so check for that first.
            issues.append(
                _add_argument_issue('type-error-too-many-arguments',
                                    argument,
                                    message=m))
        else:
            issues.append(None)
            debug.warning('non-public warning: %s', m)

    issues = []  # List[Optional[analysis issue]]
    result_params = []
    param_dict = {}
    funcdef = function_value.tree_node
    # Default params are part of the value where the function was defined.
    # This means that they might have access on class variables that the
    # function itself doesn't have.
    default_param_context = function_value.get_default_param_context()

    for param in funcdef.get_params():
        param_dict[param.name.value] = param
    unpacked_va = list(arguments.unpack(funcdef))
    var_arg_iterator = PushBackIterator(iter(unpacked_va))

    non_matching_keys = defaultdict(lambda: [])
    keys_used = {}
    keys_only = False
    had_multiple_value_error = False
    for param in funcdef.get_params():
        # The value and key can both be null. There, the defaults apply.
        # args / kwargs will just be empty arrays / dicts, respectively.
        # Wrong value count is just ignored. If you try to test cases that are
        # not allowed in Python, Jedi will maybe not show any completions.
        is_default = False
        key, argument = next(var_arg_iterator, (None, None))
        while key is not None:
            keys_only = True
            try:
                key_param = param_dict[key]
            except KeyError:
                non_matching_keys[key] = argument
            else:
                if key in keys_used:
                    had_multiple_value_error = True
                    m = (
                        "TypeError: %s() got multiple values for keyword argument '%s'."
                        % (funcdef.name, key))
                    for contextualized_node in arguments.get_calling_nodes():
                        issues.append(
                            analysis.add(contextualized_node.context,
                                         'type-error-multiple-values',
                                         contextualized_node.node,
                                         message=m))
                else:
                    keys_used[key] = ExecutedParamName(function_value,
                                                       arguments, key_param,
                                                       argument)
            key, argument = next(var_arg_iterator, (None, None))

        try:
            result_params.append(keys_used[param.name.value])
            continue
        except KeyError:
            pass

        if param.star_count == 1:
            # *args param
            lazy_value_list = []
            if argument is not None:
                lazy_value_list.append(argument)
                for key, argument in var_arg_iterator:
                    # Iterate until a key argument is found.
                    if key:
                        var_arg_iterator.push_back((key, argument))
                        break
                    lazy_value_list.append(argument)
            seq = iterable.FakeTuple(function_value.inference_state,
                                     lazy_value_list)
            result_arg = LazyKnownValue(seq)
        elif param.star_count == 2:
            if argument is not None:
                too_many_args(argument)
            # **kwargs param
            dct = iterable.FakeDict(function_value.inference_state,
                                    dict(non_matching_keys))
            result_arg = LazyKnownValue(dct)
            non_matching_keys = {}
        else:
            # normal param
            if argument is None:
                # No value: Return an empty container
                if param.default is None:
                    result_arg = LazyUnknownValue()
                    if not keys_only:
                        for contextualized_node in arguments.get_calling_nodes(
                        ):
                            m = _error_argument_count(funcdef,
                                                      len(unpacked_va))
                            issues.append(
                                analysis.add(
                                    contextualized_node.context,
                                    'type-error-too-few-arguments',
                                    contextualized_node.node,
                                    message=m,
                                ))
                else:
                    result_arg = LazyTreeValue(default_param_context,
                                               param.default)
                    is_default = True
            else:
                result_arg = argument

        result_params.append(
            ExecutedParamName(function_value,
                              arguments,
                              param,
                              result_arg,
                              is_default=is_default))
        if not isinstance(result_arg, LazyUnknownValue):
            keys_used[param.name.value] = result_params[-1]

    if keys_only:
        # All arguments should be handed over to the next function. It's not
        # about the values inside, it's about the names. Jedi needs to now that
        # there's nothing to find for certain names.
        for k in set(param_dict) - set(keys_used):
            param = param_dict[k]

            if not (non_matching_keys or had_multiple_value_error
                    or param.star_count or param.default):
                # add a warning only if there's not another one.
                for contextualized_node in arguments.get_calling_nodes():
                    m = _error_argument_count(funcdef, len(unpacked_va))
                    issues.append(
                        analysis.add(contextualized_node.context,
                                     'type-error-too-few-arguments',
                                     contextualized_node.node,
                                     message=m))

    for key, lazy_value in non_matching_keys.items():
        m = "TypeError: %s() got an unexpected keyword argument '%s'." \
            % (funcdef.name, key)
        issues.append(
            _add_argument_issue('type-error-keyword-argument',
                                lazy_value,
                                message=m))

    remaining_arguments = list(var_arg_iterator)
    if remaining_arguments:
        first_key, lazy_value = remaining_arguments[0]
        too_many_args(lazy_value)
    return result_params, issues