def _create_venv(self): path = askdirectory( parent=self.winfo_toplevel(), initialdir=None, title=tr( "Select an existing virtual environemnt or an empty directory for new virtual environment" ), ) assert os.path.isdir(path) path = normpath_with_actual_case(path) if not os.listdir(path): proc = subprocess.Popen( [running.get_interpreter_for_subprocess(), "-m", "venv", path], stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, ) dlg = SubprocessDialog(self, proc, tr("Creating virtual environment")) ui_utils.show_dialog(dlg) if running_on_windows(): exe_path = normpath_with_actual_case( os.path.join(path, "Scripts", "python.exe")) else: exe_path = os.path.join(path, "bin", "python3") if os.path.exists(exe_path): self._configuration_variable.set(exe_path) else: # Undefined error handling. pass
def _create_private_venv(self, path, description, clear=False, upgrade=False): base_exe = sys.executable if sys.executable.endswith("thonny.exe"): # assuming that thonny.exe is in the same dir as "python.exe" base_exe = sys.executable.replace("thonny.exe", "python.exe") # Don't include system site packages # This way all students will have similar configuration # independently of system Python (if Thonny is used with system Python) # NB! Cant run venv.create directly, because in Windows # it tries to link venv to thonny.exe. # Need to run it via proper python cmd = [base_exe, "-m", "venv"] if clear: cmd.append("--clear") if upgrade: cmd.append("--upgrade") try: import ensurepip # @UnusedImport except ImportError: cmd.append("--without-pip") cmd.append(path) startupinfo = None if running_on_windows(): startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW proc = subprocess.Popen(cmd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) from thonny.ui_utils import SubprocessDialog dlg = SubprocessDialog(get_workbench(), proc, "Preparing the backend", long_description=description) try: get_workbench().wait_window(dlg) except: # if using --without-pip the dialog may close very quickly # and for some reason wait_window would give error then logging.exception("Problem with waiting for venv creation dialog") get_workbench().become_topmost_window() # Otherwise focus may get stuck somewhere bindir = os.path.dirname(get_private_venv_executable()) # create private env marker marker_path = os.path.join(bindir, "is_private") with open(marker_path, mode="w") as fp: fp.write("# This file marks Thonny-private venv") # Create recommended pip conf to get rid of list deprecation warning # https://github.com/pypa/pip/issues/4058 pip_conf = "pip.ini" if running_on_windows() else "pip.conf" with open(os.path.join(path, pip_conf), mode="w") as fp: fp.write("[list]\nformat = columns") assert os.path.isdir(path)
def _create_private_venv(self, path, description, clear=False, upgrade=False): # Don't include system site packages # This way all students will have similar configuration # independently of system Python (if Thonny is used with system Python) # NB! Cant run venv.create directly, because in Windows # it tries to link venv to thonny.exe. # Need to run it via proper python args = ["-m", "venv"] if clear: args.append("--clear") if upgrade: args.append("--upgrade") try: # pylint: disable=unused-variable import ensurepip # @UnusedImport except ImportError: args.append("--without-pip") args.append(path) proc = create_frontend_python_process(args) from thonny.ui_utils import SubprocessDialog dlg = SubprocessDialog(get_workbench(), proc, "Preparing the backend", long_description=description) try: ui_utils.show_dialog(dlg) except Exception: # if using --without-pip the dialog may close very quickly # and for some reason wait_window would give error then logging.exception("Problem with waiting for venv creation dialog") get_workbench().become_active_window( ) # Otherwise focus may get stuck somewhere bindir = os.path.dirname(get_private_venv_executable()) # create private env marker marker_path = os.path.join(bindir, "is_private") with open(marker_path, mode="w") as fp: fp.write("# This file marks Thonny-private venv") # Create recommended pip conf to get rid of list deprecation warning # https://github.com/pypa/pip/issues/4058 pip_conf = "pip.ini" if running_on_windows() else "pip.conf" with open(os.path.join(path, pip_conf), mode="w") as fp: fp.write("[list]\nformat = columns") assert os.path.isdir(path)
def erase_flash(self): self.disconnect() cmd = [get_frontend_python(), '-u', '-m', 'esptool', '--port', self.port, 'erase_flash'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) dlg = SubprocessDialog(get_workbench(), proc, "Erasing flash", autoclose=False) dlg.wait_window()
def execute_command(cmd, title): """执行命令并监控输出结果""" env = os.environ.copy() env["PYTHONUSERBASE"] = THONNY_USER_DIR proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=env) dlg = SubprocessDialog(get_workbench(), proc, title, autoclose=False) dlg.wait_window()
def _create_venv(self, event=None): messagebox.showinfo( "Creating new virtual environment", "After clicking 'OK' you need to choose an empty directory, " "which will be the root of your new virtual environment.", parent=self, ) path = None while True: path = askdirectory( parent=self.winfo_toplevel(), initialdir=path, title=tr("Select empty directory for new virtual environment"), ) if not path: return if os.listdir(path): messagebox.showerror( tr("Bad directory"), tr("Selected directory is not empty.\nSelect another or cancel." ), master=self, ) else: break assert os.path.isdir(path) path = normpath_with_actual_case(path) proc = subprocess.Popen( [running.get_interpreter_for_subprocess(), "-m", "venv", path], stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, ) dlg = SubprocessDialog(self, proc, tr("Creating virtual environment")) ui_utils.show_dialog(dlg) if running_on_windows(): exe_path = normpath_with_actual_case( os.path.join(path, "Scripts", "python.exe")) else: exe_path = os.path.join(path, "bin", "python3") if os.path.exists(exe_path): self._configuration_variable.set(exe_path)
def _create_venv(self): path = None while True: path = askdirectory( master=self, initialdir=path, title=_("Select empty directory for new virtual environment"), ) if not path: return if os.listdir(path): messagebox.showerror( _("Bad directory"), _("Selected directory is not empty.\nSelect another or cancel." ), parent=get_workbench(), ) else: break assert os.path.isdir(path) path = normpath_with_actual_case(path) proc = subprocess.Popen( [running.get_frontend_python(), "-m", "venv", path], stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, ) dlg = SubprocessDialog(self, proc, _("Creating virtual environment")) ui_utils.show_dialog(dlg) if running_on_windows(): exe_path = normpath_with_actual_case( os.path.join(path, "Scripts", "python.exe")) else: exe_path = os.path.join(path, "bin", "python3") if os.path.exists(exe_path): self._configuration_variable.set(exe_path)
def _show_subprocess_dialog(master, proc, title): dlg = SubprocessDialog(master, proc, title) ui_utils.show_dialog(dlg, master) return dlg.returncode, dlg.stdout, dlg.stderr
def _install(self): if not self._port_desc_variable.get(): messagebox.showerror("Select port", "Please select port") return port = self._ports_by_desc[self._port_desc_variable.get()] firmware_path = self._firmware_entry.get() if not os.path.exists(firmware_path): messagebox.showerror("Bad firmware path", "Can't find firmware, please check path") return erase_command = self._esptool_command + [ "--chip", self._chip, "--port", port, "erase_flash", ] write_command = self._esptool_command + [ "--chip", self._chip, "--port", port, "write_flash", self._start_address, firmware_path, ] if not self._check_connection(port): return # unknown problem with first dialog appearing at 0,0 # self.update_idletasks() if self.winfo_screenwidth() >= 1024: min_left = ems_to_pixels(15) min_top = ems_to_pixels(5) else: min_left = 0 min_top = 0 def long_desc(cmd): return "Command:\n%s\n\nOutput:\n" % construct_cmd_line(cmd) self.update_idletasks() if self._erase_variable.get(): proc = self._create_subprocess(erase_command) dlg = SubprocessDialog( self, proc, "Erasing flash", long_description=long_desc(erase_command), autoclose=True, ) show_dialog(dlg, master=self, min_left=min_left, min_top=min_top) if dlg.cancelled or dlg.returncode: return proc = self._create_subprocess(write_command) dlg = SubprocessDialog( self, proc, "Installing firmware", long_description=long_desc(write_command), autoclose=False, ) show_dialog(dlg, master=self, min_left=min_left, min_top=min_top)
def _show_subprocess_dialog(master, proc, title): dlg = SubprocessDialog(master, proc, title) dlg.wait_window() return dlg.returncode, dlg.stdout, dlg.stderr