def _iter_module_names(inference_state, paths): # Python modules/packages for path in paths: try: dirs = scandir(path) except OSError: # The file might not exist or reading it might lead to an error. debug.warning("Not possible to list directory: %s", path) continue for dir_entry in dirs: name = dir_entry.name # First Namespaces then modules/stubs if dir_entry.is_dir(): # pycache is obviously not an interestin namespace. Also the # name must be a valid identifier. # TODO use str.isidentifier, once Python 2 is removed if name != '__pycache__' and not re.search(r'\W|^\d', name): yield name else: if name.endswith('.pyi'): # Stub files modname = name[:-4] else: modname = inspect.getmodulename(name) if modname and '.' not in modname: if modname != '__init__': yield modname
def test_complete_expanduser(Script): possibilities = scandir(expanduser('~')) non_dots = [p for p in possibilities if not p.name.startswith('.') and len(p.name) > 1] item = non_dots[0] line = "'~%s%s'" % (os.sep, item.name) s = Script(line) expected_name = item.name if item.is_dir(): expected_name += os.path.sep assert expected_name in [c.name for c in s.complete(column=len(line)-1)]
def file_name_completions(inference_state, module_context, start_leaf, string, like_name, call_signatures_callback, code_lines, position): # First we want to find out what can actually be changed as a name. like_name_length = len(os.path.basename(string) + like_name) addition = _get_string_additions(module_context, start_leaf) if addition is None: return string = addition + string # Here we use basename again, because if strings are added like # `'foo' + 'bar`, it should complete to `foobar/`. must_start_with = os.path.basename(string) + like_name string = os.path.dirname(string) sigs = call_signatures_callback() is_in_os_path_join = sigs and all(s.full_name == 'os.path.join' for s in sigs) if is_in_os_path_join: to_be_added = _add_os_path_join(module_context, start_leaf, sigs[0].bracket_start) if to_be_added is None: is_in_os_path_join = False else: string = to_be_added + string base_path = os.path.join(inference_state.project._path, string) try: listed = scandir(base_path) # OSError: [Errno 36] File name too long: '...' except (FileNotFoundError, OSError): return for entry in listed: name = entry.name if name.startswith(must_start_with): if is_in_os_path_join or not entry.is_dir(): if start_leaf.type == 'string': quote = get_string_quote(start_leaf) else: assert start_leaf.type == 'error_leaf' quote = start_leaf.value potential_other_quote = \ code_lines[position[0] - 1][position[1]:position[1] + len(quote)] # Add a quote if it's not already there. if quote != potential_other_quote: name += quote else: name += os.path.sep yield classes.Completion( inference_state, FileName(inference_state, name[len(must_start_with) - like_name_length:]), stack=None, like_name_length=like_name_length)
def complete_file_name(inference_state, module_context, start_leaf, string, like_name, signatures_callback, code_lines, position, fuzzy): # First we want to find out what can actually be changed as a name. like_name_length = len(os.path.basename(string)) addition = _get_string_additions(module_context, start_leaf) if addition is None: return string = addition + string # Here we use basename again, because if strings are added like # `'foo' + 'bar`, it should complete to `foobar/`. must_start_with = os.path.basename(string) string = os.path.dirname(string) sigs = signatures_callback(*position) is_in_os_path_join = sigs and all(s.full_name == 'os.path.join' for s in sigs) if is_in_os_path_join: to_be_added = _add_os_path_join(module_context, start_leaf, sigs[0].bracket_start) if to_be_added is None: is_in_os_path_join = False else: string = to_be_added + string base_path = os.path.join(inference_state.project._path, string) try: listed = sorted(scandir(base_path), key=lambda e: e.name) # OSError: [Errno 36] File name too long: '...' except (FileNotFoundError, OSError): return for entry in listed: name = entry.name if fuzzy: match = fuzzy_match(name, must_start_with) else: match = start_match(name, must_start_with) if match: if is_in_os_path_join or not entry.is_dir(): name += get_quote_ending(start_leaf.value, code_lines, position) else: name += os.path.sep yield classes.Completion( inference_state, PathName(inference_state, name[len(must_start_with) - like_name_length:]), stack=None, like_name_length=like_name_length, is_fuzzy=fuzzy, )