PY-24728 Follow symlinks inside virtualenv to detect stdlib modules

This way we deal both with symlinks in a venv pointing to actual modules
of its base interpreter and also with rare interpreter layout of
on some x86_64 systems, like Fedora, where there is "lib64"
alias to "lib" directory of a virtualenv, and stdlib of the base
interpreter is also under /usr/lib64 instead of /usr/lib.

On the whole, we can follow this path now:
venv/prefix/lib64/os.py ->
venv/prefix/lib/os.py ->
base/interpreter/prefix/lib64/os.py

and detection of the lib directory of a base interpreter is
always correct since it doesn't depend on the actual name in use.
This commit is contained in:
Mikhail Golubev
2018-02-27 18:37:50 +03:00
parent 63bd38bc8c
commit cb72c405ef
@@ -46,6 +46,7 @@ import com.intellij.remote.ext.LanguageCaseCollector;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ExceptionUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
@@ -735,14 +736,15 @@ public final class PythonSdkType extends SdkType {
}
public static boolean isStdLib(@NotNull VirtualFile vFile, @Nullable Sdk pythonSdk) {
final VirtualFile resolved = ObjectUtils.notNull(vFile.getCanonicalFile(), vFile);
if (pythonSdk != null) {
final VirtualFile libDir = PyProjectScopeBuilder.findLibDir(pythonSdk);
if (libDir != null && VfsUtilCore.isAncestor(libDir, vFile, false)) {
return isNotSitePackages(vFile, libDir);
if (libDir != null && VfsUtilCore.isAncestor(libDir, resolved, false)) {
return isNotSitePackages(resolved, libDir);
}
final VirtualFile venvLibDir = PyProjectScopeBuilder.findVirtualEnvLibDir(pythonSdk);
if (venvLibDir != null && VfsUtilCore.isAncestor(venvLibDir, vFile, false)) {
return isNotSitePackages(vFile, venvLibDir);
if (venvLibDir != null && VfsUtilCore.isAncestor(venvLibDir, resolved, false)) {
return isNotSitePackages(resolved, venvLibDir);
}
final VirtualFile skeletonsDir = PySdkUtil.findSkeletonsDir(pythonSdk);
if (skeletonsDir != null &&