From 969d029499c98da429c5857baa5f20eb8a97f34e Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Sun, 12 Nov 2017 11:46:35 +0100 Subject: [PATCH] Some subprocess progress --- jedi/evaluate/compiled/subprocess/__init__.py | 64 +++++++++++++++++++ jedi/evaluate/compiled/subprocess/__main__.py | 3 + 2 files changed, 67 insertions(+) create mode 100644 jedi/evaluate/compiled/subprocess/__init__.py create mode 100644 jedi/evaluate/compiled/subprocess/__main__.py diff --git a/jedi/evaluate/compiled/subprocess/__init__.py b/jedi/evaluate/compiled/subprocess/__init__.py new file mode 100644 index 00000000..028f6d68 --- /dev/null +++ b/jedi/evaluate/compiled/subprocess/__init__.py @@ -0,0 +1,64 @@ +""" +Makes it possible to do the compiled analysis in a subprocess. This has two +goals: + +1. Making it safer - Segfaults and RuntimeErrors as well as stdout/stderr can + be ignored and dealt with. +2. Make it possible to handle different Python versions as well as virtualenvs. +""" + +import sys +import subprocess +import pickle + +_PICKLE_PROTOCOL = 2 + + +class _SubProcess(object): + def __init__(self, args): + self._process = subprocess.Popen( + args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + #stderr=subprocess.PIPE + ) + + def _send(self, data): + pickle.dump(data, self._process.stdin, protocol=_PICKLE_PROTOCOL) + self._process.stdin.flush() + return pickle.load(self._process.stdout) + + def terminate(self): + self._process.terminate() + + def kill(self): + self._process.kill() + + +class CompiledSubProcess(object): + def __init__(self, executable): + super(CompiledSubProcess, self).__init__( + (executable, '-m', 'jedi.evaluate.compiled.subprocess') + ) + + def command(self): + return self._send() + + +def listen(): + stdout = sys.stdout + stdin = sys.stdin + if sys.version_info[0] > 2: + stdout = stdout.buffer + stdin = stdin.buffer + + while True: + try: + result = pickle.load(stdin) + except EOFError: + # It looks like the parent process closed. Don't make a big fuss + # here and just exit. + exit(1) + result += 1 + pickle.dump(result, stdout, protocol=_PICKLE_PROTOCOL) + stdout.flush() diff --git a/jedi/evaluate/compiled/subprocess/__main__.py b/jedi/evaluate/compiled/subprocess/__main__.py new file mode 100644 index 00000000..31db417c --- /dev/null +++ b/jedi/evaluate/compiled/subprocess/__main__.py @@ -0,0 +1,3 @@ +from jedi.evaluate.compiled import subprocess + +subprocess.listen()