コード例 #1
0
    def _cmd_cd(self, cmd):
        if len(cmd.args) == 1:
            if not self._supports_directories():
                raise UserError("This device doesn't have directories")

            path = cmd.args[0]
            self._execute("__thonny_helper.chdir(%r)" % path)
            self._update_cwd()
            return {}
        else:
            raise UserError("%cd takes one parameter")
コード例 #2
0
    def _cmd_cd(self, cmd):
        if len(cmd.args) == 1:
            if not self._supports_directories():
                raise UserError("This device doesn't have directories")

            path = cmd.args[0]
            self._execute("import os as __thonny_os; __module_os.chdir(%r)" %
                          path)
            return {}
        else:
            raise UserError("%cd takes one parameter")
コード例 #3
0
 def _cmd_cd(self, cmd):
     if len(cmd.args) == 1:
         path = cmd.args[0]
         try:
             os.chdir(path)
             return ToplevelResponse()
         except FileNotFoundError:
             raise UserError("No such folder: " + path)
         except OSError as e:
             raise UserError(str(e))
     else:
         raise UserError("cd takes one parameter")
コード例 #4
0
ファイル: bare_metal_backend.py プロジェクト: phaggi/thonny
    def _cmd_cd(self, cmd):
        if len(cmd.args) == 1:
            if not self._supports_directories():
                raise UserError("This device doesn't have directories")

            path = cmd.args[0]
            self._execute_without_output(
                "import os as __thonny_helper.os; __thonny_helper.os.chdir(%r)"
                % path)
            self._cwd = self._fetch_cwd()
            return {}
        else:
            raise UserError("%cd takes one parameter")
コード例 #5
0
ファイル: __init__.py プロジェクト: ZCG-coder/thonny
 def _cmd_cd(self, cmd):
     if len(cmd.args) == 1:
         path = cmd.args[0]
         try:
             os.chdir(path)
             return ToplevelResponse()
         except FileNotFoundError:
             raise UserError("No such folder: " + path)
         except OSError as e:
             raise UserError("\n".join(
                 traceback.format_exception_only(type(e), e)))
     else:
         raise UserError("cd takes one parameter")
コード例 #6
0
ファイル: running.py プロジェクト: jsisj/thonny
    def restart_backend(self,
                        clean: bool,
                        first: bool = False,
                        wait: float = 0) -> None:
        """Recreate (or replace) backend proxy / backend process."""

        if not first:
            get_shell().restart()
            get_shell().update_idletasks()

        self.destroy_backend()
        backend_name = get_workbench().get_option("run.backend_name")
        if backend_name not in get_workbench().get_backends():
            raise UserError(
                "Can't find backend '{}'. Please select another backend from options"
                .format(backend_name))

        backend_class = get_workbench().get_backends(
        )[backend_name].proxy_class
        self._set_state("running")
        self._proxy = None
        self._proxy = backend_class(clean)

        self._poll_vm_messages()

        if wait:
            start_time = time.time()
            while not self.is_waiting_toplevel_command(
            ) and time.time() - start_time <= wait:
                # self._pull_vm_messages()
                get_workbench().update()
                sleep(0.01)

        get_workbench().event_generate("BackendRestart")
コード例 #7
0
    def _execute_file(self, cmd, executor_class):
        self._check_update_tty_mode(cmd)

        if len(cmd.args) >= 1:
            sys.argv = cmd.args
            filename = cmd.args[0]
            if os.path.isabs(filename):
                full_filename = filename
            else:
                full_filename = os.path.abspath(filename)

            with tokenize.open(full_filename) as fp:
                source = fp.read()

            for preproc in self._source_preprocessors:
                source = preproc(source, cmd)

            result_attributes = self._execute_source(source, full_filename,
                                                     "exec", executor_class,
                                                     cmd,
                                                     self._ast_postprocessors)
            result_attributes["filename"] = full_filename
            return ToplevelResponse(command_name=cmd.name, **result_attributes)
        else:
            raise UserError("Command '%s' takes at least one argument" %
                            cmd.name)
コード例 #8
0
    def __init__(self, clean: bool, executable: Optional[str] = None) -> None:
        super().__init__(clean)

        if executable:
            self._executable = executable
        else:
            self._executable = get_interpreter_for_subprocess()

        if ".." in self._executable:
            self._executable = os.path.normpath(self._executable)

        if not os.path.isfile(self._executable):
            raise UserError(
                "Interpreter '%s' does not exist. Please check the configuration!"
                % self._executable
            )
        self._welcome_text = ""

        self._proc = None
        self._terminated_readers = 0
        self._response_queue = None
        self._sys_path = []
        self._usersitepackages = None
        self._gui_update_loop_id = None
        self._in_venv = None
        self._cwd = self._get_initial_cwd()  # pylint: disable=assignment-from-none
        self._start_background_process(clean=clean)
コード例 #9
0
ファイル: running.py プロジェクト: tigerg2002/thonny
    def _start_background_process(self, clean=None):
        # deque, because in one occasion I need to put messages back
        self._response_queue = collections.deque()

        # prepare environment
        env = get_environment_for_python_subprocess(self._executable)
        # variables controlling communication with the back-end process
        env["PYTHONIOENCODING"] = "utf-8"

        # because cmd line option -u won't reach child processes
        # see https://github.com/thonny/thonny/issues/808
        env["PYTHONUNBUFFERED"] = "1"

        # Let back-end know about plug-ins
        env["THONNY_USER_DIR"] = THONNY_USER_DIR
        env["THONNY_FRONTEND_SYS_PATH"] = repr(sys.path)

        if get_workbench().in_debug_mode():
            env["THONNY_DEBUG"] = "1"
        elif "THONNY_DEBUG" in env:
            del env["THONNY_DEBUG"]

        if not os.path.exists(self._executable):
            raise UserError(
                "Interpreter (%s) not found. Please recheck corresponding option!"
                % self._executable)

        cmd_line = [
            self._executable,
            "-u",  # unbuffered IO
            "-B",  # don't write pyo/pyc files
            # (to avoid problems when using different Python versions without write permissions)
        ] + self._get_launcher_with_args()

        creationflags = 0
        if running_on_windows():
            creationflags = subprocess.CREATE_NEW_PROCESS_GROUP

        debug("Starting the backend: %s %s", cmd_line,
              get_workbench().get_local_cwd())
        self._proc = subprocess.Popen(
            cmd_line,
            # bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self.get_cwd() if self.uses_local_filesystem() else None,
            env=env,
            universal_newlines=True,
            creationflags=creationflags,
        )

        # setup asynchronous output listeners
        Thread(target=self._listen_stdout,
               args=(self._proc.stdout, ),
               daemon=True).start()
        Thread(target=self._listen_stderr,
               args=(self._proc.stderr, ),
               daemon=True).start()
コード例 #10
0
 def _cmd_Reset(self, cmd):
     if len(cmd.args) == 0:
         # nothing to do, because Reset always happens in fresh process
         return ToplevelResponse(
             command_name="Reset",
             welcome_text="Python " + _get_python_version_string(),
             executable=sys.executable,
         )
     else:
         raise UserError("Command 'Reset' doesn't take arguments")
コード例 #11
0
 def reset_backend(self):
     self.kill_backend()
     configuration = get_workbench().get_option("run.backend_configuration")
     backend_name, configuration_option = parse_configuration(configuration)
     if backend_name not in get_workbench().get_backends():
         raise UserError("Can't find backend '{}'. Please select another backend from options"
                         .format(backend_name))
     
     backend_class = get_workbench().get_backends()[backend_name]
     self._set_state("running")
     self._proxy = None
     self._proxy = backend_class(configuration_option)
コード例 #12
0
    def _start_background_process(self, clean=None, extra_args=[]):
        # deque, because in one occasion I need to put messages back
        self._response_queue = collections.deque()

        if not os.path.exists(self._executable):
            raise UserError(
                "Interpreter (%s) not found. Please recheck corresponding option!"
                % self._executable
            )

        cmd_line = (
            [
                self._executable,
                "-u",  # unbuffered IO
                "-B",  # don't write pyo/pyc files
                # (to avoid problems when using different Python versions without write permissions)
            ]
            + self._get_launcher_with_args()
            + extra_args
        )

        creationflags = 0
        if running_on_windows():
            creationflags = subprocess.CREATE_NEW_PROCESS_GROUP

        debug("Starting the backend: %s %s", cmd_line, get_workbench().get_local_cwd())

        extra_params = {}
        if sys.version_info >= (3, 6):
            extra_params["encoding"] = "utf-8"

        self._proc = subprocess.Popen(
            cmd_line,
            bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self._get_launch_cwd(),
            env=self._get_environment(),
            universal_newlines=True,
            creationflags=creationflags,
            **extra_params
        )

        # setup asynchronous output listeners
        self._terminated_readers = 0
        Thread(target=self._listen_stdout, args=(self._proc.stdout,), daemon=True).start()
        Thread(target=self._listen_stderr, args=(self._proc.stderr,), daemon=True).start()
コード例 #13
0
 def _cmd_cd(self, cmd):
     if len(cmd.args) == 1:
         path = cmd.args[0]
         self._execute_without_errors(
             dedent("""
             import sys as _thonny_sys
             try:
                 if _thonny_sys.modules["_thonny_libc"].func("i", "chdir", "s")(%r) != 0:
                     raise OSError("cd failed")
             finally:
                 del _thonny_sys
         """) % path)
         self._cwd = self._fetch_cwd()
         return {}
     else:
         raise UserError("%cd takes one parameter")
コード例 #14
0
    def _write_file_via_serial(self, cmd):
        data = cmd["content_bytes"]

        # Don't create too long commands
        BUFFER_SIZE = 512

        # prelude
        out, err, __ = self._execute(
            dedent("""
            __temp_path = '{path}'
            __temp_f = open(__temp_path, 'wb')
            __temp_written = 0
            """).format(path=cmd["path"]),
            capture_output=True,
        )

        if out:
            self._send_output(out, "stdout")
        if err:
            self._send_output(err, "stderr")
        if out or err:
            return

        size = len(data)
        for i in range(0, size, BUFFER_SIZE):
            chunk_size = min(BUFFER_SIZE, size - i)
            chunk = data[i:i + chunk_size]
            self._execute(
                "__temp_written += __temp_f.write({chunk!r})".format(
                    chunk=chunk),
                capture_output=True,
            )

        bytes_written = self._evaluate(
            "__temp_written",
            cleanup=dedent("""
                __temp_f.close()
                del __temp_f
                del __temp_written
                del __temp_path
            """),
        )

        if bytes_written != size:
            raise UserError("Expected %d written bytes but wrote %d" %
                            (size, bytes_written))
コード例 #15
0
    def _write_file_via_serial(
        self,
        source_fp: BinaryIO,
        target_path: str,
        file_size: int,
        callback: Callable[[int, int], None],
    ) -> None:
        out, err = self._execute(
            dedent("""
            try:
                __thonny_path = '{path}'
                __thonny_written = 0
                __thonny_fp = open(__thonny_path, 'wb')
            except Exception as e:
                print(str(e))
            """).format(path=target_path),
            capture_output=True,
        )

        if "readonly" in (out + err).replace("-", "").lower():
            raise ReadOnlyFilesystemError()
        elif out + err:
            raise RuntimeError(
                "Could not open file %s for writing, output:\n%s" %
                (target_path, out + err))

        # Define function to allow shorter write commands
        hex_mode = self._should_hexlify(target_path)
        if hex_mode:
            self._execute_without_output(
                dedent("""
                from binascii import unhexlify as __thonny_unhex
                def __W(x):
                    global __thonny_written
                    __thonny_written += __thonny_fp.write(__thonny_unhex(x))
                    __thonny_fp.flush()
                    if hasattr(__thonny_helper.os, "sync"):
                        __thonny_helper.os.sync()
            """))
        elif self._connected_to_microbit():
            # doesn't have neither BytesIO.flush, nor os.sync
            self._execute_without_output(
                dedent("""
                def __W(x):
                    global __thonny_written
                    __thonny_written += __thonny_fp.write(x)
            """))
        else:
            self._execute_without_output(
                dedent("""
                def __W(x):
                    global __thonny_written
                    __thonny_written += __thonny_fp.write(x)
                    __thonny_fp.flush()
                    if hasattr(__thonny_helper.os, "sync"):
                        __thonny_helper.os.sync()
            """))

        bytes_sent = 0
        block_size = 512
        while True:
            callback(bytes_sent, file_size)
            block = source_fp.read(block_size)

            if block:
                if hex_mode:
                    script = "__W(%r)" % binascii.hexlify(block)
                else:
                    script = "__W(%r)" % block
                out, err = self._execute(script, capture_output=True)
                if out or err:
                    self._show_error(
                        "\nCould not write next block after having written %d bytes to %s"
                        % (bytes_sent, target_path))
                    if bytes_sent > 0:
                        self._show_error(
                            "Make sure your device's filesystem has enough free space. "
                            +
                            "(When overwriting a file, the old content may occupy space "
                            "until the end of the operation.)\n")
                    raise ManagementError(script, out, err)
                bytes_sent += len(block)

            if len(block) < block_size:
                break

        bytes_received = self._evaluate("__thonny_written")

        if bytes_received != bytes_sent:
            raise UserError("Expected %d written bytes but wrote %d" %
                            (bytes_sent, bytes_received))

        # clean up
        self._execute_without_output(
            dedent("""
                try:
                    del __W
                    del __thonny_written
                    del __thonny_path
                    __thonny_fp.close()
                    del __thonny_fp
                    del __thonny_result
                    del __thonny_unhex
                except:
                    pass
            """))

        return bytes_sent
コード例 #16
0
ファイル: running.py プロジェクト: byache/thonny
    def _start_new_process(self, cmd=None):
        this_python = get_runner().get_frontend_python()
        # deque, because in one occasion I need to put messages back
        self._message_queue = collections.deque()

        # prepare the environment
        my_env = os.environ.copy()

        # Delete some environment variables if the backend is (based on) a different Python instance
        if self._executable not in [
                this_python,
                this_python.replace("python.exe", "pythonw.exe"),
                this_python.replace("pythonw.exe", "python.exe"),
                get_private_venv_executable()
        ]:

            # Keep only the variables, that are not related to Python
            my_env = {
                name: my_env[name]
                for name in my_env if "python" not in name.lower()
                and name not in ["TK_LIBRARY", "TCL_LIBRARY"]
            }

            # Remove variables used to tweak bundled Thonny-private Python
            if using_bundled_python():
                my_env = {
                    name: my_env[name]
                    for name in my_env if name not in
                    ["SSL_CERT_FILE", "SSL_CERT_DIR", "LD_LIBRARY_PATH"]
                }

        # variables controlling communication with the back-end process
        my_env["PYTHONIOENCODING"] = "ASCII"
        my_env["PYTHONUNBUFFERED"] = "1"

        my_env["THONNY_USER_DIR"] = THONNY_USER_DIR

        # venv may not find (correct) Tk without assistance (eg. in Ubuntu)
        if self._executable == get_private_venv_executable():
            try:
                my_env["TCL_LIBRARY"] = get_workbench().tk.exprstring(
                    '$tcl_library')
                my_env["TK_LIBRARY"] = get_workbench().tk.exprstring(
                    '$tk_library')
            except:
                logging.exception("Can't find Tcl/Tk library")

        # If the back-end interpreter is something else than front-end's one,
        # then it may not have jedi installed.
        # In this case fffer front-end's jedi for the back-end
        if self._executable != get_runner().get_frontend_python():
            # I don't want to use PYTHONPATH for making jedi available
            # because that would add it to the front of sys.path
            my_env["JEDI_LOCATION"] = self._prepare_jedi()

        if not os.path.exists(self._executable):
            raise UserError(
                "Interpreter (%s) not found. Please recheck corresponding option!"
                % self._executable)

        import thonny.shared.backend_launcher
        cmd_line = [
            self._executable,
            '-u',  # unbuffered IO (neccessary in Python 3.1)
            '-B',  # don't write pyo/pyc files
            # (to avoid problems when using different Python versions without write permissions)
            thonny.shared.backend_launcher.__file__
        ]

        if hasattr(cmd, "filename"):
            cmd_line.append(cmd.filename)
            if hasattr(cmd, "args"):
                cmd_line.extend(cmd.args)

        if hasattr(cmd, "environment"):
            my_env.update(cmd.environment)

        creationflags = 0
        if running_on_windows():
            creationflags = subprocess.CREATE_NEW_PROCESS_GROUP

        debug("Starting the backend: %s %s", cmd_line, self.cwd)
        self._proc = subprocess.Popen(
            cmd_line,
            #bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self.cwd,
            env=my_env,
            universal_newlines=True,
            creationflags=creationflags)

        if cmd:
            # Consume the ready message, cmd will get its own result message
            ready_line = self._proc.stdout.readline()
            if ready_line == "":  # There was some problem
                error_msg = self._proc.stderr.read()
                raise Exception("Error starting backend process: " + error_msg)

            #ready_msg = parse_message(ready_line)
            #self._sys_path = ready_msg["path"]
            #debug("Backend ready: %s", ready_msg)

        # setup asynchronous output listeners
        start_new_thread(self._listen_stdout, ())
        start_new_thread(self._listen_stderr, ())
コード例 #17
0
ファイル: running.py プロジェクト: jsisj/thonny
    def _start_new_process(self, cmd=None):
        # deque, because in one occasion I need to put messages back
        self._message_queue = collections.deque()

        # prepare environment
        my_env = get_environment_for_python_subprocess(self._executable)
        # variables controlling communication with the back-end process
        my_env["PYTHONIOENCODING"] = "utf-8"

        # Let back-end know about plug-ins
        my_env["THONNY_USER_DIR"] = THONNY_USER_DIR

        if get_workbench().in_debug_mode():
            my_env["THONNY_DEBUG"] = "1"
        elif "THONNY_DEBUG" in my_env:
            del my_env["THONNY_DEBUG"]

        if not os.path.exists(self._executable):
            raise UserError(
                "Interpreter (%s) not found. Please recheck corresponding option!"
                % self._executable)

        import thonny.backend_launcher

        cmd_line = [
            self._executable,
            "-u",  # unbuffered IO
            "-B",  # don't write pyo/pyc files
            # (to avoid problems when using different Python versions without write permissions)
            thonny.backend_launcher.__file__,
        ]

        if hasattr(cmd, "filename"):
            cmd_line.append(cmd.filename)
            if hasattr(cmd, "args"):
                cmd_line.extend(cmd.args)

        if hasattr(cmd, "environment"):
            my_env.update(cmd.environment)

        creationflags = 0
        if running_on_windows():
            creationflags = subprocess.CREATE_NEW_PROCESS_GROUP

        debug("Starting the backend: %s %s", cmd_line,
              get_workbench().get_local_cwd())
        self._proc = subprocess.Popen(
            cmd_line,
            # bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=get_workbench().get_local_cwd(),
            env=my_env,
            universal_newlines=True,
            creationflags=creationflags,
        )

        # send init message
        self._send_msg({"frontend_sys_path": sys.path})

        if cmd:
            # Consume the ready message, cmd will get its own result message
            ready_line = self._proc.stdout.readline()
            if ready_line == "":  # There was some problem
                error_msg = self._proc.stderr.read()
                raise Exception("Error starting backend process: " + error_msg)
            self._store_state_info(parse_message(ready_line))

        # setup asynchronous output listeners
        Thread(target=self._listen_stdout, daemon=True).start()
        Thread(target=self._listen_stderr, daemon=True).start()
コード例 #18
0
    def _write_file_via_serial(self, content_blocks, target_path, notifier=None):
        result = self._evaluate(
            dedent(
                """
            try:
                __thonny_path = '{path}'
                __thonny_written = 0
                __thonny_fp = open(__thonny_path, 'wb')
                __thonny_result = "OK"
            except Exception as e:
                __thonny_result = str(e)
            
            __thonny_helper.print_mgmt_value(__thonny_result)
            
            del __thonny_result
            """
            ).format(path=target_path),
        )

        if "readonly" in result.replace("-", "").lower():
            raise ReadOnlyFilesystemError()

        elif result != "OK":
            raise RuntimeError("Problem opening file for writing: " + result)

        # Define function to allow shorter write commands
        hex_mode = self._should_hexlify(target_path)
        if hex_mode:
            self._execute_without_output(
                dedent(
                    """
                from binascii import unhexlify as __thonny_unhex
                def __W(x):
                    global __thonny_written
                    __thonny_written += __thonny_fp.write(__thonny_unhex(x))
                    __thonny_fp.flush()
            """
                )
            )
        else:
            self._execute_without_output(
                dedent(
                    """
                def __W(x):
                    global __thonny_written
                    __thonny_written += __thonny_fp.write(x)
            """
                )
            )

        bytes_sent = 0
        for block in content_blocks:
            if hex_mode:
                script = "__W(%r)" % binascii.hexlify(block)
            else:
                script = "__W(%r)" % block
            self._execute_without_output(script)
            bytes_sent += len(block)
            if notifier is not None:
                notifier(bytes_sent)

        bytes_received = self._evaluate("__thonny_written")

        if bytes_received != bytes_sent:
            raise UserError("Expected %d written bytes but wrote %d" % (bytes_sent, bytes_received))

        # clean up
        self._execute_without_output(
            dedent(
                """
                try:
                    del __W
                    del __thonny_written
                    del __thonny_path
                    __thonny_fp.close()
                    del __thonny_fp
                    del __thonny_result
                    del __thonny_unhex
                except:
                    pass
            """
            )
        )

        return bytes_sent
コード例 #19
0
ファイル: running.py プロジェクト: Blue-Design/thonny
    def _start_new_process(self, cmd):
        self._message_queue = collections.deque()
    
        # create new backend process
        my_env = {}
        for name in os.environ:
            if ("python" not in name.lower() # skip python vars, because we may use different Python version
                and name not in ["TK_LIBRARY", "TCL_LIBRARY"]): # They tend to point to frontend Python installation 
                my_env[name] = os.environ[name]
        
        # TODO: take care of SSL_CERT_FILE
        # Unset when we're in builtin python and target python is external
                
        my_env["PYTHONIOENCODING"] = "ASCII" 
        my_env["PYTHONUNBUFFERED"] = "1" 
        
        if not os.path.exists(self._executable):
            raise UserError("Interpreter (%s) not found. Please recheck corresponding option!"
                            % self._executable)
        
        
        if is_private_interpreter(self._executable):
            # in gui environment make "pip install"
            # use a folder outside thonny installation
            # in order to keep packages after reinstalling Thonny 
            my_env["PIP_USER"] = "******"
            my_env["PYTHONUSERBASE"] = THONNY_USER_DIR
        
        backend_launcher = os.path.join(get_workbench().get_package_dir(), 
                                        "backend_private",
                                        "thonny_backend.py") 
        
        if not os.path.exists(backend_launcher):
            # in dev machine use the main source
            backend_launcher = os.path.realpath(
                os.path.join(get_workbench().get_package_dir(), 
                             "..",
                             "thonny_backend.py")
            ) 
             
        
        cmd_line = [
            self._executable, 
            '-u', # unbuffered IO (neccessary in Python 3.1)
            '-B', # don't write pyo/pyc files 
                  # (to avoid problems when using different Python versions without write permissions)
            backend_launcher
        ]
        

        if hasattr(cmd, "filename"):
            cmd_line.append(cmd.filename)
            if hasattr(cmd, "args"):
                cmd_line.extend(cmd.args)
        
        if hasattr(cmd, "environment"):
            my_env.update(cmd.environment)            
        
        debug("Starting the backend: %s %s", cmd_line, self.cwd)
        self._proc = subprocess.Popen (
            cmd_line,
            #bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self.cwd,
            env=my_env,
            universal_newlines=True
        )
        
        ready_line = self._proc.stdout.readline()
        if ready_line == "": # There was some problem
            error_msg = self._proc.stderr.read()
            raise Exception("Error starting backend process: " + error_msg)
        
        ready_msg = parse_message(ready_line)
        debug("Backend ready: %s", ready_msg)
        get_workbench().event_generate("BackendReady", **ready_msg)
        
        # setup asynchronous output listeners
        start_new_thread(self._listen_stdout, ())
        start_new_thread(self._listen_stderr, ())
コード例 #20
0
    def _start_new_process(self, cmd=None):
        # deque, because in one occasion I need to put messages back
        self._message_queue = collections.deque()
    
        # create new backend process
        my_env = {}
        for name in os.environ:
            if ("python" not in name.lower() # skip python vars, because we may use different Python version
                and name not in ["TK_LIBRARY", "TCL_LIBRARY"]): # They tend to point to frontend Python installation 
                my_env[name] = os.environ[name]
        
        # TODO: take care of SSL_CERT_FILE
        # Unset when we're in builtin python and target python is external
        # And set, wen we're in external and target is builtin (or it's venv)
                
        my_env["PYTHONIOENCODING"] = "ASCII" 
        my_env["PYTHONUNBUFFERED"] = "1" 
        my_env["THONNY_USER_DIR"] = THONNY_USER_DIR
        
        # venv may not find (correct) Tk without assistance (eg. in Ubuntu)
        if self._executable == get_private_venv_executable():
            try:
                my_env["TCL_LIBRARY"] = get_workbench().tk.exprstring('$tcl_library')
                my_env["TK_LIBRARY"] = get_workbench().tk.exprstring('$tk_library')
            except:
                logging.exception("Can't find Tcl/Tk library")
        
        # I don't want to use PYTHONPATH for making jedi available
        # because that would add it to the front of sys.path
        my_env["JEDI_LOCATION"] = self._prepare_jedi()
        
        if not os.path.exists(self._executable):
            raise UserError("Interpreter (%s) not found. Please recheck corresponding option!"
                            % self._executable)
        
        
        import thonny.shared.backend_launcher
        cmd_line = [
            self._executable, 
            '-u', # unbuffered IO (neccessary in Python 3.1)
            '-B', # don't write pyo/pyc files 
                  # (to avoid problems when using different Python versions without write permissions)
            thonny.shared.backend_launcher.__file__
        ]
        

        if hasattr(cmd, "filename"):
            cmd_line.append(cmd.filename)
            if hasattr(cmd, "args"):
                cmd_line.extend(cmd.args)
        
        if hasattr(cmd, "environment"):
            my_env.update(cmd.environment)            
        
        creationflags = 0
        if running_on_windows():
            creationflags = subprocess.CREATE_NEW_PROCESS_GROUP
        
        debug("Starting the backend: %s %s", cmd_line, self.cwd)
        self._proc = subprocess.Popen (
            cmd_line,
            #bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self.cwd,
            env=my_env,
            universal_newlines=True,
            creationflags=creationflags
        )
        
        if cmd:
            # Consume the ready message, cmd will get its own result message
            ready_line = self._proc.stdout.readline()
            if ready_line == "": # There was some problem
                error_msg = self._proc.stderr.read()
                raise Exception("Error starting backend process: " + error_msg)
            
            #ready_msg = parse_message(ready_line)
            #self._sys_path = ready_msg["path"]
            #debug("Backend ready: %s", ready_msg)
        
        
        
        # setup asynchronous output listeners
        start_new_thread(self._listen_stdout, ())
        start_new_thread(self._listen_stderr, ())