mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 22:44:27 +08:00
stderr of the child processes should be printed in debug output
This fixes #1169. It might have a bit of a different intention, but at least it's now possible to see output of the subprocess and it's not just a black hole.
This commit is contained in:
@@ -369,6 +369,7 @@ def print_to_stderr(*args):
|
|||||||
eval("print(*args, file=sys.stderr)")
|
eval("print(*args, file=sys.stderr)")
|
||||||
else:
|
else:
|
||||||
print >> sys.stderr, args
|
print >> sys.stderr, args
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
|
||||||
def utf8_repr(func):
|
def utf8_repr(func):
|
||||||
|
|||||||
@@ -15,9 +15,15 @@ import errno
|
|||||||
import weakref
|
import weakref
|
||||||
import traceback
|
import traceback
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from threading import Thread
|
||||||
|
try:
|
||||||
|
from Queue import Queue, Empty
|
||||||
|
except ImportError:
|
||||||
|
from queue import Queue, Empty # python 3.x
|
||||||
|
|
||||||
from jedi._compatibility import queue, is_py3, force_unicode, \
|
from jedi._compatibility import queue, is_py3, force_unicode, \
|
||||||
pickle_dump, pickle_load, GeneralizedPopen
|
pickle_dump, pickle_load, GeneralizedPopen
|
||||||
|
from jedi import debug
|
||||||
from jedi.cache import memoize_method
|
from jedi.cache import memoize_method
|
||||||
from jedi.evaluate.compiled.subprocess import functions
|
from jedi.evaluate.compiled.subprocess import functions
|
||||||
from jedi.evaluate.compiled.access import DirectObjectAccess, AccessPath, \
|
from jedi.evaluate.compiled.access import DirectObjectAccess, AccessPath, \
|
||||||
@@ -28,6 +34,12 @@ from jedi.api.exceptions import InternalError
|
|||||||
_MAIN_PATH = os.path.join(os.path.dirname(__file__), '__main__.py')
|
_MAIN_PATH = os.path.join(os.path.dirname(__file__), '__main__.py')
|
||||||
|
|
||||||
|
|
||||||
|
def _enqueue_output(out, queue):
|
||||||
|
for line in iter(out.readline, b''):
|
||||||
|
queue.put(line)
|
||||||
|
out.close()
|
||||||
|
|
||||||
|
|
||||||
def _get_function(name):
|
def _get_function(name):
|
||||||
return getattr(functions, name)
|
return getattr(functions, name)
|
||||||
|
|
||||||
@@ -142,7 +154,7 @@ class CompiledSubprocess(object):
|
|||||||
os.path.dirname(os.path.dirname(parso_path)),
|
os.path.dirname(os.path.dirname(parso_path)),
|
||||||
'.'.join(str(x) for x in sys.version_info[:3]),
|
'.'.join(str(x) for x in sys.version_info[:3]),
|
||||||
)
|
)
|
||||||
return GeneralizedPopen(
|
process = GeneralizedPopen(
|
||||||
args,
|
args,
|
||||||
stdin=subprocess.PIPE,
|
stdin=subprocess.PIPE,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
@@ -151,6 +163,14 @@ class CompiledSubprocess(object):
|
|||||||
# (this is already the case on Python 3).
|
# (this is already the case on Python 3).
|
||||||
bufsize=-1
|
bufsize=-1
|
||||||
)
|
)
|
||||||
|
self._stderr_queue = Queue()
|
||||||
|
self._stderr_thread = t = Thread(
|
||||||
|
target=_enqueue_output,
|
||||||
|
args=(process.stderr, self._stderr_queue)
|
||||||
|
)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
return process
|
||||||
|
|
||||||
def run(self, evaluator, function, args=(), kwargs={}):
|
def run(self, evaluator, function, args=(), kwargs={}):
|
||||||
# Delete old evaluators.
|
# Delete old evaluators.
|
||||||
@@ -219,6 +239,15 @@ class CompiledSubprocess(object):
|
|||||||
stderr,
|
stderr,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Try to do some error reporting from the subprocess and print its
|
||||||
|
# stderr contents.
|
||||||
|
try:
|
||||||
|
line = self._stderr_queue.get_nowait()
|
||||||
|
debug.warning('stderr output: %s' % line.rstrip('\n'))
|
||||||
|
except Empty:
|
||||||
|
break
|
||||||
|
|
||||||
if is_exception:
|
if is_exception:
|
||||||
# Replace the attribute error message with a the traceback. It's
|
# Replace the attribute error message with a the traceback. It's
|
||||||
# way more informative.
|
# way more informative.
|
||||||
@@ -282,11 +311,9 @@ class Listener(object):
|
|||||||
|
|
||||||
def listen(self):
|
def listen(self):
|
||||||
stdout = sys.stdout
|
stdout = sys.stdout
|
||||||
# Mute stdout/stderr. Nobody should actually be able to write to those,
|
# Mute stdout. Nobody should actually be able to write to it,
|
||||||
# because stdout is used for IPC and stderr will just be annoying if it
|
# because stdout is used for IPC.
|
||||||
# leaks (on module imports).
|
|
||||||
sys.stdout = open(os.devnull, 'w')
|
sys.stdout = open(os.devnull, 'w')
|
||||||
sys.stderr = open(os.devnull, 'w')
|
|
||||||
stdin = sys.stdin
|
stdin = sys.stdin
|
||||||
if sys.version_info[0] > 2:
|
if sys.version_info[0] > 2:
|
||||||
stdout = stdout.buffer
|
stdout = stdout.buffer
|
||||||
|
|||||||
Reference in New Issue
Block a user