1
0
forked from VimPlug/jedi

Evaluator -> InferState

This commit is contained in:
Dave Halter
2019-08-15 00:33:49 +02:00
parent 8157d119a7
commit a5dff65142
62 changed files with 768 additions and 768 deletions

View File

@@ -4,8 +4,8 @@ from jedi.inference.compiled.context import CompiledObject, CompiledName, \
from jedi.inference.base_context import ContextWrapper, LazyContextWrapper
def builtin_from_name(evaluator, string):
typing_builtins_module = evaluator.builtins_module
def builtin_from_name(infer_state, string):
typing_builtins_module = infer_state.builtins_module
if string in ('None', 'True', 'False'):
builtins, = typing_builtins_module.non_stub_context_set
filter_ = next(builtins.get_filters())
@@ -18,7 +18,7 @@ def builtin_from_name(evaluator, string):
class CompiledValue(LazyContextWrapper):
def __init__(self, compiled_obj):
self.evaluator = compiled_obj.evaluator
self.infer_state = compiled_obj.infer_state
self._compiled_obj = compiled_obj
def __getattribute__(self, name):
@@ -29,36 +29,36 @@ class CompiledValue(LazyContextWrapper):
def _get_wrapped_context(self):
instance, = builtin_from_name(
self.evaluator, self._compiled_obj.name.string_name).execute_with_values()
self.infer_state, self._compiled_obj.name.string_name).execute_with_values()
return instance
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self._compiled_obj)
def create_simple_object(evaluator, obj):
def create_simple_object(infer_state, obj):
"""
Only allows creations of objects that are easily picklable across Python
versions.
"""
assert type(obj) in (int, float, str, bytes, unicode, slice, complex, bool), obj
compiled_obj = create_from_access_path(
evaluator,
evaluator.compiled_subprocess.create_simple_object(obj)
infer_state,
infer_state.compiled_subprocess.create_simple_object(obj)
)
return CompiledValue(compiled_obj)
def get_string_context_set(evaluator):
return builtin_from_name(evaluator, u'str').execute_with_values()
def get_string_context_set(infer_state):
return builtin_from_name(infer_state, u'str').execute_with_values()
def load_module(evaluator, dotted_name, **kwargs):
def load_module(infer_state, dotted_name, **kwargs):
# Temporary, some tensorflow builtins cannot be loaded, so it's tried again
# and again and it's really slow.
if dotted_name.startswith('tensorflow.'):
return None
access_path = evaluator.compiled_subprocess.load_module(dotted_name=dotted_name, **kwargs)
access_path = infer_state.compiled_subprocess.load_module(dotted_name=dotted_name, **kwargs)
if access_path is None:
return None
return create_from_access_path(evaluator, access_path)
return create_from_access_path(infer_state, access_path)

View File

@@ -109,8 +109,8 @@ def compiled_objects_cache(attribute_name):
Caching the id has the advantage that an object doesn't need to be
hashable.
"""
def wrapper(evaluator, obj, parent_context=None):
cache = getattr(evaluator, attribute_name)
def wrapper(infer_state, obj, parent_context=None):
cache = getattr(infer_state, attribute_name)
# Do a very cheap form of caching here.
key = id(obj)
try:
@@ -119,9 +119,9 @@ def compiled_objects_cache(attribute_name):
except KeyError:
# TODO wuaaaarrghhhhhhhh
if attribute_name == 'mixed_cache':
result = func(evaluator, obj, parent_context)
result = func(infer_state, obj, parent_context)
else:
result = func(evaluator, obj)
result = func(infer_state, obj)
# Need to cache all of them, otherwise the id could be overwritten.
cache[key] = result, obj, parent_context
return result
@@ -130,11 +130,11 @@ def compiled_objects_cache(attribute_name):
return decorator
def create_access(evaluator, obj):
return evaluator.compiled_subprocess.get_or_create_access_handle(obj)
def create_access(infer_state, obj):
return infer_state.compiled_subprocess.get_or_create_access_handle(obj)
def load_module(evaluator, dotted_name, sys_path):
def load_module(infer_state, dotted_name, sys_path):
temp, sys.path = sys.path, sys_path
try:
__import__(dotted_name)
@@ -154,7 +154,7 @@ def load_module(evaluator, dotted_name, sys_path):
# Just access the cache after import, because of #59 as well as the very
# complicated import structure of Python.
module = sys.modules[dotted_name]
return create_access_path(evaluator, module)
return create_access_path(infer_state, module)
class AccessPath(object):
@@ -171,8 +171,8 @@ class AccessPath(object):
self.accesses = value
def create_access_path(evaluator, obj):
access = create_access(evaluator, obj)
def create_access_path(infer_state, obj):
access = create_access(infer_state, obj)
return AccessPath(access.get_access_path_tuples())
@@ -193,18 +193,18 @@ def get_api_type(obj):
class DirectObjectAccess(object):
def __init__(self, evaluator, obj):
self._evaluator = evaluator
def __init__(self, infer_state, obj):
self._infer_state = infer_state
self._obj = obj
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.get_repr())
def _create_access(self, obj):
return create_access(self._evaluator, obj)
return create_access(self._infer_state, obj)
def _create_access_path(self, obj):
return create_access_path(self._evaluator, obj)
return create_access_path(self._infer_state, obj)
def py__bool__(self):
return bool(self._obj)
@@ -376,7 +376,7 @@ class DirectObjectAccess(object):
return get_api_type(self._obj)
def get_access_path_tuples(self):
accesses = [create_access(self._evaluator, o) for o in self._get_objects_path()]
accesses = [create_access(self._infer_state, o) for o in self._get_objects_path()]
return [(access.py__name__(), access) for access in accesses]
def _get_objects_path(self):

View File

@@ -14,7 +14,7 @@ from jedi.inference.names import AbstractNameDefinition, ContextNameMixin, \
from jedi.inference.base_context import Context, ContextSet, NO_CONTEXTS
from jedi.inference.lazy_context import LazyKnownContext
from jedi.inference.compiled.access import _sentinel
from jedi.inference.cache import evaluator_function_cache
from jedi.inference.cache import infer_state_function_cache
from jedi.inference.helpers import reraise_getitem_errors
from jedi.inference.signature import BuiltinSignature
@@ -41,15 +41,15 @@ class CheckAttribute(object):
class CompiledObject(Context):
def __init__(self, evaluator, access_handle, parent_context=None):
super(CompiledObject, self).__init__(evaluator, parent_context)
def __init__(self, infer_state, access_handle, parent_context=None):
super(CompiledObject, self).__init__(infer_state, parent_context)
self.access_handle = access_handle
def py__call__(self, arguments):
return_annotation = self.access_handle.get_return_annotation()
if return_annotation is not None:
# TODO the return annotation may also be a string.
return create_from_access_path(self.evaluator, return_annotation).execute_annotation()
return create_from_access_path(self.infer_state, return_annotation).execute_annotation()
try:
self.access_handle.getattr_paths(u'__call__')
@@ -59,26 +59,26 @@ class CompiledObject(Context):
if self.access_handle.is_class():
from jedi.inference.context import CompiledInstance
return ContextSet([
CompiledInstance(self.evaluator, self.parent_context, self, arguments)
CompiledInstance(self.infer_state, self.parent_context, self, arguments)
])
else:
return ContextSet(self._execute_function(arguments))
@CheckAttribute()
def py__class__(self):
return create_from_access_path(self.evaluator, self.access_handle.py__class__())
return create_from_access_path(self.infer_state, self.access_handle.py__class__())
@CheckAttribute()
def py__mro__(self):
return (self,) + tuple(
create_from_access_path(self.evaluator, access)
create_from_access_path(self.infer_state, access)
for access in self.access_handle.py__mro__accesses()
)
@CheckAttribute()
def py__bases__(self):
return tuple(
create_from_access_path(self.evaluator, access)
create_from_access_path(self.infer_state, access)
for access in self.access_handle.py__bases__()
)
@@ -178,7 +178,7 @@ class CompiledObject(Context):
search_global shouldn't change the fact that there's one dict, this way
there's only one `object`.
"""
return CompiledObjectFilter(self.evaluator, self, is_instance)
return CompiledObjectFilter(self.infer_state, self, is_instance)
@CheckAttribute(u'__getitem__')
def py__simple_getitem__(self, index):
@@ -187,7 +187,7 @@ class CompiledObject(Context):
if access is None:
return NO_CONTEXTS
return ContextSet([create_from_access_path(self.evaluator, access)])
return ContextSet([create_from_access_path(self.infer_state, access)])
def py__getitem__(self, index_context_set, contextualized_node):
all_access_paths = self.access_handle.py__getitem__all_values()
@@ -196,7 +196,7 @@ class CompiledObject(Context):
# object.
return super(CompiledObject, self).py__getitem__(index_context_set, contextualized_node)
return ContextSet(
create_from_access_path(self.evaluator, access)
create_from_access_path(self.infer_state, access)
for access in all_access_paths
)
@@ -215,7 +215,7 @@ class CompiledObject(Context):
return
for access in access_path_list:
yield LazyKnownContext(create_from_access_path(self.evaluator, access))
yield LazyKnownContext(create_from_access_path(self.infer_state, access))
def py__name__(self):
return self.access_handle.py__name__()
@@ -237,12 +237,12 @@ class CompiledObject(Context):
try:
# TODO wtf is this? this is exactly the same as the thing
# below. It uses getattr as well.
self.evaluator.builtins_module.access_handle.getattr_paths(name)
self.infer_state.builtins_module.access_handle.getattr_paths(name)
except AttributeError:
continue
else:
bltn_obj = builtin_from_name(self.evaluator, name)
for result in self.evaluator.execute(bltn_obj, params):
bltn_obj = builtin_from_name(self.infer_state, name)
for result in self.infer_state.execute(bltn_obj, params):
yield result
for type_ in docstrings.infer_return_types(self):
yield type_
@@ -257,20 +257,20 @@ class CompiledObject(Context):
def execute_operation(self, other, operator):
return create_from_access_path(
self.evaluator,
self.infer_state,
self.access_handle.execute_operation(other.access_handle, operator)
)
def negate(self):
return create_from_access_path(self.evaluator, self.access_handle.negate())
return create_from_access_path(self.infer_state, self.access_handle.negate())
def get_metaclasses(self):
return NO_CONTEXTS
class CompiledName(AbstractNameDefinition):
def __init__(self, evaluator, parent_context, name):
self._evaluator = evaluator
def __init__(self, infer_state, parent_context, name):
self._infer_state = infer_state
self.parent_context = parent_context
self.string_name = name
@@ -296,7 +296,7 @@ class CompiledName(AbstractNameDefinition):
@underscore_memoization
def infer(self):
return ContextSet([_create_from_name(
self._evaluator, self.parent_context, self.string_name
self._infer_state, self.parent_context, self.string_name
)])
@@ -322,12 +322,12 @@ class SignatureParamName(ParamNameInterface, AbstractNameDefinition):
def infer(self):
p = self._signature_param
evaluator = self.parent_context.evaluator
infer_state = self.parent_context.infer_state
contexts = NO_CONTEXTS
if p.has_default:
contexts = ContextSet([create_from_access_path(evaluator, p.default)])
contexts = ContextSet([create_from_access_path(infer_state, p.default)])
if p.has_annotation:
annotation = create_from_access_path(evaluator, p.annotation)
annotation = create_from_access_path(infer_state, p.annotation)
contexts |= annotation.execute_with_values()
return contexts
@@ -364,8 +364,8 @@ class EmptyCompiledName(AbstractNameDefinition):
completions, just give Jedi the option to return this object. It infers to
nothing.
"""
def __init__(self, evaluator, name):
self.parent_context = evaluator.builtins_module
def __init__(self, infer_state, name):
self.parent_context = infer_state.builtins_module
self.string_name = name
def infer(self):
@@ -375,8 +375,8 @@ class EmptyCompiledName(AbstractNameDefinition):
class CompiledObjectFilter(AbstractFilter):
name_class = CompiledName
def __init__(self, evaluator, compiled_object, is_instance=False):
self._evaluator = evaluator
def __init__(self, infer_state, compiled_object, is_instance=False):
self._infer_state = infer_state
self.compiled_object = compiled_object
self.is_instance = is_instance
@@ -399,7 +399,7 @@ class CompiledObjectFilter(AbstractFilter):
# Always use unicode objects in Python 2 from here.
name = force_unicode(name)
if (is_descriptor and not self._evaluator.allow_descriptor_getattr) or not has_attribute:
if (is_descriptor and not self._infer_state.allow_descriptor_getattr) or not has_attribute:
return [self._get_cached_name(name, is_empty=True)]
if self.is_instance and name not in dir_callback():
@@ -409,7 +409,7 @@ class CompiledObjectFilter(AbstractFilter):
@memoize_method
def _get_cached_name(self, name, is_empty=False):
if is_empty:
return EmptyCompiledName(self._evaluator, name)
return EmptyCompiledName(self._infer_state, name)
else:
return self._create_name(name)
@@ -426,12 +426,12 @@ class CompiledObjectFilter(AbstractFilter):
# ``dir`` doesn't include the type names.
if not self.is_instance and needs_type_completions:
for filter in builtin_from_name(self._evaluator, u'type').get_filters():
for filter in builtin_from_name(self._infer_state, u'type').get_filters():
names += filter.values()
return names
def _create_name(self, name):
return self.name_class(self._evaluator, self.compiled_object, name)
return self.name_class(self._infer_state, self.compiled_object, name)
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self.compiled_object)
@@ -507,7 +507,7 @@ def _parse_function_doc(doc):
return param_str, ret
def _create_from_name(evaluator, compiled_object, name):
def _create_from_name(infer_state, compiled_object, name):
access_paths = compiled_object.access_handle.getattr_paths(name, default=None)
parent_context = compiled_object
if parent_context.is_class():
@@ -516,26 +516,26 @@ def _create_from_name(evaluator, compiled_object, name):
context = None
for access_path in access_paths:
context = create_cached_compiled_object(
evaluator, access_path, parent_context=context
infer_state, access_path, parent_context=context
)
return context
def _normalize_create_args(func):
"""The cache doesn't care about keyword vs. normal args."""
def wrapper(evaluator, obj, parent_context=None):
return func(evaluator, obj, parent_context)
def wrapper(infer_state, obj, parent_context=None):
return func(infer_state, obj, parent_context)
return wrapper
def create_from_access_path(evaluator, access_path):
def create_from_access_path(infer_state, access_path):
parent_context = None
for name, access in access_path.accesses:
parent_context = create_cached_compiled_object(evaluator, access, parent_context)
parent_context = create_cached_compiled_object(infer_state, access, parent_context)
return parent_context
@_normalize_create_args
@evaluator_function_cache()
def create_cached_compiled_object(evaluator, access_handle, parent_context):
return CompiledObject(evaluator, access_handle, parent_context)
@infer_state_function_cache()
def create_cached_compiled_object(infer_state, access_handle, parent_context):
return CompiledObject(infer_state, access_handle, parent_context)

View File

@@ -15,7 +15,7 @@ from jedi.file_io import FileIO
from jedi.inference.base_context import ContextSet, ContextWrapper
from jedi.inference.helpers import SimpleGetItemNotFound
from jedi.inference.context import ModuleContext
from jedi.inference.cache import evaluator_function_cache
from jedi.inference.cache import infer_state_function_cache
from jedi.inference.compiled.getattr_static import getattr_static
from jedi.inference.compiled.access import compiled_objects_cache, \
ALLOWED_GETITEM_TYPES, get_api_type
@@ -48,7 +48,7 @@ class MixedObject(ContextWrapper):
self.access_handle = compiled_object.access_handle
def get_filters(self, *args, **kwargs):
yield MixedObjectFilter(self.evaluator, self)
yield MixedObjectFilter(self.infer_state, self)
def get_signatures(self):
# Prefer `inspect.signature` over somehow analyzing Python code. It
@@ -105,9 +105,9 @@ class MixedName(compiled.CompiledName):
contexts = [None]
for access in access_paths:
contexts = ContextSet.from_sets(
_create(self._evaluator, access, parent_context=c)
_create(self._infer_state, access, parent_context=c)
if c is None or isinstance(c, MixedObject)
else ContextSet({create_cached_compiled_object(c.evaluator, access, c)})
else ContextSet({create_cached_compiled_object(c.infer_state, access, c)})
for c in contexts
)
return contexts
@@ -121,9 +121,9 @@ class MixedObjectFilter(compiled.CompiledObjectFilter):
name_class = MixedName
@evaluator_function_cache()
def _load_module(evaluator, path):
module_node = evaluator.parse(
@infer_state_function_cache()
def _load_module(infer_state, path):
module_node = infer_state.parse(
path=path,
cache=True,
diff_cache=settings.fast_parser,
@@ -131,7 +131,7 @@ def _load_module(evaluator, path):
).get_root_node()
# python_module = inspect.getmodule(python_object)
# TODO we should actually make something like this possible.
#evaluator.modules[python_module.__name__] = module_node
#infer_state.modules[python_module.__name__] = module_node
return module_node
@@ -155,7 +155,7 @@ def _get_object_to_check(python_object):
raise TypeError # Prevents computation of `repr` within inspect.
def _find_syntax_node_name(evaluator, python_object):
def _find_syntax_node_name(infer_state, python_object):
original_object = python_object
try:
python_object = _get_object_to_check(python_object)
@@ -168,13 +168,13 @@ def _find_syntax_node_name(evaluator, python_object):
return None
file_io = FileIO(path)
module_node = _load_module(evaluator, path)
module_node = _load_module(infer_state, path)
if inspect.ismodule(python_object):
# We don't need to check names for modules, because there's not really
# a way to write a module in a module in Python (and also __name__ can
# be something like ``email.utils``).
code_lines = get_cached_code_lines(evaluator.grammar, path)
code_lines = get_cached_code_lines(infer_state.grammar, path)
return module_node, module_node, file_io, code_lines
try:
@@ -214,7 +214,7 @@ def _find_syntax_node_name(evaluator, python_object):
if line_names:
names = line_names
code_lines = get_cached_code_lines(evaluator.grammar, path)
code_lines = get_cached_code_lines(infer_state.grammar, path)
# It's really hard to actually get the right definition, here as a last
# resort we just return the last one. This chance might lead to odd
# completions at some points but will lead to mostly correct type
@@ -230,9 +230,9 @@ def _find_syntax_node_name(evaluator, python_object):
@compiled_objects_cache('mixed_cache')
def _create(evaluator, access_handle, parent_context, *args):
def _create(infer_state, access_handle, parent_context, *args):
compiled_object = create_cached_compiled_object(
evaluator,
infer_state,
access_handle,
parent_context=parent_context and parent_context.compiled_object
)
@@ -240,7 +240,7 @@ def _create(evaluator, access_handle, parent_context, *args):
# TODO accessing this is bad, but it probably doesn't matter that much,
# because we're working with interpreteters only here.
python_object = access_handle.access._obj
result = _find_syntax_node_name(evaluator, python_object)
result = _find_syntax_node_name(infer_state, python_object)
if result is None:
# TODO Care about generics from stuff like `[1]` and don't return like this.
if type(python_object) in (dict, list, tuple):
@@ -257,14 +257,14 @@ def _create(evaluator, access_handle, parent_context, *args):
name = compiled_object.get_root_context().py__name__()
string_names = tuple(name.split('.'))
module_context = ModuleContext(
evaluator, module_node,
infer_state, module_node,
file_io=file_io,
string_names=string_names,
code_lines=code_lines,
is_package=hasattr(compiled_object, 'py__path__'),
)
if name is not None:
evaluator.module_cache.add(string_names, ContextSet([module_context]))
infer_state.module_cache.add(string_names, ContextSet([module_context]))
else:
if parent_context.tree_node.get_root_node() != module_node:
# This happens e.g. when __module__ is wrong, or when using

View File

@@ -70,10 +70,10 @@ def _cleanup_process(process, thread):
pass
class _EvaluatorProcess(object):
def __init__(self, evaluator):
self._evaluator_weakref = weakref.ref(evaluator)
self._evaluator_id = id(evaluator)
class _InferStateProcess(object):
def __init__(self, infer_state):
self._infer_state_weakref = weakref.ref(infer_state)
self._infer_state_id = id(infer_state)
self._handles = {}
def get_or_create_access_handle(self, obj):
@@ -81,7 +81,7 @@ class _EvaluatorProcess(object):
try:
return self.get_access_handle(id_)
except KeyError:
access = DirectObjectAccess(self._evaluator_weakref(), obj)
access = DirectObjectAccess(self._infer_state_weakref(), obj)
handle = AccessHandle(self, access, id_)
self.set_access_handle(handle)
return handle
@@ -93,19 +93,19 @@ class _EvaluatorProcess(object):
self._handles[handle.id] = handle
class EvaluatorSameProcess(_EvaluatorProcess):
class InferStateSameProcess(_InferStateProcess):
"""
Basically just an easy access to functions.py. It has the same API
as EvaluatorSubprocess and does the same thing without using a subprocess.
as InferStateSubprocess and does the same thing without using a subprocess.
This is necessary for the Interpreter process.
"""
def __getattr__(self, name):
return partial(_get_function(name), self._evaluator_weakref())
return partial(_get_function(name), self._infer_state_weakref())
class EvaluatorSubprocess(_EvaluatorProcess):
def __init__(self, evaluator, compiled_subprocess):
super(EvaluatorSubprocess, self).__init__(evaluator)
class InferStateSubprocess(_InferStateProcess):
def __init__(self, infer_state, compiled_subprocess):
super(InferStateSubprocess, self).__init__(infer_state)
self._used = False
self._compiled_subprocess = compiled_subprocess
@@ -116,7 +116,7 @@ class EvaluatorSubprocess(_EvaluatorProcess):
self._used = True
result = self._compiled_subprocess.run(
self._evaluator_weakref(),
self._infer_state_weakref(),
func,
args=args,
kwargs=kwargs,
@@ -148,7 +148,7 @@ class EvaluatorSubprocess(_EvaluatorProcess):
def __del__(self):
if self._used and not self._compiled_subprocess.is_crashed:
self._compiled_subprocess.delete_evaluator(self._evaluator_id)
self._compiled_subprocess.delete_infer_state(self._infer_state_id)
class CompiledSubprocess(object):
@@ -158,7 +158,7 @@ class CompiledSubprocess(object):
def __init__(self, executable):
self._executable = executable
self._evaluator_deletion_queue = queue.deque()
self._infer_state_deletion_queue = queue.deque()
self._cleanup_callable = lambda: None
def __repr__(self):
@@ -205,18 +205,18 @@ class CompiledSubprocess(object):
t)
return process
def run(self, evaluator, function, args=(), kwargs={}):
# Delete old evaluators.
def run(self, infer_state, function, args=(), kwargs={}):
# Delete old infer_states.
while True:
try:
evaluator_id = self._evaluator_deletion_queue.pop()
infer_state_id = self._infer_state_deletion_queue.pop()
except IndexError:
break
else:
self._send(evaluator_id, None)
self._send(infer_state_id, None)
assert callable(function)
return self._send(id(evaluator), function, args, kwargs)
return self._send(id(infer_state), function, args, kwargs)
def get_sys_path(self):
return self._send(None, functions.get_sys_path, (), {})
@@ -225,7 +225,7 @@ class CompiledSubprocess(object):
self.is_crashed = True
self._cleanup_callable()
def _send(self, evaluator_id, function, args=(), kwargs={}):
def _send(self, infer_state_id, function, args=(), kwargs={}):
if self.is_crashed:
raise InternalError("The subprocess %s has crashed." % self._executable)
@@ -233,7 +233,7 @@ class CompiledSubprocess(object):
# Python 2 compatibility
kwargs = {force_unicode(key): value for key, value in kwargs.items()}
data = evaluator_id, function, args, kwargs
data = infer_state_id, function, args, kwargs
try:
pickle_dump(data, self._get_process().stdin, self._pickle_protocol)
except (socket.error, IOError) as e:
@@ -272,59 +272,59 @@ class CompiledSubprocess(object):
raise result
return result
def delete_evaluator(self, evaluator_id):
def delete_infer_state(self, infer_state_id):
"""
Currently we are not deleting evalutors instantly. They only get
Currently we are not deleting infer_state instantly. They only get
deleted once the subprocess is used again. It would probably a better
solution to move all of this into a thread. However, the memory usage
of a single evaluator shouldn't be that high.
of a single infer_state shouldn't be that high.
"""
# With an argument - the evaluator gets deleted.
self._evaluator_deletion_queue.append(evaluator_id)
# With an argument - the infer_state gets deleted.
self._infer_state_deletion_queue.append(infer_state_id)
class Listener(object):
def __init__(self, pickle_protocol):
self._evaluators = {}
self._infer_states = {}
# TODO refactor so we don't need to process anymore just handle
# controlling.
self._process = _EvaluatorProcess(Listener)
self._process = _InferStateProcess(Listener)
self._pickle_protocol = pickle_protocol
def _get_evaluator(self, function, evaluator_id):
from jedi.inference import Evaluator
def _get_infer_state(self, function, infer_state_id):
from jedi.inference import InferState
try:
evaluator = self._evaluators[evaluator_id]
infer_state = self._infer_states[infer_state_id]
except KeyError:
from jedi.api.environment import InterpreterEnvironment
evaluator = Evaluator(
infer_state = InferState(
# The project is not actually needed. Nothing should need to
# access it.
project=None,
environment=InterpreterEnvironment()
)
self._evaluators[evaluator_id] = evaluator
return evaluator
self._infer_states[infer_state_id] = infer_state
return infer_state
def _run(self, evaluator_id, function, args, kwargs):
if evaluator_id is None:
def _run(self, infer_state_id, function, args, kwargs):
if infer_state_id is None:
return function(*args, **kwargs)
elif function is None:
del self._evaluators[evaluator_id]
del self._infer_states[infer_state_id]
else:
evaluator = self._get_evaluator(function, evaluator_id)
infer_state = self._get_infer_state(function, infer_state_id)
# Exchange all handles
args = list(args)
for i, arg in enumerate(args):
if isinstance(arg, AccessHandle):
args[i] = evaluator.compiled_subprocess.get_access_handle(arg.id)
args[i] = infer_state.compiled_subprocess.get_access_handle(arg.id)
for key, value in kwargs.items():
if isinstance(value, AccessHandle):
kwargs[key] = evaluator.compiled_subprocess.get_access_handle(value.id)
kwargs[key] = infer_state.compiled_subprocess.get_access_handle(value.id)
return function(evaluator, *args, **kwargs)
return function(infer_state, *args, **kwargs)
def listen(self):
stdout = sys.stdout
@@ -399,7 +399,7 @@ class AccessHandle(object):
@memoize_method
def _cached_results(self, name, *args, **kwargs):
#if type(self._subprocess) == EvaluatorSubprocess:
#if type(self._subprocess) == InferStateSubprocess:
#print(name, args, kwargs,
#self._subprocess.get_compiled_method_return(self.id, name, *args, **kwargs)
#)

View File

@@ -12,20 +12,20 @@ def get_sys_path():
return list(map(cast_path, sys.path))
def load_module(evaluator, **kwargs):
return access.load_module(evaluator, **kwargs)
def load_module(infer_state, **kwargs):
return access.load_module(infer_state, **kwargs)
def get_compiled_method_return(evaluator, id, attribute, *args, **kwargs):
handle = evaluator.compiled_subprocess.get_access_handle(id)
def get_compiled_method_return(infer_state, id, attribute, *args, **kwargs):
handle = infer_state.compiled_subprocess.get_access_handle(id)
return getattr(handle.access, attribute)(*args, **kwargs)
def create_simple_object(evaluator, obj):
return access.create_access_path(evaluator, obj)
def create_simple_object(infer_state, obj):
return access.create_access_path(infer_state, obj)
def get_module_info(evaluator, sys_path=None, full_name=None, **kwargs):
def get_module_info(infer_state, sys_path=None, full_name=None, **kwargs):
"""
Returns Tuple[Union[NamespaceInfo, FileIO, None], Optional[bool]]
"""
@@ -40,25 +40,25 @@ def get_module_info(evaluator, sys_path=None, full_name=None, **kwargs):
sys.path = temp
def list_module_names(evaluator, search_path):
def list_module_names(infer_state, search_path):
return [
force_unicode(name)
for module_loader, name, is_pkg in iter_modules(search_path)
]
def get_builtin_module_names(evaluator):
def get_builtin_module_names(infer_state):
return list(map(force_unicode, sys.builtin_module_names))
def _test_raise_error(evaluator, exception_type):
def _test_raise_error(infer_state, exception_type):
"""
Raise an error to simulate certain problems for unit tests.
"""
raise exception_type
def _test_print(evaluator, stderr=None, stdout=None):
def _test_print(infer_state, stderr=None, stdout=None):
"""
Force some prints in the subprocesses. This exists for unit tests.
"""
@@ -82,5 +82,5 @@ def _get_init_path(directory_path):
return None
def safe_literal_eval(evaluator, value):
def safe_literal_eval(infer_state, value):
return parser_utils.safe_literal_eval(value)