diff --git a/ptvsd/pydevd/_pydevd_bundle/pydevd_comm.py b/ptvsd/pydevd/_pydevd_bundle/pydevd_comm.py index 3313797a..c965b4f9 100644 --- a/ptvsd/pydevd/_pydevd_bundle/pydevd_comm.py +++ b/ptvsd/pydevd/_pydevd_bundle/pydevd_comm.py @@ -47,6 +47,11 @@ each command has a format: 119 CMD_RELOAD_CODE 120 CMD_GET_COMPLETIONS JAVA + 200 CMD_REDIRECT_OUTPUT JAVA streams to redirect as string - + 'STDOUT' (redirect only STDOUT) + 'STDERR' (redirect only STDERR) + 'STDOUT STDERR' (redirect both streams) + 500 series diagnostics/ok 501 VERSION either Version string (1.0) Currently just used at startup 502 RETURN either Depends on caller - @@ -147,6 +152,8 @@ CMD_GET_DESCRIPTION = 148 CMD_PROCESS_CREATED = 149 +CMD_REDIRECT_OUTPUT = 200 + CMD_VERSION = 501 CMD_RETURN = 502 CMD_ERROR = 901 @@ -204,6 +211,8 @@ ID_TO_MEANING = { '149': 'CMD_PROCESS_CREATED', + '200': 'CMD_REDIRECT_OUTPUT', + '501': 'CMD_VERSION', '502': 'CMD_RETURN', '901': 'CMD_ERROR', diff --git a/ptvsd/pydevd/_pydevd_bundle/pydevd_process_net_command.py b/ptvsd/pydevd/_pydevd_bundle/pydevd_process_net_command.py index 5931e3e5..868187e7 100644 --- a/ptvsd/pydevd/_pydevd_bundle/pydevd_process_net_command.py +++ b/ptvsd/pydevd/_pydevd_bundle/pydevd_process_net_command.py @@ -18,7 +18,7 @@ from _pydevd_bundle.pydevd_comm import CMD_RUN, CMD_VERSION, CMD_LIST_THREADS, C CMD_REMOVE_EXCEPTION_BREAK, CMD_LOAD_SOURCE, CMD_ADD_DJANGO_EXCEPTION_BREAK, CMD_REMOVE_DJANGO_EXCEPTION_BREAK, \ CMD_EVALUATE_CONSOLE_EXPRESSION, InternalEvaluateConsoleExpression, InternalConsoleGetCompletions, \ CMD_RUN_CUSTOM_OPERATION, InternalRunCustomOperation, CMD_IGNORE_THROWN_EXCEPTION_AT, CMD_ENABLE_DONT_TRACE, \ - CMD_SHOW_RETURN_VALUES, ID_TO_MEANING, CMD_GET_DESCRIPTION, InternalGetDescription + CMD_SHOW_RETURN_VALUES, ID_TO_MEANING, CMD_GET_DESCRIPTION, InternalGetDescription, CMD_REDIRECT_OUTPUT from _pydevd_bundle.pydevd_constants import get_thread_id, IS_PY3K, DebugInfoHolder, dict_keys, \ STATE_RUN @@ -679,6 +679,10 @@ def process_net_command(py_db, cmd_id, seq, text): mode = text.strip() == true_str pydevd_dont_trace.trace_filter(mode) + elif cmd_id == CMD_REDIRECT_OUTPUT: + if text: + py_db.enable_output_redirection('STDOUT' in text, 'STDERR' in text) + else: #I have no idea what this is all about cmd = py_db.cmd_factory.make_error_message(seq, "unexpected command " + str(cmd_id)) @@ -705,5 +709,3 @@ def process_net_command(py_db, cmd_id, seq, text): py_db.writer.add_command(cmd) finally: py_db._main_lock.release() - - diff --git a/ptvsd/pydevd/pydevd.py b/ptvsd/pydevd/pydevd.py index b9221dd8..623ce2ce 100644 --- a/ptvsd/pydevd/pydevd.py +++ b/ptvsd/pydevd/pydevd.py @@ -257,6 +257,7 @@ class PyDB: self.is_filter_libraries = pydevd_utils.is_filter_libraries() self.show_return_values = False self.remove_return_values_flag = False + self.redirect_output = False # this flag disables frame evaluation even if it's available self.do_not_use_frame_eval = False @@ -351,6 +352,18 @@ class PyDB: queue = self.get_internal_queue(thread_id) queue.put(int_cmd) + def enable_output_redirection(self, redirect_stdout, redirect_stderr): + global bufferStdOutToServer + global bufferStdErrToServer + + bufferStdOutToServer = redirect_stdout + bufferStdErrToServer = redirect_stderr + self.redirect_output = redirect_stdout or redirect_stderr + if bufferStdOutToServer: + init_stdout_redirect() + if bufferStdErrToServer: + init_stderr_redirect() + def check_output_redirect(self): global bufferStdOutToServer global bufferStdErrToServer @@ -908,7 +921,7 @@ class PyDB: # functions, because frame evaluation function is set to all threads by default. PyDBCommandThread(self).start() - if self.signature_factory is not None or self.thread_analyser is not None: + if self.redirect_output or self.signature_factory is not None or self.thread_analyser is not None: # we need all data to be sent to IDE even after program finishes CheckOutputThread(self).start()