diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 34c968d8..b9070493 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -100,9 +100,11 @@ class Script(object): encoding = source_encoding self._orig_path = path - self.path = None if path is None else os.path.abspath(path) + # An empty path (also empty string) should always result in no path. + self.path = os.path.abspath(path) if path else None if source is None: + # TODO add a better warning than the traceback! with open(path) as f: source = f.read() @@ -131,8 +133,8 @@ class Script(object): def _get_module(self): cache.invalidate_star_import_cache(self._path) - parser = FastParser(self._grammar, self._source, self._path) - save_parser(self._path, parser, pickling=False) + parser = FastParser(self._grammar, self._source, self.path) + save_parser(self.path, parser, pickling=False) module = self._evaluator.wrap(parser.module) imports.add_module(self._evaluator, unicode(module.name), module) diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index 1cbdaf92..77e13500 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -201,20 +201,21 @@ class Importer(object): base = [] if level > len(base): path = module.py__file__() - import_path = list(import_path) - for i in range(level): - path = os.path.dirname(path) - dir_name = os.path.basename(path) - # This is not the proper way to do relative imports. However, since - # Jedi cannot be sure about the entry point, we just calculate an - # absolute path here. - if dir_name: - import_path.insert(0, dir_name) - else: - _add_error(self._evaluator, import_path[-1]) - import_path = [] - # TODO add import error. - debug.warning('Attempted relative import beyond top-level package.') + if path is not None: + import_path = list(import_path) + for i in range(level): + path = os.path.dirname(path) + dir_name = os.path.basename(path) + # This is not the proper way to do relative imports. However, since + # Jedi cannot be sure about the entry point, we just calculate an + # absolute path here. + if dir_name: + import_path.insert(0, dir_name) + else: + _add_error(self._evaluator, import_path[-1]) + import_path = [] + # TODO add import error. + debug.warning('Attempted relative import beyond top-level package.') else: # Here we basically rewrite the level to 0. import_path = tuple(base) + import_path diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index ad04ff41..cd572ede 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -852,7 +852,8 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, tree.Module, Wrapper)): def _get_init_directory(self): for suffix, _, _ in imp.get_suffixes(): ending = '__init__' + suffix - if self.py__file__().endswith(ending): + 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 diff --git a/test/test_integration_import.py b/test/test_integration_import.py index 6b5ad73a..d961666c 100644 --- a/test/test_integration_import.py +++ b/test/test_integration_import.py @@ -18,17 +18,17 @@ def test_goto_definition_on_import(): def test_complete_on_empty_import(): assert Script("from datetime import").completions()[0].name == 'import' # should just list the files in the directory - assert 10 < len(Script("from .", path='').completions()) < 30 + assert 10 < len(Script("from .", path='whatever.py').completions()) < 30 # Global import - assert len(Script("from . import", 1, 5, '').completions()) > 30 + assert len(Script("from . import", 1, 5, 'whatever.py').completions()) > 30 # relative import - assert 10 < len(Script("from . import", 1, 6, '').completions()) < 30 + assert 10 < len(Script("from . import", 1, 6, 'whatever.py').completions()) < 30 # Global import - assert len(Script("from . import classes", 1, 5, '').completions()) > 30 + assert len(Script("from . import classes", 1, 5, 'whatever.py').completions()) > 30 # relative import - assert 10 < len(Script("from . import classes", 1, 6, '').completions()) < 30 + assert 10 < len(Script("from . import classes", 1, 6, 'whatever.py').completions()) < 30 wanted = set(['ImportError', 'import', 'ImportWarning']) assert set([c.name for c in Script("import").completions()]) == wanted