forked from VimPlug/jedi
Fix issues with the os module.
Using a try/finally assures that the recursion checkers work the right way.
This commit is contained in:
@@ -179,52 +179,54 @@ class ImportWrapper(pr.Base):
|
|||||||
# check recursion
|
# check recursion
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if self.import_path:
|
try:
|
||||||
try:
|
if self.import_path:
|
||||||
module, rest = self._importer.follow_file_system()
|
try:
|
||||||
except ModuleNotFound as e:
|
module, rest = self._importer.follow_file_system()
|
||||||
analysis.add(self._evaluator, 'import-error', e.name_part)
|
except ModuleNotFound as e:
|
||||||
return []
|
analysis.add(self._evaluator, 'import-error', e.name_part)
|
||||||
|
return []
|
||||||
|
|
||||||
if self.import_stmt.is_nested() and not self.nested_resolve:
|
if self.import_stmt.is_nested() and not self.nested_resolve:
|
||||||
scopes = [NestedImportModule(module, self.import_stmt)]
|
scopes = [NestedImportModule(module, self.import_stmt)]
|
||||||
else:
|
|
||||||
scopes = [module]
|
|
||||||
|
|
||||||
star_imports = remove_star_imports(self._evaluator, module)
|
|
||||||
if star_imports:
|
|
||||||
scopes = [StarImportModule(scopes[0], star_imports)]
|
|
||||||
|
|
||||||
# goto only accepts Names or NameParts
|
|
||||||
if is_goto and not rest:
|
|
||||||
scopes = [s.name.names[-1] for s in scopes]
|
|
||||||
|
|
||||||
# follow the rest of the import (not FS -> classes, functions)
|
|
||||||
if len(rest) > 1 or rest and self.is_like_search:
|
|
||||||
scopes = []
|
|
||||||
if ('os', 'path') == self.import_path[:2] \
|
|
||||||
and not self._is_relative_import():
|
|
||||||
# This is a huge exception, we follow a nested import
|
|
||||||
# ``os.path``, because it's a very important one in Python
|
|
||||||
# that is being achieved by messing with ``sys.modules`` in
|
|
||||||
# ``os``.
|
|
||||||
scopes = self._evaluator.follow_path(iter(rest), [module], module)
|
|
||||||
elif rest:
|
|
||||||
if is_goto:
|
|
||||||
scopes = list(chain.from_iterable(
|
|
||||||
self._evaluator.find_types(s, rest[0], is_goto=True)
|
|
||||||
for s in scopes))
|
|
||||||
else:
|
else:
|
||||||
scopes = list(chain.from_iterable(
|
scopes = [module]
|
||||||
self._evaluator.follow_path(iter(rest), [s], s)
|
|
||||||
for s in scopes))
|
star_imports = remove_star_imports(self._evaluator, module)
|
||||||
else:
|
if star_imports:
|
||||||
scopes = [ImportWrapper.GlobalNamespace]
|
scopes = [StarImportModule(scopes[0], star_imports)]
|
||||||
debug.dbg('after import: %s', scopes)
|
|
||||||
if not scopes:
|
# goto only accepts Names or NameParts
|
||||||
analysis.add(self._evaluator, 'import-error',
|
if is_goto and not rest:
|
||||||
self._importer.import_path[-1])
|
scopes = [s.name.names[-1] for s in scopes]
|
||||||
self._evaluator.recursion_detector.pop_stmt()
|
|
||||||
|
# follow the rest of the import (not FS -> classes, functions)
|
||||||
|
if len(rest) > 1 or rest and self.is_like_search:
|
||||||
|
scopes = []
|
||||||
|
if ('os', 'path') == self.import_path[:2] \
|
||||||
|
and not self._is_relative_import():
|
||||||
|
# This is a huge exception, we follow a nested import
|
||||||
|
# ``os.path``, because it's a very important one in Python
|
||||||
|
# that is being achieved by messing with ``sys.modules`` in
|
||||||
|
# ``os``.
|
||||||
|
scopes = self._evaluator.follow_path(iter(rest), [module], module)
|
||||||
|
elif rest:
|
||||||
|
if is_goto:
|
||||||
|
scopes = list(chain.from_iterable(
|
||||||
|
self._evaluator.find_types(s, rest[0], is_goto=True)
|
||||||
|
for s in scopes))
|
||||||
|
else:
|
||||||
|
scopes = list(chain.from_iterable(
|
||||||
|
self._evaluator.follow_path(iter(rest), [s], s)
|
||||||
|
for s in scopes))
|
||||||
|
else:
|
||||||
|
scopes = [ImportWrapper.GlobalNamespace]
|
||||||
|
debug.dbg('after import: %s', scopes)
|
||||||
|
if not scopes:
|
||||||
|
analysis.add(self._evaluator, 'import-error',
|
||||||
|
self._importer.import_path[-1])
|
||||||
|
finally:
|
||||||
|
self._evaluator.recursion_detector.pop_stmt()
|
||||||
return scopes
|
return scopes
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -686,6 +686,14 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)):
|
|||||||
imp = helpers.FakeImport(name, self, level=1)
|
imp = helpers.FakeImport(name, self, level=1)
|
||||||
name.parent = imp
|
name.parent = imp
|
||||||
names.append(name)
|
names.append(name)
|
||||||
|
|
||||||
|
# TODO add something like this in the future, its cleaner than the
|
||||||
|
# import hacks.
|
||||||
|
# ``os.path`` is a hardcoded exception, because it's a
|
||||||
|
# ``sys.modules`` modification.
|
||||||
|
#if str(self.name) == 'os':
|
||||||
|
# names.append(helpers.FakeName('path', parent=self))
|
||||||
|
|
||||||
return names
|
return names
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
|||||||
@@ -267,3 +267,14 @@ class TestGotoAssignments(TestCase):
|
|||||||
n = nms[1].goto_assignments()[0]
|
n = nms[1].goto_assignments()[0]
|
||||||
assert n.name == 'load'
|
assert n.name == 'load'
|
||||||
assert n.type == 'function'
|
assert n.type == 'function'
|
||||||
|
|
||||||
|
nms = names('import os; os.path', references=True)
|
||||||
|
assert nms[0].name == 'os'
|
||||||
|
assert nms[0].type == 'import'
|
||||||
|
n = nms[0].goto_assignments()[0]
|
||||||
|
assert n.name == 'os'
|
||||||
|
assert n.type == 'module'
|
||||||
|
|
||||||
|
n = nms[2].goto_assignments()[0]
|
||||||
|
assert n.name == 'path'
|
||||||
|
assert n.type == 'import'
|
||||||
|
|||||||
Reference in New Issue
Block a user