def import_module(inference_state, import_names, parent_module_value, sys_path): """ This method is very similar to importlib's `_gcd_import`. """ if import_names[0] in settings.auto_import_modules: module = _load_builtin_module(inference_state, import_names, sys_path) if module is None: return NO_VALUES return ValueSet([module]) module_name = '.'.join(import_names) if parent_module_value is None: # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. file_io_or_ns, is_pkg = inference_state.compiled_subprocess.get_module_info( string=import_names[-1], full_name=module_name, sys_path=sys_path, is_global_search=True, ) if is_pkg is None: return NO_VALUES else: paths = parent_module_value.py__path__() if paths is None: # The module might not be a package. return NO_VALUES file_io_or_ns, is_pkg = inference_state.compiled_subprocess.get_module_info( string=import_names[-1], path=paths, full_name=module_name, is_global_search=False, ) if is_pkg is None: return NO_VALUES if isinstance(file_io_or_ns, ImplicitNSInfo): from jedi.inference.value.namespace import ImplicitNamespaceValue module = ImplicitNamespaceValue( inference_state, string_names=tuple(file_io_or_ns.name.split('.')), paths=file_io_or_ns.paths, ) elif file_io_or_ns is None: module = _load_builtin_module(inference_state, import_names, sys_path) if module is None: return NO_VALUES else: module = _load_python_module( inference_state, file_io_or_ns, import_names=import_names, is_package=is_pkg, ) if parent_module_value is None: debug.dbg('global search_module %s: %s', import_names[-1], module) else: debug.dbg('search_module %s in paths %s: %s', module_name, paths, module) return ValueSet([module])
def load_namespace_from_path(inference_state, folder_io): import_names, is_package = sys_path.transform_path_to_dotted( inference_state.get_sys_path(), Path(folder_io.path) ) from jedi.inference.value.namespace import ImplicitNamespaceValue return ImplicitNamespaceValue(inference_state, import_names, [folder_io.path])
def follow(self): if not self.import_path: if self._fixed_sys_path: # This is a bit of a special case, that maybe should be # revisited. If the project path is wrong or the user uses # relative imports the wrong way, we might end up here, where # the `fixed_sys_path == project.path` in that case we kind of # use the project.path.parent directory as our path. This is # usually not a problem, except if imports in other places are # using the same names. Example: # # foo/ < #1 # - setup.py # - foo/ < #2 # - __init__.py # - foo.py < #3 # # If the top foo is our project folder and somebody uses # `from . import foo` in `setup.py`, it will resolve to foo #2, # which means that the import for foo.foo is cached as # `__init__.py` (#2) and not as `foo.py` (#3). This is usually # not an issue, because this case is probably pretty rare, but # might be an issue for some people. # # However for most normal cases where we work with different # file names, this code path hits where we basically change the # project path to an ancestor of project path. from jedi.inference.value.namespace import ImplicitNamespaceValue import_path = (os.path.basename(self._fixed_sys_path[0]), ) ns = ImplicitNamespaceValue( self._inference_state, string_names=import_path, paths=self._fixed_sys_path, ) return ValueSet({ns}) return NO_VALUES if not self._infer_possible: return NO_VALUES # Check caches first from_cache = self._inference_state.stub_module_cache.get( self._str_import_path) if from_cache is not None: return ValueSet({from_cache}) from_cache = self._inference_state.module_cache.get( self._str_import_path) if from_cache is not None: return from_cache sys_path = self._sys_path_with_modifications(is_completion=False) return import_module_by_names(self._inference_state, self.import_path, sys_path, self._module_context)