summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2016-08-24 09:44:03 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2016-08-24 09:57:39 +0300
commit6b9a7ed82cef0b89edb00b19e991fe6ec5d057d5 (patch)
treee8bcd6765980f5c9fc628d44714888da14416a9d
parent8ec025fa36c9c627bcdd6da7fab56271731d47eb (diff)
downloadastroid-git-6b9a7ed82cef0b89edb00b19e991fe6ec5d057d5.tar.gz
Add support for discovering .pth file created by certain namespace packages.
-rw-r--r--astroid/modutils.py29
-rw-r--r--astroid/tests/testdata/python2/data/foogle/fax/__init__.py0
-rw-r--r--astroid/tests/testdata/python2/data/foogle/fax/a.py1
-rw-r--r--astroid/tests/testdata/python2/data/foogle_fax-0.12.5-py2.7-nspkg.pth1
-rw-r--r--astroid/tests/testdata/python3/data/foogle/fax/__init__.py0
-rw-r--r--astroid/tests/testdata/python3/data/foogle/fax/a.py1
-rw-r--r--astroid/tests/testdata/python3/data/foogle_fax-0.12.5-py2.7-nspkg.pth1
-rw-r--r--astroid/tests/unittest_manager.py18
8 files changed, 47 insertions, 4 deletions
diff --git a/astroid/modutils.py b/astroid/modutils.py
index 77081b5b..3334e1e3 100644
--- a/astroid/modutils.py
+++ b/astroid/modutils.py
@@ -742,6 +742,22 @@ class ImpFinder(Finder):
return path
+class DynamicImpFinder(ImpFinder):
+
+ def find_module(self, modname, module_parts, processed, submodule_path):
+ if _is_namespace(modname) and modname in sys.modules:
+ submodule_path = sys.modules[modname].__path__
+ return ModuleSpec(name=modname, location='',
+ origin='namespace',
+ type=ModuleType.PY_NAMESPACE,
+ submodule_search_locations=submodule_path)
+
+
+ def contribute_to_path(self, spec, processed):
+ return spec.submodule_search_locations
+
+
+
class ZipFinder(Finder):
def __init__(self, path):
@@ -776,12 +792,17 @@ class PEP420SpecFinder(Finder):
return spec.submodule_search_locations
return None
+_SPEC_FINDERS = (
+ ImpFinder,
+ ZipFinder,
+)
+if _HAS_MACHINERY and sys.version_info[:2] > (3, 3):
+ _SPEC_FINDERS += (PEP420SpecFinder, )
+_SPEC_FINDERS += (DynamicImpFinder, )
-def _find_spec_with_path(search_path, modname, module_parts, processed, submodule_path):
- finders = [finder(search_path) for finder in (ImpFinder, ZipFinder)]
- if _HAS_MACHINERY and sys.version_info[:2] > (3, 3):
- finders.append(PEP420SpecFinder(search_path))
+def _find_spec_with_path(search_path, modname, module_parts, processed, submodule_path):
+ finders = [finder(search_path) for finder in _SPEC_FINDERS]
for finder in finders:
spec = finder.find_module(modname, module_parts, processed, submodule_path)
if spec is None:
diff --git a/astroid/tests/testdata/python2/data/foogle/fax/__init__.py b/astroid/tests/testdata/python2/data/foogle/fax/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/astroid/tests/testdata/python2/data/foogle/fax/__init__.py
diff --git a/astroid/tests/testdata/python2/data/foogle/fax/a.py b/astroid/tests/testdata/python2/data/foogle/fax/a.py
new file mode 100644
index 00000000..3d2b4b14
--- /dev/null
+++ b/astroid/tests/testdata/python2/data/foogle/fax/a.py
@@ -0,0 +1 @@
+x = 1 \ No newline at end of file
diff --git a/astroid/tests/testdata/python2/data/foogle_fax-0.12.5-py2.7-nspkg.pth b/astroid/tests/testdata/python2/data/foogle_fax-0.12.5-py2.7-nspkg.pth
new file mode 100644
index 00000000..d3cb4591
--- /dev/null
+++ b/astroid/tests/testdata/python2/data/foogle_fax-0.12.5-py2.7-nspkg.pth
@@ -0,0 +1 @@
+import sys, types, os;p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('foogle',));ie = os.path.exists(os.path.join(p,'__init__.py'));m = not ie and sys.modules.setdefault('foogle', types.ModuleType('foogle'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p)
diff --git a/astroid/tests/testdata/python3/data/foogle/fax/__init__.py b/astroid/tests/testdata/python3/data/foogle/fax/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/astroid/tests/testdata/python3/data/foogle/fax/__init__.py
diff --git a/astroid/tests/testdata/python3/data/foogle/fax/a.py b/astroid/tests/testdata/python3/data/foogle/fax/a.py
new file mode 100644
index 00000000..3d2b4b14
--- /dev/null
+++ b/astroid/tests/testdata/python3/data/foogle/fax/a.py
@@ -0,0 +1 @@
+x = 1 \ No newline at end of file
diff --git a/astroid/tests/testdata/python3/data/foogle_fax-0.12.5-py2.7-nspkg.pth b/astroid/tests/testdata/python3/data/foogle_fax-0.12.5-py2.7-nspkg.pth
new file mode 100644
index 00000000..d3cb4591
--- /dev/null
+++ b/astroid/tests/testdata/python3/data/foogle_fax-0.12.5-py2.7-nspkg.pth
@@ -0,0 +1 @@
+import sys, types, os;p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('foogle',));ie = os.path.exists(os.path.join(p,'__init__.py'));m = not ie and sys.modules.setdefault('foogle', types.ModuleType('foogle'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p)
diff --git a/astroid/tests/unittest_manager.py b/astroid/tests/unittest_manager.py
index 34c9ef8f..3b145853 100644
--- a/astroid/tests/unittest_manager.py
+++ b/astroid/tests/unittest_manager.py
@@ -7,9 +7,11 @@
import os
import platform
+import site
import sys
import unittest
+import pkg_resources
import six
import astroid
@@ -120,6 +122,22 @@ class AstroidManagerTest(resources.SysPathSetup,
for _ in range(2):
sys.path.pop(0)
+ def test_namespace_package_pth_support(self):
+ directory = os.path.join(resources.DATA_DIR, 'data')
+ pth = 'foogle_fax-0.12.5-py2.7-nspkg.pth'
+ site.addpackage(directory, pth, [])
+ pkg_resources._namespace_packages['foogle'] = []
+ try:
+ module = self.manager.ast_from_module_name('foogle.fax')
+ submodule = next(module.igetattr('a'))
+ value = next(submodule.igetattr('x'))
+ self.assertIsInstance(value, astroid.Const)
+ with self.assertRaises(exceptions.AstroidImportError):
+ self.manager.ast_from_module_name('foogle.moogle')
+ finally:
+ del pkg_resources._namespace_packages['foogle']
+ sys.modules.pop('foogle')
+
def _test_ast_from_zip(self, archive):
origpath = sys.path[:]
sys.modules.pop('mypypa', None)