diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2016-05-09 14:19:00 +0300 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2016-05-09 17:41:29 +0300 |
commit | 9f8998945feb8ab986ebc7ba66af775edeba3b59 (patch) | |
tree | 0fb785ff62c01c29445651a5acad6646514501c5 | |
parent | cfab7072ce63a207774685782529ba2d6157328d (diff) | |
download | astroid-git-9f8998945feb8ab986ebc7ba66af775edeba3b59.tar.gz |
Build a dummy module object for namespace directories and add a test for multiple directories contributing to the same namespace.
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 |