Beispiel #1
0
    def gen_param_name_copy(param, keys=(), values=(), array_type=None):
        """
        Create a param with the original scope (of varargs) as parent.
        """
        if isinstance(var_args, pr.Array):
            parent = var_args.parent
            start_pos = var_args.start_pos
        else:
            parent = func
            start_pos = 0, 0

        new_param = copy.copy(param)
        new_param.is_generated = True
        if parent is not None:
            new_param.parent = parent

        # create an Array (-> needed for *args/**kwargs tuples/dicts)
        arr = pr.Array(helpers.FakeSubModule, start_pos, array_type, parent)
        arr.values = values
        key_stmts = []
        for key in keys:
            key_stmts.append(helpers.FakeStatement([key], start_pos))
        arr.keys = key_stmts
        arr.type = array_type

        new_param._expression_list = [arr]

        name = copy.copy(param.get_name())
        name.parent = new_param
        return name
Beispiel #2
0
def _gen_param_name_copy(func, var_args, param, keys=(), values=(), array_type=None):
    """
    Create a param with the original scope (of varargs) as parent.
    """
    if isinstance(var_args, pr.Array):
        parent = var_args.parent
        start_pos = var_args.start_pos
    else:
        parent = func
        start_pos = 0, 0

    new_param = ExecutedParam.from_param(param, parent, var_args)

    # create an Array (-> needed for *args/**kwargs tuples/dicts)
    arr = pr.Array(helpers.FakeSubModule, start_pos, array_type, parent)
    arr.values = list(values)  # Arrays only work with list.
    key_stmts = []
    for key in keys:
        key_stmts.append(helpers.FakeStatement([key], start_pos))
    arr.keys = key_stmts
    arr.type = array_type

    new_param.set_expression_list([arr])

    name = copy.copy(param.get_name())
    name.parent = new_param
    return name
Beispiel #3
0
def _var_args_iterator(evaluator, var_args):
    """
    Yields a key/value pair, the key is None, if its not a named arg.
    """
    # `var_args` is typically an Array, and not a list.
    for stmt in var_args:
        if not isinstance(stmt, pr.Statement):
            if stmt is None:
                yield None, None
                continue
            old = stmt
            # generate a statement if it's not already one.
            stmt = helpers.FakeStatement([old])

        # *args
        expression_list = stmt.expression_list()
        if not len(expression_list):
            continue
        if expression_list[0] == '*':
            # *args must be some sort of an array, otherwise -> ignore
            for array in evaluator.eval_expression_list(expression_list[1:]):
                if isinstance(array, iterable.Array):
                    for field_stmt in array:  # yield from plz!
                        yield None, field_stmt
                elif isinstance(array, iterable.Generator):
                    for field_stmt in array.iter_content():
                        yield None, helpers.FakeStatement([field_stmt])
        # **kwargs
        elif expression_list[0] == '**':
            for array in evaluator.eval_expression_list(expression_list[1:]):
                if isinstance(array, iterable.Array):
                    for key_stmt, value_stmt in array.items():
                        # first index, is the key if syntactically correct
                        call = key_stmt.expression_list()[0]
                        if isinstance(call, pr.Name):
                            yield call, value_stmt
                        elif isinstance(call, pr.Call):
                            yield call.name, value_stmt
        # Normal arguments (including key arguments).
        else:
            if stmt.assignment_details:
                key_arr, op = stmt.assignment_details[0]
                # named parameter
                if key_arr and isinstance(key_arr[0], pr.Call):
                    yield key_arr[0].name, stmt
            else:
                yield None, stmt
Beispiel #4
0
    def get_index_types(self, index_array):

        indexes = iterable.create_indexes_or_slices(self._evaluator,
                                                    index_array)
        if any([isinstance(i, iterable.Slice) for i in indexes]):
            # Slice support in Jedi is very marginal, at the moment, so just
            # ignore them in case of __getitem__.
            # TODO support slices in a more general way.
            indexes = []

        index = helpers.FakeStatement(indexes, parent=compiled.builtin)
        try:
            return self.execute_subscope_by_name('__getitem__', [index])
        except KeyError:
            debug.warning('No __getitem__, cannot access the array.')
            return []
Beispiel #5
0
def _iterate_star_args(evaluator, array, expression_list, func):
    from jedi.evaluate.representation import Instance
    if isinstance(array, iterable.Array):
        for field_stmt in array:  # yield from plz!
            yield field_stmt
    elif isinstance(array, iterable.Generator):
        for field_stmt in array.iter_content():
            yield helpers.FakeStatement([field_stmt])
    elif isinstance(array, Instance) and array.name == 'tuple':
        pass
    else:
        if expression_list:
            m = "TypeError: %s() argument after * must be a sequence, not %s" \
                % (func.name, array)
            analysis.add(evaluator, 'type-error-star',
                         expression_list[0], message=m)
Beispiel #6
0
def _unpack_var_args(evaluator, var_args, func):
    """
    Yields a key/value pair, the key is None, if its not a named arg.
    """
    argument_list = []
    from jedi.evaluate.representation import InstanceElement
    if isinstance(func, InstanceElement):
        # Include self at this place.
        argument_list.append((None, [helpers.FakeStatement([func.instance])]))

    # `var_args` is typically an Array, and not a list.
    for stmt in _reorder_var_args(var_args):
        if not isinstance(stmt, pr.Statement):
            if stmt is None:
                argument_list.append((None, []))
                # TODO generate warning?
                continue
            old = stmt
            # generate a statement if it's not already one.
            stmt = helpers.FakeStatement([old])

        expression_list = stmt.expression_list()
        if not len(expression_list):
            continue
        # *args
        if expression_list[0] == '*':
            arrays = evaluator.eval_expression_list(expression_list[1:])
            iterators = [_iterate_star_args(evaluator, a, expression_list[1:], func)
                         for a in arrays]
            for values in list(zip_longest(*iterators)):
                argument_list.append((None, [v for v in values if v is not None]))
        # **kwargs
        elif expression_list[0] == '**':
            dct = {}
            for array in evaluator.eval_expression_list(expression_list[1:]):
                # Merge multiple kwargs dictionaries, if used with dynamic
                # parameters.
                s = _star_star_dict(evaluator, array, expression_list[1:], func)
                for name, (key, value) in s.items():
                    try:
                        dct[name][1].add(value)
                    except KeyError:
                        dct[name] = key, set([value])

            for key, values in dct.values():
                # merge **kwargs/*args also for dynamic parameters
                for i, p in enumerate(func.params):
                    if str(p.get_name()) == str(key) and not p.stars:
                        try:
                            k, vs = argument_list[i]
                        except IndexError:
                            pass
                        else:
                            if k is None:  # k would imply a named argument
                                # Don't merge if they orginate at the same
                                # place. -> type-error-multiple-values
                                if [v.parent for v in values] != [v.parent for v in vs]:
                                    vs.extend(values)
                                    break
                else:
                    # default is to merge
                    argument_list.append((key, values))
        # Normal arguments (including key arguments).
        else:
            if stmt.assignment_details:
                key_arr, op = stmt.assignment_details[0]
                # Filter error tokens
                key_arr = [x for x in key_arr if isinstance(x, pr.Call)]
                # named parameter
                if key_arr and isinstance(key_arr[0], pr.Call):
                    argument_list.append((key_arr[0].name, [stmt]))
            else:
                argument_list.append((None, [stmt]))
    return argument_list