summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2016-05-09 14:19:00 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2016-05-09 17:41:29 +0300
commit9f8998945feb8ab986ebc7ba66af775edeba3b59 (patch)
tree0fb785ff62c01c29445651a5acad6646514501c5
parentcfab7072ce63a207774685782529ba2d6157328d (diff)
downloadastroid-git-9f8998945feb8ab986ebc7ba66af775edeba3b59.tar.gz
Build a dummy module object for namespace directories and add a test for multiple directories contributing to the same namespace.
-rw-r--r--astroid/builder.py5
-rw-r--r--astroid/manager.py6
-rw-r--r--astroid/tests/testdata/python2/data/contribute_to_namespace/namespace_pep_420/submodule.py1
-rw-r--r--astroid/tests/testdata/python2/data/namespace_pep_420/module.py1
-rw-r--r--astroid/tests/testdata/python3/data/contribute_to_namespace/namespace_pep_420/submodule.py1
-rw-r--r--astroid/tests/testdata/python3/data/namespace_pep_420/module.py1
-rw-r--r--astroid/tests/unittest_manager.py11
-rw-r--r--astroid/tests/unittest_modutils.py1
-rw-r--r--astroid/tree/scoped_nodes.py2
9 files changed, 27 insertions, 2 deletions
diff --git a/astroid/builder.py b/astroid/builder.py
index ca2b92ba..0c05f8cf 100644
--- a/astroid/builder.py
+++ b/astroid/builder.py
@@ -36,6 +36,7 @@ from astroid.tree import treeabc
from astroid import util
raw_building = util.lazy_import('raw_building')
+nodes = util.lazy_import('nodes')
def _parse(string):
@@ -237,6 +238,10 @@ def delayed_assignments(root):
pass
+def build_namespace_package_module(name, path):
+ return nodes.Module(name, doc='', path=path, package=True)
+
+
def parse(code, module_name='', path=None, apply_transforms=True):
"""Parses a source string in order to obtain an astroid AST from it
diff --git a/astroid/manager.py b/astroid/manager.py
index f6c9a261..73dd961a 100644
--- a/astroid/manager.py
+++ b/astroid/manager.py
@@ -94,6 +94,10 @@ class AstroidManager(object):
def _build_stub_module(self, modname):
return builder.AstroidBuilder(self).string_build('', modname)
+ def _build_namespace_module(self, modname, path):
+ from astroid.builder import build_namespace_package_module
+ return build_namespace_package_module(modname, path)
+
def _can_load_extension(self, modname):
if self.always_load_extensions:
return True
@@ -133,6 +137,8 @@ class AstroidManager(object):
raise exceptions.AstroidImportError(
"Unable to load compiled module {modname}.",
modname=modname, path=spec.location)
+ elif spec.type == modutils.ModuleType.PY_NAMESPACE:
+ return self._build_namespace_module(modname, spec.submodule_search_locations)
if spec.location is None:
raise exceptions.AstroidImportError(
"Can't find a file for module {modname}.",
diff --git a/astroid/tests/testdata/python2/data/contribute_to_namespace/namespace_pep_420/submodule.py b/astroid/tests/testdata/python2/data/contribute_to_namespace/namespace_pep_420/submodule.py
new file mode 100644
index 00000000..6fbcff41
--- /dev/null
+++ b/astroid/tests/testdata/python2/data/contribute_to_namespace/namespace_pep_420/submodule.py
@@ -0,0 +1 @@
+var = 42 \ No newline at end of file
diff --git a/astroid/tests/testdata/python2/data/namespace_pep_420/module.py b/astroid/tests/testdata/python2/data/namespace_pep_420/module.py
index e69de29b..a4d111e6 100644
--- a/astroid/tests/testdata/python2/data/namespace_pep_420/module.py
+++ b/astroid/tests/testdata/python2/data/namespace_pep_420/module.py
@@ -0,0 +1 @@
+from namespace_pep_420.submodule import var \ No newline at end of file
diff --git a/astroid/tests/testdata/python3/data/contribute_to_namespace/namespace_pep_420/submodule.py b/astroid/tests/testdata/python3/data/contribute_to_namespace/namespace_pep_420/submodule.py
new file mode 100644
index 00000000..6fbcff41
--- /dev/null
+++ b/astroid/tests/testdata/python3/data/contribute_to_namespace/namespace_pep_420/submodule.py
@@ -0,0 +1 @@
+var = 42 \ No newline at end of file
diff --git a/astroid/tests/testdata/python3/data/namespace_pep_420/module.py b/astroid/tests/testdata/python3/data/namespace_pep_420/module.py
index e69de29b..a4d111e6 100644
--- a/astroid/tests/testdata/python3/data/namespace_pep_420/module.py
+++ b/astroid/tests/testdata/python3/data/namespace_pep_420/module.py
@@ -0,0 +1 @@
+from namespace_pep_420.submodule import var \ No newline at end of file
diff --git a/astroid/tests/unittest_manager.py b/astroid/tests/unittest_manager.py
index 40c21770..1b83862c 100644
--- a/astroid/tests/unittest_manager.py
+++ b/astroid/tests/unittest_manager.py
@@ -116,13 +116,20 @@ class AstroidManagerTest(resources.SysPathSetup,
@unittest.skipUnless(sys.version_info[:2] > (3, 3), "Needs PEP 420 namespace protocol")
def test_implicit_namespace_package(self):
data_dir = os.path.dirname(resources.find('data/namespace_pep_420'))
- sys.path.insert(0, data_dir)
+ contribute = os.path.join(data_dir, 'contribute_to_namespace')
+ for value in (data_dir, contribute):
+ sys.path.insert(0, value)
+
try:
module = self.manager.ast_from_module_name('namespace_pep_420.module')
self.assertIsInstance(module, astroid.Module)
self.assertEqual(module.name, 'namespace_pep_420.module')
+ var = next(module.igetattr('var'))
+ self.assertIsInstance(var, astroid.Const)
+ self.assertEqual(var.value, 42)
finally:
- sys.path.pop(0)
+ for _ in range(2):
+ sys.path.pop(0)
def _test_ast_from_zip(self, archive):
origpath = sys.path[:]
diff --git a/astroid/tests/unittest_modutils.py b/astroid/tests/unittest_modutils.py
index b8d5213c..05a7e9d5 100644
--- a/astroid/tests/unittest_modutils.py
+++ b/astroid/tests/unittest_modutils.py
@@ -110,6 +110,7 @@ class ModPathFromFileTest(unittest.TestCase):
def test_raise_modpath_from_file_Exception(self):
self.assertRaises(Exception, modutils.modpath_from_file, '/turlututu')
+ @unittest.skipUnless(sys.version_info[:2] > (3, 3), "Needs Python 3.3+ namespace package.")
def test_modpath_from_file_namespace(self):
datadir = os.path.abspath(resources.find('data'))
path = os.path.abspath(
diff --git a/astroid/tree/scoped_nodes.py b/astroid/tree/scoped_nodes.py
index 46420dfb..7bdc8aab 100644
--- a/astroid/tree/scoped_nodes.py
+++ b/astroid/tree/scoped_nodes.py
@@ -314,6 +314,7 @@ class Module(QualifiedNameMixin, lookup.LocalsDictNode):
if relative_only and level is None:
level = 0
absmodname = self.relative_to_absolute_name(modname, level)
+
try:
return MANAGER.ast_from_module_name(absmodname)
except exceptions.AstroidBuildingError:
@@ -345,6 +346,7 @@ class Module(QualifiedNameMixin, lookup.LocalsDictNode):
package_name = self.name
else:
package_name = self.name.rsplit('.', 1)[0]
+
if package_name:
if not modname:
return package_name