Repository: google/importlab

Issue:
Importlab running under Python 3.6 and analyzing Python 2.7 can't find networkx
Steps I took:

sudo apt-get install python-pip
pip install networkx  # puts networkx in ~/.local/lib/python2.7/site-packages/
virtualenv --python=python3.6 .venv3
source .venv3/bin/activate
pip install importlab
echo "import networkx" > foo.py
importlab -V2.7 foo.py --tree

`foo.py` shows up as the only file in the tree. On the other hand, if I install importlab under Python 2.7 and analyze Python 3.5 code (I didn't try 3.6 because pip3 is 3.5 on my machine), the last command (correctly) causes a bunch of networkx files to be printed as part of the tree.

Discussion:

Patch:
diff --git a/importlab/import_finder.py b/importlab/import_finder.py
index 35e11ff..47687d3 100644
--- a/importlab/import_finder.py
+++ b/importlab/import_finder.py
@@ -64,7 +64,10 @@ def _resolve_import_2(name):
         path = None
     for part in parts[i:]:
         try:
-            spec = imp.find_module(part, path)
+            if path:
+                spec = imp.find_module(part, [path])
+            else:
+                spec = imp.find_module(part)
         except ImportError:
             return None
         path = spec[1]
diff --git a/importlab/resolve.py b/importlab/resolve.py
index c4c1a9c..23314bc 100644
--- a/importlab/resolve.py
+++ b/importlab/resolve.py
@@ -183,8 +183,8 @@ class Resolver:
             short_filename = os.path.dirname(filename)
             files.append((short_name, short_filename))
 
-        for fs in self.fs_path:
-            for module_name, path in files:
+        for module_name, path in files:
+            for fs in self.fs_path:
                 f = self._find_file(fs, path)
                 if not f:
                     continue
@@ -214,6 +214,10 @@ class Resolver:
                 pyfile = prefix + '.py'
                 if os.path.exists(pyfile):
                     return System(pyfile, mod_name)
+            elif not ext:
+                pyfile = os.path.join(prefix, "__init__.py")
+                if os.path.exists(pyfile):
+                    return System(pyfile, mod_name)
             return System(item.source, mod_name)
 
         raise ImportException(name)


Test patch:
diff --git a/tests/test_resolve.py b/tests/test_resolve.py
index 0d00214..df9e8a0 100644
--- a/tests/test_resolve.py
+++ b/tests/test_resolve.py
@@ -176,6 +176,18 @@ class TestResolver(unittest.TestCase):
         self.assertTrue(isinstance(f, resolve.System))
         self.assertEqual(f.module_name, "foo.bar")
 
+    def testResolveSystemPackageDir(self):
+        with utils.Tempdir() as d:
+            py_file = d.create_file("foo/__init__.py")
+            imp = parsepy.ImportStatement("foo",
+                                          source=d["foo"],
+                                          is_from=True)
+            r = self.make_resolver("x.py", "x")
+            f = r.resolve_import(imp)
+            self.assertTrue(isinstance(f, resolve.System))
+            self.assertEqual(f.module_name, "foo")
+            self.assertEqual(f.path, d["foo/__init__.py"])
+
     def testGetPyFromPycSource(self):
         # Override a source pyc file with the corresponding py file if it exists
         # in the native filesystem.