def collections_namedtuple(value, arguments, callback): """ Implementation of the namedtuple function. This has to be done by processing the namedtuple class template and inferring the result. """ inference_state = value.inference_state # Process arguments name = u'jedi_unknown_namedtuple' for c in _follow_param(inference_state, arguments, 0): x = get_str_or_none(c) if x is not None: name = force_unicode(x) break # TODO here we only use one of the types, we should use all. param_values = _follow_param(inference_state, arguments, 1) if not param_values: return NO_VALUES _fields = list(param_values)[0] string = get_str_or_none(_fields) if string is not None: fields = force_unicode(string).replace(',', ' ').split() elif isinstance(_fields, iterable.Sequence): fields = [ force_unicode(get_str_or_none(v)) for lazy_value in _fields.py__iter__() for v in lazy_value.infer() ] fields = [f for f in fields if f is not None] else: return NO_VALUES # Build source code code = _NAMEDTUPLE_CLASS_TEMPLATE.format( typename=name, field_names=tuple(fields), num_fields=len(fields), arg_list=repr(tuple(fields)).replace("u'", "").replace("'", "")[1:-1], repr_fmt='', field_defs='\n'.join( _NAMEDTUPLE_FIELD_TEMPLATE.format(index=index, name=name) for index, name in enumerate(fields))) # Parse source code module = inference_state.grammar.parse(code) generated_class = next(module.iter_classdefs()) parent_context = ModuleValue( inference_state, module, file_io=None, string_names=None, code_lines=parso.split_lines(code, keepends=True), ).as_context() return ValueSet( [ClassValue(inference_state, parent_context, generated_class)])
def iterate(): for value in strings: s = get_str_or_none(value) if s is not None: s = func(s) yield compiled.create_simple_object( value.inference_state, s)
def builtins_getattr(objects, names, defaults=None): # follow the first param for value in objects: for name in names: string = get_str_or_none(name) if string is None: debug.warning('getattr called without str') continue else: return value.py__getattribute__(string) return NO_VALUES
def _add_strings(context, nodes, add_slash=False): string = '' first = True for child_node in nodes: values = context.infer_node(child_node) if len(values) != 1: return None c, = values s = get_str_or_none(c) if s is None: return None if not first and add_slash: string += os.path.sep string += force_unicode(s) first = False return string
def _os_path_join(args_set, callback): if len(args_set) == 1: string = '' sequence, = args_set is_first = True for lazy_value in sequence.py__iter__(): string_values = lazy_value.infer() if len(string_values) != 1: break s = get_str_or_none(next(iter(string_values))) if s is None: break if not is_first: string += os.path.sep string += s is_first = False else: return ValueSet([compiled.create_simple_object(sequence.inference_state, string)]) return callback()
def _paths_from_list_modifications(module_context, trailer1, trailer2): """ extract the path from either "sys.path.append" or "sys.path.insert" """ # Guarantee that both are trailers, the first one a name and the second one # a function execution with at least one param. if not (trailer1.type == 'trailer' and trailer1.children[0] == '.' and trailer2.type == 'trailer' and trailer2.children[0] == '(' and len(trailer2.children) == 3): return name = trailer1.children[1].value if name not in ['insert', 'append']: return arg = trailer2.children[1] if name == 'insert' and len(arg.children) in (3, 4): # Possible trailing comma. arg = arg.children[2] for value in module_context.create_context(arg).infer_node(arg): p = get_str_or_none(value) if p is None: continue abs_path = _abs_path(module_context, p) if abs_path is not None: yield abs_path