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])
Beispiel #3
0
    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)