intellij: Intellij doesn't resolve python imports from pip_install()

Python rules used from https://github.com/bazelbuild/rules_python

A pip dependency added to my target in deps. E.g.: requirement("tensorflow")

import tensorflow OR from pypi__tensorflow as tensorflow

Both of them work with bazel commandline; but Intellij IDE only resolves the second one with Bazel plugin. Looking at the code, the behaviour makes sense.

Following patch reverses the IDE behavior (i.e. first import is resolved and second one isn’t- which seems correct behavior): In https://github.com/bazelbuild/intellij/blob/master/python/src/com/google/idea/blaze/python/resolve/provider/BazelPyImportResolverStrategy.java#L50:

diff --git a/python/src/com/google/idea/blaze/python/resolve/provider/BazelPyImportResolverStrategy.java b/python/src/com/google/idea/blaze/python/resolve/provider/BazelPyImportResolverStrategy.java
index ee0acbda..56d1f92c 100644
--- a/python/src/com/google/idea/blaze/python/resolve/provider/BazelPyImportResolverStrategy.java
+++ b/python/src/com/google/idea/blaze/python/resolve/provider/BazelPyImportResolverStrategy.java
@@ -22,6 +22,8 @@ import com.intellij.psi.PsiElement;
 import com.intellij.psi.util.QualifiedName;
 import com.jetbrains.python.psi.resolve.PyQualifiedNameResolveContext;
 import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import javax.annotation.Nullable;
 
 /**
@@ -32,6 +34,10 @@ import javax.annotation.Nullable;
  */
 public class BazelPyImportResolverStrategy extends AbstractPyImportResolverStrategy {
 
+  // Packages installed with pip_install in python_rules are installed in a subdir that starts
+  // with this prefix.
+  private static final String PIP_INSTALL_DIR_PREFIX = "pypi__";
+
   @Override
   public boolean appliesToBuildSystem(BuildSystem buildSystem) {
     return buildSystem == BuildSystem.Bazel;
@@ -51,6 +57,11 @@ public class BazelPyImportResolverStrategy extends AbstractPyImportResolverStrat
     if (source.isGenerated() || !source.getRelativePath().endsWith(".py")) {
       return null;
     }
-    return fromRelativePath(source.getRelativePath());
+    String relativePath = source.getRelativePath();
+    if (relativePath.startsWith(PIP_INSTALL_DIR_PREFIX)) {
+      Path path = Paths.get(relativePath);
+      relativePath = path.subpath(1, path.getNameCount()).toString();
+    }
+    return fromRelativePath(relativePath);
   }
 }

If it makes sense, I can send a pull request.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 14
  • Comments: 24 (8 by maintainers)

Most upvoted comments

Just leaving a comment for those looking for a workaround: I managed to workaround this issue by downgrading rules_python to 0.9.0 (this may not be a solution for everyone)

http_archive(
    name = "rules_python",
    sha256 = "5fa3c738d33acca3b97622a13a741129f67ef43f5fdfcec63b29374cc0574c29",
    strip_prefix = "rules_python-0.9.0",
    url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.9.0.tar.gz",
)

I am using my the plugin compiled from my fork with this fix: https://github.com/sudopk/intellij

The fix works. I didn’t hear from bazel team, so didn’t take any further steps. If bazel team can include this fix, it will be easy. I can send a pull request, but adding tests will take me some more effort since I have never done plugin development.