mirror of
https://github.com/davidhalter/jedi.git
synced 2026-01-04 11:13:26 +08:00
Don't use the pickler modification anymore. That doesn't work in other python versions and was in general a bit hard to do
This commit is contained in:
@@ -17,7 +17,8 @@ from functools import partial
|
||||
from jedi._compatibility import queue
|
||||
from jedi.cache import memoize_method
|
||||
from jedi.evaluate.compiled.subprocess import functions
|
||||
from jedi.evaluate.compiled.access import DirectObjectAccess
|
||||
from jedi.evaluate.compiled.access import DirectObjectAccess, AccessPath, \
|
||||
SignatureParam
|
||||
|
||||
_PICKLE_PROTOCOL = 2
|
||||
|
||||
@@ -88,15 +89,32 @@ class EvaluatorSubprocess(_EvaluatorProcess):
|
||||
func,
|
||||
args=args,
|
||||
kwargs=kwargs,
|
||||
unpickler=lambda stdout: _ModifiedUnpickler(self, stdout).load()
|
||||
)
|
||||
if isinstance(result, AccessHandle):
|
||||
result.add_subprocess(self)
|
||||
|
||||
return result
|
||||
# IMO it should be possible to create a hook in pickle.load to
|
||||
# mess with the loaded objects. However it's extremely complicated
|
||||
# to work around this so just do it with this call. ~ dave
|
||||
return self._convert_access_handles(result)
|
||||
|
||||
return wrapper
|
||||
|
||||
def _convert_access_handles(self, obj):
|
||||
if isinstance(obj, SignatureParam):
|
||||
return SignatureParam(*self._convert_access_handles(tuple(obj)))
|
||||
elif isinstance(obj, tuple):
|
||||
return tuple(self._convert_access_handles(o) for o in obj)
|
||||
elif isinstance(obj, list):
|
||||
return [self._convert_access_handles(o) for o in obj]
|
||||
elif isinstance(obj, AccessHandle):
|
||||
try:
|
||||
# Rewrite the access handle to one we're already having.
|
||||
obj = self.get_access_handle(obj.id)
|
||||
except KeyError:
|
||||
obj.add_subprocess(self)
|
||||
self.set_access_handle(obj)
|
||||
elif isinstance(obj, AccessPath):
|
||||
return AccessPath(self._convert_access_handles(obj.accesses))
|
||||
return obj
|
||||
|
||||
def __del__(self):
|
||||
if self._used:
|
||||
self._compiled_subprocess.delete_evaluator(self._evaluator_id)
|
||||
@@ -116,11 +134,11 @@ class _Subprocess(object):
|
||||
# stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
def _send(self, evaluator_id, function, args=(), kwargs={}, unpickler=pickle.load):
|
||||
def _send(self, evaluator_id, function, args=(), kwargs={}):
|
||||
data = evaluator_id, function, args, kwargs
|
||||
pickle.dump(data, self._process.stdin, protocol=_PICKLE_PROTOCOL)
|
||||
self._process.stdin.flush()
|
||||
is_exception, result = unpickler(self._process.stdout)
|
||||
is_exception, result = pickle.load(self._process.stdout)
|
||||
if is_exception:
|
||||
raise result
|
||||
return result
|
||||
@@ -143,7 +161,7 @@ class _CompiledSubprocess(_Subprocess):
|
||||
)
|
||||
self._evaluator_deletion_queue = queue.deque()
|
||||
|
||||
def run(self, evaluator, function, args=(), kwargs={}, unpickler=None):
|
||||
def run(self, evaluator, function, args=(), kwargs={}):
|
||||
# Delete old evaluators.
|
||||
while True:
|
||||
try:
|
||||
@@ -154,7 +172,7 @@ class _CompiledSubprocess(_Subprocess):
|
||||
self._send(evaluator_id, None)
|
||||
|
||||
assert callable(function)
|
||||
return self._send(id(evaluator), function, args, kwargs, unpickler=unpickler)
|
||||
return self._send(id(evaluator), function, args, kwargs)
|
||||
|
||||
def get_sys_path(self):
|
||||
return self._send(None, functions.get_sys_path, (), {})
|
||||
@@ -229,30 +247,6 @@ class Listener():
|
||||
stdout.flush()
|
||||
|
||||
|
||||
class _ModifiedUnpickler(pickle._Unpickler):
|
||||
dispatch = pickle._Unpickler.dispatch.copy()
|
||||
|
||||
def __init__(self, subprocess, *args, **kwargs):
|
||||
super(_ModifiedUnpickler, self).__init__(*args, **kwargs)
|
||||
self._subprocess = subprocess
|
||||
|
||||
def load_build(self):
|
||||
super(_ModifiedUnpickler, self).load_build()
|
||||
tos = self.stack[-1]
|
||||
if isinstance(tos, AccessHandle):
|
||||
self.stack[-1] = self.get_access_handle(tos)
|
||||
dispatch[pickle.BUILD[0]] = load_build
|
||||
|
||||
def get_access_handle(self, access_handle):
|
||||
try:
|
||||
# Rewrite the access handle to one we're already having.
|
||||
access_handle = self._subprocess.get_access_handle(access_handle.id)
|
||||
except KeyError:
|
||||
access_handle.add_subprocess(self._subprocess)
|
||||
self._subprocess.set_access_handle(access_handle)
|
||||
return access_handle
|
||||
|
||||
|
||||
class AccessHandle(object):
|
||||
def __init__(self, subprocess, access, id_):
|
||||
self.access = access
|
||||
|
||||
Reference in New Issue
Block a user