1
0
forked from VimPlug/jedi

Namespace packages work again. This time the same way as Python does it.

This commit is contained in:
Dave Halter
2015-04-23 03:36:46 +02:00
parent 039579b391
commit a7c4b5800b
2 changed files with 83 additions and 53 deletions

View File

@@ -389,7 +389,6 @@ class _Importer(object):
except KeyError: except KeyError:
pass pass
try:
if len(import_path) > 1: if len(import_path) > 1:
# This is a recursive way of importing that works great with # This is a recursive way of importing that works great with
# the module cache. # the module cache.
@@ -409,7 +408,7 @@ class _Importer(object):
return self._evaluator.find_types(base, 'path') return self._evaluator.find_types(base, 'path')
try: try:
paths = base.py__path__() paths = base.py__path__(sys_path)
except AttributeError: except AttributeError:
# The module is not a package. # The module is not a package.
_add_error(self._evaluator, import_path[-1]) _add_error(self._evaluator, import_path[-1])
@@ -419,9 +418,17 @@ class _Importer(object):
for path in paths: for path in paths:
# At the moment we are only using one path. So this is # At the moment we are only using one path. So this is
# not important to be correct. # not important to be correct.
try:
module_file, module_path, is_pkg = \ module_file, module_path, is_pkg = \
find_module(import_parts[-1], [path]) find_module(import_parts[-1], [path])
break
except ImportError:
module_path = None
if module_path is None:
_add_error(self._evaluator, import_path[-1])
return []
else: else:
try:
debug.dbg('search_module %s in %s', import_parts[-1], self.file_path) debug.dbg('search_module %s in %s', import_parts[-1], self.file_path)
# Override the sys.path. It works only good that way. # Override the sys.path. It works only good that way.
# Injecting the path directly into `find_module` did not work. # Injecting the path directly into `find_module` did not work.
@@ -435,7 +442,7 @@ class _Importer(object):
# The module is not a package. # The module is not a package.
_add_error(self._evaluator, import_path[-1]) _add_error(self._evaluator, import_path[-1])
return [] return []
else:
source = None source = None
if is_pkg: if is_pkg:
# In this case, we don't have a file yet. Search for the # In this case, we don't have a file yet. Search for the

View File

@@ -786,11 +786,34 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)):
@property @property
def py__path__(self): def py__path__(self):
""" """
Not seen here, since it's a property. The callback actually uses a
variable, so use it like::
foo.py__path__(sys_path)
In case of a package, this returns Python's __path__ attribute, which In case of a package, this returns Python's __path__ attribute, which
is a list of paths (strings). is a list of paths (strings).
Raises an AttributeError if the module is not a package. Raises an AttributeError if the module is not a package.
""" """
def return_value(): def return_value(search_path):
init_path = self.py__file__()
if os.path.basename(init_path) == '__init__.py':
with open(init_path, 'rb') as f:
content = common.source_to_unicode(f.read())
# these are strings that need to be used for namespace packages,
# the first one is ``pkgutil``, the second ``pkg_resources``.
options = ('declare_namespace(__name__)', 'extend_path(__path__')
if options[0] in content or options[1] in content:
# It is a namespace, now try to find the rest of the
# modules on sys_path or whatever the search_path is.
paths = set()
for s in search_path:
other = os.path.join(s, unicode(self.name))
if os.path.isdir(other):
paths.add(other)
return list(paths)
# Default to this.
return [path] return [path]
path = self._get_init_directory() path = self._get_init_directory()