forked from VimPlug/jedi
Start using FileIO in modules
This commit is contained in:
@@ -21,6 +21,7 @@ from jedi.parser_utils import get_executable_nodes
|
|||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
from jedi import cache
|
from jedi import cache
|
||||||
|
from jedi.file_io import KnownContentFileIO
|
||||||
from jedi.api import classes
|
from jedi.api import classes
|
||||||
from jedi.api import interpreter
|
from jedi.api import interpreter
|
||||||
from jedi.api import helpers
|
from jedi.api import helpers
|
||||||
@@ -38,8 +39,7 @@ from jedi.evaluate.syntax_tree import tree_name_to_contexts
|
|||||||
from jedi.evaluate.context import ModuleContext
|
from jedi.evaluate.context import ModuleContext
|
||||||
from jedi.evaluate.base_context import ContextSet
|
from jedi.evaluate.base_context import ContextSet
|
||||||
from jedi.evaluate.context.iterable import unpack_tuple_to_dict
|
from jedi.evaluate.context.iterable import unpack_tuple_to_dict
|
||||||
from jedi.evaluate.gradual.conversion import try_stubs_to_actual_context_set, \
|
from jedi.evaluate.gradual.conversion import try_stub_to_actual_names
|
||||||
try_stub_to_actual_names
|
|
||||||
from jedi.evaluate.gradual.utils import load_proper_stub_module
|
from jedi.evaluate.gradual.utils import load_proper_stub_module
|
||||||
|
|
||||||
# Jedi uses lots and lots of recursion. By setting this a little bit higher, we
|
# Jedi uses lots and lots of recursion. By setting this a little bit higher, we
|
||||||
@@ -164,11 +164,12 @@ class Script(object):
|
|||||||
names = import_names
|
names = import_names
|
||||||
is_package = is_p
|
is_package = is_p
|
||||||
|
|
||||||
|
file_io = KnownContentFileIO(cast_path(self.path), self._code)
|
||||||
if self.path is not None and self.path.endswith('.pyi'):
|
if self.path is not None and self.path.endswith('.pyi'):
|
||||||
# We are in a stub file. Try to load the stub properly.
|
# We are in a stub file. Try to load the stub properly.
|
||||||
stub_module = load_proper_stub_module(
|
stub_module = load_proper_stub_module(
|
||||||
self._evaluator,
|
self._evaluator,
|
||||||
cast_path(self.path),
|
file_io,
|
||||||
names,
|
names,
|
||||||
self._module_node
|
self._module_node
|
||||||
)
|
)
|
||||||
@@ -179,14 +180,11 @@ class Script(object):
|
|||||||
names = ('__main__',)
|
names = ('__main__',)
|
||||||
|
|
||||||
module = ModuleContext(
|
module = ModuleContext(
|
||||||
self._evaluator, self._module_node, cast_path(self.path),
|
self._evaluator, self._module_node, file_io,
|
||||||
string_names=names,
|
string_names=names,
|
||||||
code_lines=self._code_lines,
|
code_lines=self._code_lines,
|
||||||
is_package=is_package,
|
is_package=is_package,
|
||||||
)
|
)
|
||||||
#module, = try_to_merge_with_stub(
|
|
||||||
# self._evaluator, None, module.string_names, ContextSet([module])
|
|
||||||
#)
|
|
||||||
if names[0] not in ('builtins', '__builtin__', 'typing'):
|
if names[0] not in ('builtins', '__builtin__', 'typing'):
|
||||||
# These modules are essential for Jedi, so don't overwrite them.
|
# These modules are essential for Jedi, so don't overwrite them.
|
||||||
self._evaluator.module_cache.add(names, ContextSet([module]))
|
self._evaluator.module_cache.add(names, ContextSet([module]))
|
||||||
@@ -469,7 +467,7 @@ class Interpreter(Script):
|
|||||||
self._evaluator,
|
self._evaluator,
|
||||||
self._module_node,
|
self._module_node,
|
||||||
self.namespaces,
|
self.namespaces,
|
||||||
path=self.path,
|
file_io=KnownContentFileIO(self.path, self._code),
|
||||||
code_lines=self._code_lines,
|
code_lines=self._code_lines,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ class MixedModuleContext(Context):
|
|||||||
# TODO use ContextWrapper!
|
# 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, file_io, code_lines):
|
||||||
self.evaluator = evaluator
|
self.evaluator = evaluator
|
||||||
self._namespaces = namespaces
|
self._namespaces = namespaces
|
||||||
|
|
||||||
self._namespace_objects = [NamespaceObject(n) for n in namespaces]
|
self._namespace_objects = [NamespaceObject(n) for n in namespaces]
|
||||||
self._module_context = ModuleContext(
|
self._module_context = ModuleContext(
|
||||||
evaluator, tree_module,
|
evaluator, tree_module,
|
||||||
path=path,
|
file_io=file_io,
|
||||||
string_names=('__main__',),
|
string_names=('__main__',),
|
||||||
code_lines=code_lines
|
code_lines=code_lines
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from jedi import settings
|
|||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.cache import underscore_memoization
|
from jedi.cache import underscore_memoization
|
||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
|
from jedi.file_io import FileIO
|
||||||
from jedi.evaluate.base_context import Context, ContextSet
|
from jedi.evaluate.base_context import Context, ContextSet
|
||||||
from jedi.evaluate.context import ModuleContext
|
from jedi.evaluate.context import ModuleContext
|
||||||
from jedi.evaluate.cache import evaluator_function_cache
|
from jedi.evaluate.cache import evaluator_function_cache
|
||||||
@@ -140,6 +141,7 @@ def _find_syntax_node_name(evaluator, access_handle):
|
|||||||
# The path might not exist or be e.g. <stdin>.
|
# The path might not exist or be e.g. <stdin>.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
file_io = FileIO(path)
|
||||||
module_node = _load_module(evaluator, path)
|
module_node = _load_module(evaluator, path)
|
||||||
|
|
||||||
if inspect.ismodule(python_object):
|
if inspect.ismodule(python_object):
|
||||||
@@ -147,7 +149,7 @@ def _find_syntax_node_name(evaluator, access_handle):
|
|||||||
# a way to write a module in a module in Python (and also __name__ can
|
# a way to write a module in a module in Python (and also __name__ can
|
||||||
# be something like ``email.utils``).
|
# be something like ``email.utils``).
|
||||||
code_lines = get_cached_code_lines(evaluator.grammar, path)
|
code_lines = get_cached_code_lines(evaluator.grammar, path)
|
||||||
return module_node, module_node, path, code_lines
|
return module_node, module_node, file_io, code_lines
|
||||||
|
|
||||||
try:
|
try:
|
||||||
name_str = python_object.__name__
|
name_str = python_object.__name__
|
||||||
@@ -186,7 +188,7 @@ def _find_syntax_node_name(evaluator, access_handle):
|
|||||||
# completions at some points but will lead to mostly correct type
|
# completions at some points but will lead to mostly correct type
|
||||||
# inference, because people tend to define a public name in a module only
|
# inference, because people tend to define a public name in a module only
|
||||||
# once.
|
# once.
|
||||||
return module_node, names[-1].parent, path, code_lines
|
return module_node, names[-1].parent, file_io, code_lines
|
||||||
|
|
||||||
|
|
||||||
@compiled_objects_cache('mixed_cache')
|
@compiled_objects_cache('mixed_cache')
|
||||||
@@ -198,7 +200,7 @@ def _create(evaluator, access_handle, parent_context, *args):
|
|||||||
if result is None:
|
if result is None:
|
||||||
return compiled_object
|
return compiled_object
|
||||||
|
|
||||||
module_node, tree_node, path, code_lines = result
|
module_node, tree_node, file_io, code_lines = result
|
||||||
|
|
||||||
if parent_context.tree_node.get_root_node() == module_node:
|
if parent_context.tree_node.get_root_node() == module_node:
|
||||||
module_context = parent_context.get_root_context()
|
module_context = parent_context.get_root_context()
|
||||||
@@ -208,7 +210,7 @@ def _create(evaluator, access_handle, parent_context, *args):
|
|||||||
string_names = tuple(name.split('.'))
|
string_names = tuple(name.split('.'))
|
||||||
module_context = ModuleContext(
|
module_context = ModuleContext(
|
||||||
evaluator, module_node,
|
evaluator, module_node,
|
||||||
path=path,
|
file_io=file_io,
|
||||||
string_names=string_names,
|
string_names=string_names,
|
||||||
code_lines=code_lines,
|
code_lines=code_lines,
|
||||||
is_package=hasattr(compiled_object, 'py__path__'),
|
is_package=hasattr(compiled_object, 'py__path__'),
|
||||||
|
|||||||
@@ -173,13 +173,17 @@ 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, is_package=False):
|
def __init__(self, evaluator, module_node, file_io, string_names, code_lines, is_package=False):
|
||||||
super(ModuleContext, self).__init__(
|
super(ModuleContext, self).__init__(
|
||||||
evaluator,
|
evaluator,
|
||||||
parent_context=None,
|
parent_context=None,
|
||||||
tree_node=module_node
|
tree_node=module_node
|
||||||
)
|
)
|
||||||
self._path = path
|
self._file_io = file_io
|
||||||
|
if self._file_io is None:
|
||||||
|
self._path = None
|
||||||
|
else:
|
||||||
|
self._path = file_io.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
|
self.is_package = is_package
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import re
|
|||||||
from jedi.file_io import FileIO
|
from jedi.file_io import FileIO
|
||||||
from jedi._compatibility import FileNotFoundError, cast_path
|
from jedi._compatibility import FileNotFoundError, cast_path
|
||||||
from jedi.parser_utils import get_cached_code_lines
|
from jedi.parser_utils import get_cached_code_lines
|
||||||
from jedi.evaluate.cache import evaluator_function_cache
|
|
||||||
from jedi.evaluate.base_context import ContextSet
|
from jedi.evaluate.base_context import ContextSet
|
||||||
from jedi.evaluate.gradual.stub_context import TypingModuleWrapper, StubModuleContext
|
from jedi.evaluate.gradual.stub_context import TypingModuleWrapper, StubModuleContext
|
||||||
|
|
||||||
@@ -62,11 +61,6 @@ def _get_typeshed_directories(version_info):
|
|||||||
yield os.path.join(base, check_version)
|
yield os.path.join(base, check_version)
|
||||||
|
|
||||||
|
|
||||||
@evaluator_function_cache()
|
|
||||||
def _load_stub(evaluator, path):
|
|
||||||
return evaluator.parse(file_io=FileIO(path), cache=True, use_latest_grammar=True)
|
|
||||||
|
|
||||||
|
|
||||||
_version_cache = {}
|
_version_cache = {}
|
||||||
|
|
||||||
|
|
||||||
@@ -149,7 +143,12 @@ def _try_to_load_stub(evaluator, import_names, actual_context_set,
|
|||||||
# foo-stubs
|
# foo-stubs
|
||||||
for p in sys_path:
|
for p in sys_path:
|
||||||
init = os.path.join(p, *import_names) + '-stubs' + os.path.sep + '__init__.pyi'
|
init = os.path.join(p, *import_names) + '-stubs' + os.path.sep + '__init__.pyi'
|
||||||
m = _try_to_load_stub_from_file(evaluator, actual_context_set, init, import_names)
|
m = _try_to_load_stub_from_file(
|
||||||
|
evaluator,
|
||||||
|
actual_context_set,
|
||||||
|
file_io=FileIO(init),
|
||||||
|
import_names=import_names,
|
||||||
|
)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
return m
|
return m
|
||||||
|
|
||||||
@@ -172,8 +171,8 @@ def _try_to_load_stub(evaluator, import_names, actual_context_set,
|
|||||||
evaluator,
|
evaluator,
|
||||||
actual_context_set,
|
actual_context_set,
|
||||||
# The file path should end with .pyi
|
# The file path should end with .pyi
|
||||||
file_path,
|
file_io=FileIO(file_path),
|
||||||
import_names
|
import_names=import_names,
|
||||||
)
|
)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
return m
|
return m
|
||||||
@@ -202,8 +201,8 @@ def _try_to_load_stub(evaluator, import_names, actual_context_set,
|
|||||||
m = _try_to_load_stub_from_file(
|
m = _try_to_load_stub_from_file(
|
||||||
evaluator,
|
evaluator,
|
||||||
actual_context_set,
|
actual_context_set,
|
||||||
os.path.join(p, *names_for_path) + '.pyi',
|
file_io=FileIO(os.path.join(p, *names_for_path) + '.pyi'),
|
||||||
import_names,
|
import_names=import_names,
|
||||||
)
|
)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
return m
|
return m
|
||||||
@@ -229,35 +228,44 @@ def _load_from_typeshed(evaluator, actual_context_set, parent_module_context, im
|
|||||||
if map_ is not None:
|
if map_ is not None:
|
||||||
path = map_.get(import_name)
|
path = map_.get(import_name)
|
||||||
if path is not None:
|
if path is not None:
|
||||||
return _try_to_load_stub_from_file(evaluator, actual_context_set, path, import_names)
|
return _try_to_load_stub_from_file(
|
||||||
|
evaluator,
|
||||||
|
actual_context_set,
|
||||||
|
file_io=FileIO(path),
|
||||||
|
import_names=import_names,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _try_to_load_stub_from_file(evaluator, actual_context_set, path, import_names):
|
def _try_to_load_stub_from_file(evaluator, actual_context_set, file_io, import_names):
|
||||||
try:
|
try:
|
||||||
stub_module_node = _load_stub(evaluator, path)
|
stub_module_node = evaluator.parse(
|
||||||
|
file_io=file_io,
|
||||||
|
cache=True,
|
||||||
|
use_latest_grammar=True
|
||||||
|
)
|
||||||
except (OSError, IOError): # IOError is Python 2 only
|
except (OSError, IOError): # IOError is Python 2 only
|
||||||
# The file that you're looking for doesn't exist (anymore).
|
# The file that you're looking for doesn't exist (anymore).
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return create_stub_module(
|
return create_stub_module(
|
||||||
evaluator, actual_context_set, stub_module_node, path,
|
evaluator, actual_context_set, stub_module_node, file_io,
|
||||||
import_names
|
import_names
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_stub_module(evaluator, actual_context_set, stub_module_node, path, import_names):
|
def create_stub_module(evaluator, actual_context_set, stub_module_node, file_io, import_names):
|
||||||
if import_names == ('typing',):
|
if import_names == ('typing',):
|
||||||
module_cls = TypingModuleWrapper
|
module_cls = TypingModuleWrapper
|
||||||
else:
|
else:
|
||||||
module_cls = StubModuleContext
|
module_cls = StubModuleContext
|
||||||
file_name = os.path.basename(path)
|
file_name = os.path.basename(file_io.path)
|
||||||
stub_module_context = module_cls(
|
stub_module_context = module_cls(
|
||||||
actual_context_set, evaluator, stub_module_node,
|
actual_context_set, evaluator, stub_module_node,
|
||||||
path=path,
|
file_io=file_io,
|
||||||
string_names=import_names,
|
string_names=import_names,
|
||||||
# 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, file_io.path),
|
||||||
is_package=file_name == '__init__.pyi',
|
is_package=file_name == '__init__.pyi',
|
||||||
)
|
)
|
||||||
return stub_module_context
|
return stub_module_context
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ import os
|
|||||||
from jedi.evaluate.gradual.typeshed import TYPESHED_PATH, create_stub_module
|
from jedi.evaluate.gradual.typeshed import TYPESHED_PATH, create_stub_module
|
||||||
|
|
||||||
|
|
||||||
def load_proper_stub_module(evaluator, path, import_names, module_node):
|
def load_proper_stub_module(evaluator, file_io, import_names, module_node):
|
||||||
"""
|
"""
|
||||||
This function is given a random .pyi file and should return the proper
|
This function is given a random .pyi file and should return the proper
|
||||||
module.
|
module.
|
||||||
"""
|
"""
|
||||||
|
path = file_io.path
|
||||||
assert path.endswith('.pyi')
|
assert path.endswith('.pyi')
|
||||||
if path.startswith(TYPESHED_PATH):
|
if path.startswith(TYPESHED_PATH):
|
||||||
# /foo/stdlib/3/os/__init__.pyi -> stdlib/3/os/__init__
|
# /foo/stdlib/3/os/__init__.pyi -> stdlib/3/os/__init__
|
||||||
@@ -24,7 +25,7 @@ def load_proper_stub_module(evaluator, path, import_names, module_node):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
stub = create_stub_module(
|
stub = create_stub_module(
|
||||||
evaluator, actual_context_set, module_node, path, import_names
|
evaluator, actual_context_set, module_node, file_io, import_names
|
||||||
)
|
)
|
||||||
evaluator.stub_module_cache[import_names] = stub
|
evaluator.stub_module_cache[import_names] = stub
|
||||||
return stub
|
return stub
|
||||||
|
|||||||
@@ -464,7 +464,7 @@ def _load_python_module(evaluator, file_io, sys_path=None,
|
|||||||
from jedi.evaluate.context import ModuleContext
|
from jedi.evaluate.context import ModuleContext
|
||||||
return ModuleContext(
|
return ModuleContext(
|
||||||
evaluator, module_node,
|
evaluator, module_node,
|
||||||
path=file_io.path,
|
file_io=file_io,
|
||||||
string_names=import_names,
|
string_names=import_names,
|
||||||
code_lines=get_cached_code_lines(evaluator.grammar, file_io.path),
|
code_lines=get_cached_code_lines(evaluator.grammar, file_io.path),
|
||||||
is_package=is_package,
|
is_package=is_package,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from jedi.evaluate.base_context import ContextualizedNode
|
|||||||
from jedi.evaluate.helpers import is_string
|
from jedi.evaluate.helpers import is_string
|
||||||
from jedi.common.utils import traverse_parents
|
from jedi.common.utils import traverse_parents
|
||||||
from jedi.parser_utils import get_cached_code_lines
|
from jedi.parser_utils import get_cached_code_lines
|
||||||
|
from jedi.file_io import FileIO
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
|
|
||||||
@@ -140,9 +141,10 @@ def discover_buildout_paths(evaluator, script_path):
|
|||||||
|
|
||||||
|
|
||||||
def _get_paths_from_buildout_script(evaluator, buildout_script_path):
|
def _get_paths_from_buildout_script(evaluator, buildout_script_path):
|
||||||
|
file_io = FileIO(buildout_script_path)
|
||||||
try:
|
try:
|
||||||
module_node = evaluator.parse(
|
module_node = evaluator.parse(
|
||||||
path=buildout_script_path,
|
file_io=file_io,
|
||||||
cache=True,
|
cache=True,
|
||||||
cache_path=settings.cache_directory
|
cache_path=settings.cache_directory
|
||||||
)
|
)
|
||||||
@@ -152,7 +154,7 @@ def _get_paths_from_buildout_script(evaluator, buildout_script_path):
|
|||||||
|
|
||||||
from jedi.evaluate.context import ModuleContext
|
from jedi.evaluate.context import ModuleContext
|
||||||
module = ModuleContext(
|
module = ModuleContext(
|
||||||
evaluator, module_node, buildout_script_path,
|
evaluator, module_node, file_io,
|
||||||
string_names=None,
|
string_names=None,
|
||||||
code_lines=get_cached_code_lines(evaluator.grammar, buildout_script_path),
|
code_lines=get_cached_code_lines(evaluator.grammar, buildout_script_path),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -437,7 +437,7 @@ def collections_namedtuple(obj, arguments):
|
|||||||
generated_class = next(module.iter_classdefs())
|
generated_class = next(module.iter_classdefs())
|
||||||
parent_context = ModuleContext(
|
parent_context = ModuleContext(
|
||||||
evaluator, module,
|
evaluator, module,
|
||||||
path=None,
|
file_io=None,
|
||||||
string_names=None,
|
string_names=None,
|
||||||
code_lines=parso.split_lines(code, keepends=True),
|
code_lines=parso.split_lines(code, keepends=True),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user