mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-11 00:01:54 +08:00
WIP import improvement, getting rid of bad old code
This commit is contained in:
@@ -81,32 +81,30 @@ def find_module_py33(string, path=None, loader=None, full_name=None, is_global_s
|
|||||||
if loader is None:
|
if loader is None:
|
||||||
raise ImportError("Couldn't find a loader for {}".format(string))
|
raise ImportError("Couldn't find a loader for {}".format(string))
|
||||||
|
|
||||||
try:
|
is_package = loader.is_package(string)
|
||||||
is_package = loader.is_package(string)
|
if is_package:
|
||||||
if is_package:
|
if hasattr(loader, 'path'):
|
||||||
if hasattr(loader, 'path'):
|
module_path = os.path.dirname(loader.path)
|
||||||
module_path = os.path.dirname(loader.path)
|
|
||||||
else:
|
|
||||||
# At least zipimporter does not have path attribute
|
|
||||||
module_path = os.path.dirname(loader.get_filename(string))
|
|
||||||
if hasattr(loader, 'archive'):
|
|
||||||
module_file = DummyFile(loader, string)
|
|
||||||
else:
|
|
||||||
module_file = None
|
|
||||||
else:
|
else:
|
||||||
|
# At least zipimporter does not have path attribute
|
||||||
|
module_path = os.path.dirname(loader.get_filename(string))
|
||||||
|
if hasattr(loader, 'archive'):
|
||||||
|
module_file = DummyFile(loader, string)
|
||||||
|
else:
|
||||||
|
module_file = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
module_path = loader.get_filename(string)
|
module_path = loader.get_filename(string)
|
||||||
module_file = DummyFile(loader, string)
|
module_file = DummyFile(loader, string)
|
||||||
except AttributeError:
|
|
||||||
# ExtensionLoader has not attribute get_filename, instead it has a
|
|
||||||
# path attribute that we can use to retrieve the module path
|
|
||||||
try:
|
|
||||||
module_path = loader.path
|
|
||||||
module_file = DummyFile(loader, string)
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
module_path = string
|
# ExtensionLoader has not attribute get_filename, instead it has a
|
||||||
module_file = None
|
# path attribute that we can use to retrieve the module path
|
||||||
finally:
|
try:
|
||||||
is_package = False
|
module_path = loader.path
|
||||||
|
module_file = DummyFile(loader, string)
|
||||||
|
except AttributeError:
|
||||||
|
module_path = string
|
||||||
|
module_file = None
|
||||||
|
|
||||||
if hasattr(loader, 'archive'):
|
if hasattr(loader, 'archive'):
|
||||||
module_path = loader.archive
|
module_path = loader.archive
|
||||||
|
|||||||
@@ -150,15 +150,21 @@ class Script(object):
|
|||||||
@cache.memoize_method
|
@cache.memoize_method
|
||||||
def _get_module(self):
|
def _get_module(self):
|
||||||
names = ('__main__',)
|
names = ('__main__',)
|
||||||
|
is_package = False
|
||||||
if self.path is not None:
|
if self.path is not None:
|
||||||
import_names = transform_path_to_dotted(self._evaluator.get_sys_path(), self.path)
|
import_names, is_p = transform_path_to_dotted(
|
||||||
|
self._evaluator.get_sys_path(),
|
||||||
|
self.path
|
||||||
|
)
|
||||||
if import_names is not None:
|
if import_names is not None:
|
||||||
names = import_names
|
names = import_names
|
||||||
|
is_package = is_p
|
||||||
|
|
||||||
module = ModuleContext(
|
module = ModuleContext(
|
||||||
self._evaluator, self._module_node, cast_path(self.path),
|
self._evaluator, self._module_node, cast_path(self.path),
|
||||||
string_names=names,
|
string_names=names,
|
||||||
code_lines=self._code_lines,
|
code_lines=self._code_lines,
|
||||||
|
is_package=is_package,
|
||||||
)
|
)
|
||||||
self._evaluator.module_cache.add(names, ContextSet([module]))
|
self._evaluator.module_cache.add(names, ContextSet([module]))
|
||||||
return module
|
return module
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class NamespaceObject(object):
|
|||||||
|
|
||||||
|
|
||||||
class MixedModuleContext(Context):
|
class MixedModuleContext(Context):
|
||||||
|
# TODO use ContextWrapper!
|
||||||
type = 'mixed_module'
|
type = 'mixed_module'
|
||||||
|
|
||||||
def __init__(self, evaluator, tree_module, namespaces, path, code_lines):
|
def __init__(self, evaluator, tree_module, namespaces, path, code_lines):
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ def _create(evaluator, access_handle, parent_context, *args):
|
|||||||
path=path,
|
path=path,
|
||||||
string_names=string_names,
|
string_names=string_names,
|
||||||
code_lines=code_lines,
|
code_lines=code_lines,
|
||||||
|
is_package=hasattr(compiled_object, 'py__path__'),
|
||||||
)
|
)
|
||||||
if name is not None:
|
if name is not None:
|
||||||
evaluator.module_cache.add(string_names, ContextSet([module_context]))
|
evaluator.module_cache.add(string_names, ContextSet([module_context]))
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ class ModuleContext(ModuleMixin, TreeContext):
|
|||||||
api_type = u'module'
|
api_type = u'module'
|
||||||
parent_context = None
|
parent_context = None
|
||||||
|
|
||||||
def __init__(self, evaluator, module_node, path, string_names, code_lines):
|
def __init__(self, evaluator, module_node, path, string_names, code_lines, is_package=False):
|
||||||
super(ModuleContext, self).__init__(
|
super(ModuleContext, self).__init__(
|
||||||
evaluator,
|
evaluator,
|
||||||
parent_context=None,
|
parent_context=None,
|
||||||
@@ -148,19 +148,7 @@ class ModuleContext(ModuleMixin, TreeContext):
|
|||||||
self._path = path
|
self._path = path
|
||||||
self.string_names = string_names
|
self.string_names = string_names
|
||||||
self.code_lines = code_lines
|
self.code_lines = code_lines
|
||||||
|
self.is_package = is_package
|
||||||
def _get_init_directory(self):
|
|
||||||
"""
|
|
||||||
:return: The path to the directory of a package. None in case it's not
|
|
||||||
a package.
|
|
||||||
"""
|
|
||||||
for suffix in all_suffixes() + ['.pyi']:
|
|
||||||
ending = '__init__' + suffix
|
|
||||||
py__file__ = self.py__file__()
|
|
||||||
if py__file__ is not None and py__file__.endswith(ending):
|
|
||||||
# Remove the ending, including the separator.
|
|
||||||
return self.py__file__()[:-len(ending) - 1]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def py__name__(self):
|
def py__name__(self):
|
||||||
if self.string_names is None:
|
if self.string_names is None:
|
||||||
@@ -176,39 +164,36 @@ class ModuleContext(ModuleMixin, TreeContext):
|
|||||||
|
|
||||||
return os.path.abspath(self._path)
|
return os.path.abspath(self._path)
|
||||||
|
|
||||||
def is_package(self):
|
|
||||||
return self._get_init_directory() is not None
|
|
||||||
|
|
||||||
def py__package__(self):
|
def py__package__(self):
|
||||||
if self._get_init_directory() is None:
|
if self.is_package:
|
||||||
return re.sub(r'\.?[^.]+$', '', self.py__name__()).split('.')
|
|
||||||
else:
|
|
||||||
return self.string_names
|
return self.string_names
|
||||||
|
return self.string_names[:-1]
|
||||||
|
|
||||||
def _py__path__(self):
|
def _py__path__(self):
|
||||||
search_path = self.evaluator.get_sys_path()
|
# A namespace package is typically auto generated and ~10 lines long.
|
||||||
init_path = self.py__file__()
|
first_few_lines = ''.join(self.code_lines[:50])
|
||||||
if os.path.basename(init_path) in ('__init__.py', '__init__.pyi'):
|
# these are strings that need to be used for namespace packages,
|
||||||
with open(init_path, 'rb') as f:
|
# the first one is ``pkgutil``, the second ``pkg_resources``.
|
||||||
content = python_bytes_to_unicode(f.read(), errors='replace')
|
options = ('declare_namespace(__name__)', 'extend_path(__path__')
|
||||||
# these are strings that need to be used for namespace packages,
|
if options[0] in first_few_lines or options[1] in first_few_lines:
|
||||||
# the first one is ``pkgutil``, the second ``pkg_resources``.
|
# It is a namespace, now try to find the rest of the
|
||||||
options = ('declare_namespace(__name__)', 'extend_path(__path__')
|
# modules on sys_path or whatever the search_path is.
|
||||||
if options[0] in content or options[1] in content:
|
paths = set()
|
||||||
# It is a namespace, now try to find the rest of the
|
for s in self.evaluator.get_sys_path():
|
||||||
# modules on sys_path or whatever the search_path is.
|
other = os.path.join(s, self.name.string_name)
|
||||||
paths = set()
|
if os.path.isdir(other):
|
||||||
for s in search_path:
|
paths.add(other)
|
||||||
other = os.path.join(s, self.name.string_name)
|
if paths:
|
||||||
if os.path.isdir(other):
|
return list(paths)
|
||||||
paths.add(other)
|
# Nested namespace packages will not be supported. Nobody ever
|
||||||
if paths:
|
# asked for it and in Python 3 they are there without using all the
|
||||||
return list(paths)
|
# crap above.
|
||||||
# TODO I'm not sure if this is how nested namespace
|
|
||||||
# packages work. The tests are not really good enough to
|
# Default to the of this file.
|
||||||
# show that.
|
file = self.py__file__()
|
||||||
# Default to this.
|
if file is None:
|
||||||
return [self._get_init_directory()]
|
return None
|
||||||
|
return os.path.dirname(file)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def py__path__(self):
|
def py__path__(self):
|
||||||
@@ -222,7 +207,7 @@ class ModuleContext(ModuleMixin, TreeContext):
|
|||||||
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.
|
||||||
"""
|
"""
|
||||||
if self.is_package():
|
if self.is_package:
|
||||||
return self._py__path__
|
return self._py__path__
|
||||||
else:
|
else:
|
||||||
raise AttributeError('Only packages have __path__ attributes.')
|
raise AttributeError('Only packages have __path__ attributes.')
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ def import_module_decorator(func):
|
|||||||
if len(import_names) == 1:
|
if len(import_names) == 1:
|
||||||
map_ = _cache_stub_file_map(evaluator.grammar.version_info)
|
map_ = _cache_stub_file_map(evaluator.grammar.version_info)
|
||||||
elif isinstance(parent_module_context, StubModuleContext):
|
elif isinstance(parent_module_context, StubModuleContext):
|
||||||
if not parent_module_context.stub_context.is_package():
|
if not parent_module_context.stub_context.is_package:
|
||||||
# Only if it's a package (= a folder) something can be
|
# Only if it's a package (= a folder) something can be
|
||||||
# imported.
|
# imported.
|
||||||
return context_set
|
return context_set
|
||||||
@@ -161,6 +161,7 @@ def import_module_decorator(func):
|
|||||||
module_cls = TypingModuleWrapper
|
module_cls = TypingModuleWrapper
|
||||||
else:
|
else:
|
||||||
module_cls = StubOnlyModuleContext
|
module_cls = StubOnlyModuleContext
|
||||||
|
file_name = os.path.basename(path)
|
||||||
stub_module_context = module_cls(
|
stub_module_context = module_cls(
|
||||||
context_set, evaluator, stub_module_node,
|
context_set, evaluator, stub_module_node,
|
||||||
path=path,
|
path=path,
|
||||||
@@ -168,6 +169,7 @@ def import_module_decorator(func):
|
|||||||
# The code was loaded with latest_grammar, so use
|
# The code was loaded with latest_grammar, so use
|
||||||
# that.
|
# that.
|
||||||
code_lines=get_cached_code_lines(evaluator.latest_grammar, path),
|
code_lines=get_cached_code_lines(evaluator.latest_grammar, path),
|
||||||
|
is_package=file_name == '__init__.pyi',
|
||||||
)
|
)
|
||||||
modules = _merge_modules(context_set, stub_module_context)
|
modules = _merge_modules(context_set, stub_module_context)
|
||||||
return ContextSet(modules)
|
return ContextSet(modules)
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ class Importer(object):
|
|||||||
if level:
|
if level:
|
||||||
base = module_context.py__package__()
|
base = module_context.py__package__()
|
||||||
if base == [''] or base == ['__main__']:
|
if base == [''] or base == ['__main__']:
|
||||||
|
raise NotImplementedError(module_context.py__package__())
|
||||||
base = []
|
base = []
|
||||||
# We need to care for two cases, the first one is if it's a valid
|
# We need to care for two cases, the first one is if it's a valid
|
||||||
# Python import. This import has a properly defined module name
|
# Python import. This import has a properly defined module name
|
||||||
@@ -487,6 +488,7 @@ def import_module(evaluator, import_names, parent_module_context, sys_path):
|
|||||||
evaluator, module_path, code, sys_path,
|
evaluator, module_path, code, sys_path,
|
||||||
import_names=import_names,
|
import_names=import_names,
|
||||||
safe_module_name=True,
|
safe_module_name=True,
|
||||||
|
is_package=is_pkg,
|
||||||
)
|
)
|
||||||
|
|
||||||
if parent_module_context is None:
|
if parent_module_context is None:
|
||||||
@@ -497,7 +499,7 @@ def import_module(evaluator, import_names, parent_module_context, sys_path):
|
|||||||
|
|
||||||
|
|
||||||
def _load_module(evaluator, path=None, code=None, sys_path=None,
|
def _load_module(evaluator, path=None, code=None, sys_path=None,
|
||||||
import_names=None, safe_module_name=False):
|
import_names=None, safe_module_name=False, is_package=False):
|
||||||
if import_names is None:
|
if import_names is None:
|
||||||
dotted_name = None
|
dotted_name = None
|
||||||
else:
|
else:
|
||||||
@@ -530,6 +532,7 @@ def _load_module(evaluator, path=None, code=None, sys_path=None,
|
|||||||
path=path,
|
path=path,
|
||||||
string_names=import_names,
|
string_names=import_names,
|
||||||
code_lines=get_cached_code_lines(evaluator.grammar, path),
|
code_lines=get_cached_code_lines(evaluator.grammar, path),
|
||||||
|
is_package=is_package,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
assert dotted_name is not None
|
assert dotted_name is not None
|
||||||
@@ -561,19 +564,23 @@ def get_modules_containing_name(evaluator, modules, name):
|
|||||||
code = python_bytes_to_unicode(f.read(), errors='replace')
|
code = python_bytes_to_unicode(f.read(), errors='replace')
|
||||||
if name in code:
|
if name in code:
|
||||||
e_sys_path = evaluator.get_sys_path()
|
e_sys_path = evaluator.get_sys_path()
|
||||||
module_name = os.path.basename(path)
|
|
||||||
if module_name.endswith('.py'):
|
|
||||||
module_name = module_name[:-3]
|
|
||||||
|
|
||||||
if base_names:
|
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,)
|
import_names = base_names + (module_name,)
|
||||||
else:
|
else:
|
||||||
import_names = sys_path.transform_path_to_dotted(e_sys_path, path)
|
import_names, is_package = sys_path.transform_path_to_dotted(e_sys_path, path)
|
||||||
|
|
||||||
module = _load_module(
|
module = _load_module(
|
||||||
evaluator, path, code,
|
evaluator, path, code,
|
||||||
sys_path=e_sys_path,
|
sys_path=e_sys_path,
|
||||||
import_names=import_names,
|
import_names=import_names,
|
||||||
|
is_package=is_package,
|
||||||
)
|
)
|
||||||
evaluator.module_cache.add(import_names, ContextSet([module]))
|
evaluator.module_cache.add(import_names, ContextSet([module]))
|
||||||
return module
|
return module
|
||||||
@@ -590,10 +597,7 @@ def get_modules_containing_name(evaluator, modules, name):
|
|||||||
if path is not None:
|
if path is not None:
|
||||||
if path not in used_mod_paths:
|
if path not in used_mod_paths:
|
||||||
used_mod_paths.add(path)
|
used_mod_paths.add(path)
|
||||||
string_names = m.string_names
|
path_with_names_to_be_checked.append((path, m.py__package__()))
|
||||||
if not m.is_package() and string_names is not None:
|
|
||||||
string_names = string_names[:-1]
|
|
||||||
path_with_names_to_be_checked.append((path, string_names))
|
|
||||||
yield m
|
yield m
|
||||||
|
|
||||||
if not settings.dynamic_params_for_other_modules:
|
if not settings.dynamic_params_for_other_modules:
|
||||||
|
|||||||
@@ -197,25 +197,33 @@ def _get_buildout_script_paths(search_path):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
def remove_python_path_suffix(path):
|
||||||
|
for suffix in all_suffixes():
|
||||||
|
if path.endswith(suffix):
|
||||||
|
path = path[:-len(suffix)]
|
||||||
|
break
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
def transform_path_to_dotted(sys_path, module_path):
|
def transform_path_to_dotted(sys_path, module_path):
|
||||||
"""
|
"""
|
||||||
Returns the dotted path inside a sys.path as a list of names. e.g.
|
Returns the dotted path inside a sys.path as a list of names. e.g.
|
||||||
|
|
||||||
>>> transform_path_to_dotted(["/foo"], '/foo/bar/baz.py')
|
>>> transform_path_to_dotted(["/foo"], '/foo/bar/baz.py')
|
||||||
('bar', 'baz')
|
('bar', 'baz'), False
|
||||||
|
|
||||||
Returns None if the path doesn't really resolve to anything.
|
Returns (None, False) if the path doesn't really resolve to anything.
|
||||||
|
The second return part is if it is a package.
|
||||||
"""
|
"""
|
||||||
# First remove the suffix.
|
# First remove the suffix.
|
||||||
for suffix in all_suffixes():
|
module_path = remove_python_path_suffix(module_path)
|
||||||
if module_path.endswith(suffix):
|
|
||||||
module_path = module_path[:-len(suffix)]
|
|
||||||
break
|
|
||||||
# Once the suffix was removed we are using the files as we know them. This
|
# Once the suffix was removed we are using the files as we know them. This
|
||||||
# means that if someone uses an ending like .vim for a Python file, .vim
|
# means that if someone uses an ending like .vim for a Python file, .vim
|
||||||
# will be part of the returned dotted part.
|
# will be part of the returned dotted part.
|
||||||
|
|
||||||
if module_path.endswith(os.path.sep + '__init__'):
|
is_package = module_path.endswith(os.path.sep + '__init__')
|
||||||
|
if is_package:
|
||||||
# -1 to remove the separator
|
# -1 to remove the separator
|
||||||
module_path = module_path[:-len('__init__') - 1]
|
module_path = module_path[:-len('__init__') - 1]
|
||||||
|
|
||||||
@@ -231,6 +239,6 @@ def transform_path_to_dotted(sys_path, module_path):
|
|||||||
split = rest.split(os.path.sep)
|
split = rest.split(os.path.sep)
|
||||||
for string in split:
|
for string in split:
|
||||||
if not string:
|
if not string:
|
||||||
return None
|
return None, False
|
||||||
return tuple(split)
|
return tuple(split), is_package
|
||||||
return None
|
return None, False
|
||||||
|
|||||||
@@ -36,9 +36,11 @@ def test_find_module_not_package():
|
|||||||
assert is_package is False
|
assert is_package is False
|
||||||
|
|
||||||
|
|
||||||
|
pkg_zip_path = os.path.join(os.path.dirname(__file__), 'zipped_imports/pkg.zip')
|
||||||
|
|
||||||
|
|
||||||
def test_find_module_package_zipped(Script, evaluator, environment):
|
def test_find_module_package_zipped(Script, evaluator, environment):
|
||||||
path = os.path.join(os.path.dirname(__file__), 'zipped_imports/pkg.zip')
|
sys_path = environment.get_sys_path() + [pkg_zip_path]
|
||||||
sys_path = environment.get_sys_path() + [path]
|
|
||||||
script = Script('import pkg; pkg.mod', sys_path=sys_path)
|
script = Script('import pkg; pkg.mod', sys_path=sys_path)
|
||||||
assert len(script.completions()) == 1
|
assert len(script.completions()) == 1
|
||||||
|
|
||||||
@@ -52,6 +54,16 @@ def test_find_module_package_zipped(Script, evaluator, environment):
|
|||||||
assert is_package is True
|
assert is_package is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_correct_zip_package_behavior(Script, evaluator, environment):
|
||||||
|
sys_path = environment.get_sys_path() + [pkg_zip_path]
|
||||||
|
pkg, = Script('import pkg', sys_path=sys_path).goto_definitions()
|
||||||
|
context, = pkg._name.infer()
|
||||||
|
assert context.py__file__() == pkg_zip_path
|
||||||
|
assert context.is_package is True
|
||||||
|
assert context.py__package__() == ('pkg',)
|
||||||
|
assert context.py__path__() == [pkg_zip_path]
|
||||||
|
|
||||||
|
|
||||||
def test_find_module_not_package_zipped(Script, evaluator, environment):
|
def test_find_module_not_package_zipped(Script, evaluator, environment):
|
||||||
path = os.path.join(os.path.dirname(__file__), 'zipped_imports/not_pkg.zip')
|
path = os.path.join(os.path.dirname(__file__), 'zipped_imports/not_pkg.zip')
|
||||||
sys_path = environment.get_sys_path() + [path]
|
sys_path = environment.get_sys_path() + [path]
|
||||||
|
|||||||
@@ -67,30 +67,31 @@ _s = ['/a', '/b', '/c/d/']
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'sys_path_, module_path, result', [
|
'sys_path_, module_path, expected, is_package', [
|
||||||
(_s, '/a/b', ('b',)),
|
(_s, '/a/b', ('b',), False),
|
||||||
(_s, '/a/b/c', ('b', 'c')),
|
(_s, '/a/b/c', ('b', 'c'), False),
|
||||||
(_s, '/a/b.py', ('b',)),
|
(_s, '/a/b.py', ('b',), False),
|
||||||
(_s, '/a/b/c.py', ('b', 'c')),
|
(_s, '/a/b/c.py', ('b', 'c'), False),
|
||||||
(_s, '/x/b.py', None),
|
(_s, '/x/b.py', None, False),
|
||||||
(_s, '/c/d/x.py', ('x',)),
|
(_s, '/c/d/x.py', ('x',), False),
|
||||||
(_s, '/c/d/x.py', ('x',)),
|
(_s, '/c/d/x.py', ('x',), False),
|
||||||
(_s, '/c/d/x/y.py', ('x', 'y')),
|
(_s, '/c/d/x/y.py', ('x', 'y'), False),
|
||||||
# If dots are in there they also resolve. These are obviously illegal
|
# If dots are in there they also resolve. These are obviously illegal
|
||||||
# in Python, but Jedi can handle them. Give the user a bit more freedom
|
# in Python, but Jedi can handle them. Give the user a bit more freedom
|
||||||
# that he will have to correct eventually.
|
# that he will have to correct eventually.
|
||||||
(_s, '/a/b.c.py', ('b.c',)),
|
(_s, '/a/b.c.py', ('b.c',), False),
|
||||||
(_s, '/a/b.d/foo.bar.py', ('b.d', 'foo.bar')),
|
(_s, '/a/b.d/foo.bar.py', ('b.d', 'foo.bar'), False),
|
||||||
|
|
||||||
(_s, '/a/.py', None),
|
(_s, '/a/.py', None, False),
|
||||||
(_s, '/a/c/.py', None),
|
(_s, '/a/c/.py', None, False),
|
||||||
|
|
||||||
(['/foo'], '/foo/bar/__init__.py', ('bar',)),
|
(['/foo'], '/foo/bar/__init__.py', ('bar',), True),
|
||||||
(['/foo'], '/foo/bar/baz/__init__.py', ('bar', 'baz')),
|
(['/foo'], '/foo/bar/baz/__init__.py', ('bar', 'baz'), True),
|
||||||
(['/foo'], '/foo/bar.so', ('bar',)),
|
(['/foo'], '/foo/bar.so', ('bar',), False),
|
||||||
(['/foo'], '/foo/bar/__init__.so', ('bar',)),
|
(['/foo'], '/foo/bar/__init__.so', ('bar',), True),
|
||||||
(['/foo'], '/x/bar.py', None),
|
(['/foo'], '/x/bar.py', None, False),
|
||||||
(['/foo'], '/foo/bar.xyz', ('bar.xyz',)),
|
(['/foo'], '/foo/bar.xyz', ('bar.xyz',), False),
|
||||||
])
|
])
|
||||||
def test_calculate_dotted_from_path(sys_path_, module_path, result):
|
def test_calculate_dotted_from_path(sys_path_, module_path, expected, is_package):
|
||||||
assert sys_path.transform_path_to_dotted(sys_path_, module_path) == result
|
assert sys_path.transform_path_to_dotted(sys_path_, module_path) \
|
||||||
|
== (expected, is_package)
|
||||||
|
|||||||
Reference in New Issue
Block a user