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
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
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
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 []
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)
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