Fix a NotImplementedError when loading random modules

This commit is contained in:
Dave Halter
2019-05-20 09:54:41 +02:00
parent 03de39092a
commit 95cd8427f4
2 changed files with 45 additions and 22 deletions

View File

@@ -485,6 +485,34 @@ def _load_builtin_module(evaluator, import_names=None, sys_path=None):
return module
def _load_module_from_path(evaluator, path, base_names, code):
"""
This should pretty much only be used for get_modules_containing_name. It's
here to ensure that a random path is still properly loaded into the Jedi
module structure.
"""
e_sys_path = evaluator.get_sys_path()
if base_names:
module_name = os.path.basename(path)
module_name = sys_path.remove_python_path_suffix(module_name)
is_package = module_name == '__init__'
if is_package:
import_names = base_names
else:
import_names = base_names + (module_name,)
else:
import_names, is_package = sys_path.transform_path_to_dotted(e_sys_path, path)
module = _load_python_module(
evaluator, KnownContentFileIO(path, code),
sys_path=e_sys_path,
import_names=import_names,
is_package=is_package,
)
evaluator.module_cache.add(import_names, ContextSet([module]))
return module
def get_modules_containing_name(evaluator, modules, name):
"""
Search a name in the directories of modules.
@@ -505,28 +533,7 @@ def get_modules_containing_name(evaluator, modules, name):
code = python_bytes_to_unicode(f.read(), errors='replace')
if name not in code:
return None
e_sys_path = evaluator.get_sys_path()
if base_names:
module_name = os.path.basename(path)
module_name = sys_path.remove_python_path_suffix(module_name)
is_package = module_name == '__init__'
if is_package:
raise NotImplementedError(
"This is probably not possible yet, please add a failing test first")
module_name = os.path.basename(os.path.dirname(path))
import_names = base_names + (module_name,)
else:
import_names, is_package = sys_path.transform_path_to_dotted(e_sys_path, path)
module = _load_python_module(
evaluator, KnownContentFileIO(path, code),
sys_path=e_sys_path,
import_names=import_names,
is_package=is_package,
)
evaluator.module_cache.add(import_names, ContextSet([module]))
return module
return _load_module_from_path(evaluator, path, base_names, code)
# skip non python modules
used_mod_paths = set()

View File

@@ -325,6 +325,22 @@ def test_get_modules_containing_name(evaluator, path, goal, is_package):
assert found_module.string_names == goal
@pytest.mark.parametrize(
('path', 'base_names', 'is_package', 'names'), [
('/foo/bar.py', ('foo',), False, ('foo', 'bar')),
('/foo/bar.py', ('foo', 'baz'), False, ('foo', 'baz', 'bar')),
('/foo/__init__.py', ('foo',), True, ('foo',)),
('/__init__.py', ('foo',), True, ('foo',)),
('/foo/bar/__init__.py', ('foo',), True, ('foo',)),
('/foo/bar/__init__.py', ('foo', 'bar'), True, ('foo', 'bar')),
]
)
def test_load_module_from_path(evaluator, path, base_names, is_package, names):
m = imports._load_module_from_path(evaluator, path, base_names, '')
assert m.is_package == is_package
assert m.string_names == names
@pytest.mark.parametrize(
'path', ('api/whatever/test_this.py', 'api/whatever/file'))
@pytest.mark.parametrize('empty_sys_path', (False, True))