forked from VimPlug/jedi
Add absolute import detection
This commit is contained in:
@@ -294,6 +294,27 @@ class Scope(Simple, IsScope):
|
||||
if p:
|
||||
return p
|
||||
|
||||
@property
|
||||
def absolute_imports(self):
|
||||
"""
|
||||
Checks if imports in this scope are absolute.
|
||||
|
||||
In Python 3, this is always true. In Python 2, this is true if there
|
||||
is a ``absolute_import`` ``__future__`` import.
|
||||
|
||||
The result of this property is cached; the first time it is called on
|
||||
Python 2 will cause it to walk through all the imports in the parse
|
||||
tree.
|
||||
"""
|
||||
if self._absolute_imports is not None:
|
||||
return self._absolute_imports
|
||||
|
||||
has_import = any(_enables_absolute_import(i) for i in self.imports)
|
||||
self._absolute_imports = has_import
|
||||
return has_import
|
||||
|
||||
_absolute_imports = True if is_py3k else None
|
||||
|
||||
def __repr__(self):
|
||||
try:
|
||||
name = self.path
|
||||
@@ -306,6 +327,13 @@ class Scope(Simple, IsScope):
|
||||
return "<%s: %s@%s-%s>" % (type(self).__name__, name,
|
||||
self.start_pos[0], self.end_pos[0])
|
||||
|
||||
def _enables_absolute_import(imp):
|
||||
"""
|
||||
Checks if the import is a ``__future__`` import that enables the
|
||||
``absolute_import`` feature.
|
||||
"""
|
||||
namespace, feature = imp.from_ns.names[0], imp.namespace.names[0]
|
||||
return namespace == "__future__" and feature == "absolute_import"
|
||||
|
||||
class Module(IsScope):
|
||||
""" For isinstance checks. fast_parser.Module also inherits from this. """
|
||||
|
||||
@@ -6,6 +6,7 @@ else:
|
||||
import os
|
||||
from os.path import abspath, dirname
|
||||
import functools
|
||||
import pytest
|
||||
|
||||
import jedi
|
||||
|
||||
@@ -60,3 +61,6 @@ def cwd_at(path):
|
||||
os.chdir(oldcwd)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
py3_only = pytest.mark.skipif("not is_py3k")
|
||||
py2_only = pytest.mark.skipif("is_py3k")
|
||||
|
||||
27
test/test_absolute_import.py
Normal file
27
test/test_absolute_import.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from jedi.parsing import Parser
|
||||
from jedi._compatibility import is_py3k; is_py3k # shut up pyflakes
|
||||
from . import base
|
||||
|
||||
@base.py3_only
|
||||
def test_py3k_imports_are_always_absolute():
|
||||
"""
|
||||
By default, imports in Python 3 are absolute.
|
||||
"""
|
||||
parser = Parser("1", "test.py")
|
||||
assert parser.scope.absolute_imports
|
||||
|
||||
@base.py2_only
|
||||
def test_py2_imports_are_not_always_absolute():
|
||||
"""
|
||||
By default, imports in Python 2 are not absolute.
|
||||
"""
|
||||
parser = Parser("1", "test.py")
|
||||
assert not parser.scope.absolute_imports
|
||||
|
||||
def test_imports_are_absolute_in_modules_with_future_import():
|
||||
"""
|
||||
In any module with the ``absolute_import`` ``__future__`` import, all
|
||||
imports are absolute.
|
||||
"""
|
||||
parser = Parser("from __future__ import absolute_import", "test.py")
|
||||
assert parser.scope.absolute_imports
|
||||
Reference in New Issue
Block a user