(self, path: str, prefix: str)
| 115 | return [mod for mod in modules if mod.isidentifier()] |
| 116 | |
| 117 | def _find_modules(self, path: str, prefix: str) -> list[str]: |
| 118 | if not path: |
| 119 | # Top-level import (e.g. `import foo<tab>`` or `from foo<tab>`)` |
| 120 | builtin_modules = [name for name in sys.builtin_module_names |
| 121 | if self.is_suggestion_match(name, prefix)] |
| 122 | third_party_modules = [module.name for module in self.global_cache |
| 123 | if self.is_suggestion_match(module.name, prefix)] |
| 124 | return sorted(builtin_modules + third_party_modules) |
| 125 | |
| 126 | path = self._resolve_relative_path(path) # type: ignore[assignment] |
| 127 | if path is None: |
| 128 | return [] |
| 129 | |
| 130 | modules: Iterable[pkgutil.ModuleInfo] = self.global_cache |
| 131 | imported_module = sys.modules.get(path.split('.')[0]) |
| 132 | if imported_module: |
| 133 | # Filter modules to those whose name and specs match the |
| 134 | # imported module to avoid invalid suggestions |
| 135 | spec = imported_module.__spec__ |
| 136 | if spec: |
| 137 | def _safe_find_spec(mod: pkgutil.ModuleInfo) -> bool: |
| 138 | try: |
| 139 | return mod.module_finder.find_spec(mod.name, None) == spec |
| 140 | except Exception: |
| 141 | return False |
| 142 | modules = [mod for mod in modules |
| 143 | if mod.name == spec.name |
| 144 | and _safe_find_spec(mod)] |
| 145 | else: |
| 146 | modules = [] |
| 147 | |
| 148 | is_stdlib_import: bool | None = None |
| 149 | for segment in path.split('.'): |
| 150 | modules = [mod_info for mod_info in modules |
| 151 | if mod_info.ispkg and mod_info.name == segment] |
| 152 | if is_stdlib_import is None: |
| 153 | # Top-level import decide if we import from stdlib or not |
| 154 | is_stdlib_import = all( |
| 155 | self._is_stdlib_module(mod_info) for mod_info in modules |
| 156 | ) |
| 157 | modules = self.iter_submodules(modules) |
| 158 | |
| 159 | module_names = [module.name for module in modules] |
| 160 | if is_stdlib_import: |
| 161 | module_names.extend(HARDCODED_SUBMODULES.get(path, ())) |
| 162 | return [module_name for module_name in module_names |
| 163 | if self.is_suggestion_match(module_name, prefix)] |
| 164 | |
| 165 | def _is_stdlib_module(self, module_info: pkgutil.ModuleInfo) -> bool: |
| 166 | return (isinstance(module_info.module_finder, FileFinder) |
no test coverage detected