def __init__(self, parent=None): super().__init__(parent) self.setup_ui() self.setAttribute(Qt.WA_DeleteOnClose) # create install process self.process = QProcess(self) self.process.setProgram(sys.executable) self.process.setProcessChannelMode(QProcess.MergedChannels) # setup process path env = QProcessEnvironment() combined_paths = os.pathsep.join( [user_site_packages(), env.systemEnvironment().value("PYTHONPATH")] ) env.insert("PYTHONPATH", combined_paths) self.process.setProcessEnvironment(env) # connections self.install_button.clicked.connect(self._install) self.uninstall_button.clicked.connect(self._uninstall) self.process.readyReadStandardOutput.connect(self._on_stdout_ready) from ..plugins import plugin_manager self.process.finished.connect(plugin_manager.discover) self.process.finished.connect(plugin_manager.prune)
def create_process(self): self.shell.clear() self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) # PYTHONPATH (in case we use Python in this terminal, e.g. py2exe) env = [ to_text_string(_path) for _path in self.process.systemEnvironment() ] processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) add_pathlist_to_PYTHONPATH(env, self.path) self.process.setProcessEnvironment(processEnvironment) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) # Shell arguments if os.name == 'nt': p_args = ['/Q'] else: p_args = ['-i'] if self.arguments: p_args.extend(shell_split(self.arguments)) self.process.readyReadStandardOutput.connect(self.write_output) self.process.finished.connect(self.finished) self.kill_button.clicked.connect(self.process.kill) if os.name == 'nt': self.process.start('cmd.exe', p_args) else: # Using bash: self.process.start('bash', p_args) self.send_to_process('PS1="\\u@\\h:\\w> "\n') running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("Process failed to start")) else: self.shell.setFocus() self.started.emit() return self.process
def start(self, config, pythonpath): """ Start process which will run the unit test suite. The process is run in the working directory specified in 'config', with the directories in `pythonpath` added to the Python path for the test process. The test results are written to the file `self.resultfilename`. The standard output and error are also recorded. Once the process is finished, `self.finished()` will be called. Parameters ---------- config : TestConfig Unit test configuration. pythonpath : list of str List of directories to be added to the Python path Raises ------ RuntimeError If process failed to start. """ wdir = config.wdir self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) self.process.setWorkingDirectory(wdir) self.process.finished.connect(self.finished) if pythonpath is not None: env = [ to_text_string(_pth) for _pth in self.process.systemEnvironment() ] add_pathlist_to_PYTHONPATH(env, pythonpath) processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) executable = get_python_executable() p_args = ['-m', self.module] + self.create_argument_list() try: os.remove(self.resultfilename) except OSError: pass self.process.start(executable, p_args) running = self.process.waitForStarted() if not running: raise RuntimeError
def run(self): """Handle the connection with the server. """ # Set up the zmq port. self.socket = self.context.socket(zmq.PAIR) self.port = self.socket.bind_to_random_port('tcp://*') # Set up the process. self.process = QProcess(self) if self.cwd: self.process.setWorkingDirectory(self.cwd) p_args = ['-u', self.target, str(self.port)] if self.extra_args is not None: p_args += self.extra_args # Set up environment variables. processEnvironment = QProcessEnvironment() env = self.process.systemEnvironment() if (self.env and 'PYTHONPATH' not in self.env) or self.env is None: python_path = osp.dirname(get_module_path('spyder')) # Add the libs to the python path. for lib in self.libs: try: path = osp.dirname(imp.find_module(lib)[1]) python_path = osp.pathsep.join([python_path, path]) except ImportError: pass if self.extra_path: try: python_path = osp.pathsep.join([python_path] + self.extra_path) except Exception as e: debug_print("Error when adding extra_path to plugin env") debug_print(e) env.append("PYTHONPATH=%s" % python_path) if self.env: env.update(self.env) for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) # Start the process and wait for started. self.process.start(self.executable, p_args) self.process.finished.connect(self._on_finished) running = self.process.waitForStarted() if not running: raise IOError('Could not start %s' % self) # Set up the socket notifer. fid = self.socket.getsockopt(zmq.FD) self.notifier = QSocketNotifier(fid, QSocketNotifier.Read, self) self.notifier.activated.connect(self._on_msg_received)
def create_process(self): self.shell.clear() self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) # PYTHONPATH (in case we use Python in this terminal, e.g. py2exe) env = [to_text_string(_path) for _path in self.process.systemEnvironment()] processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) add_pathlist_to_PYTHONPATH(env, self.path) self.process.setProcessEnvironment(processEnvironment) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) # Shell arguments if os.name == 'nt': p_args = ['/Q'] else: p_args = ['-i'] if self.arguments: p_args.extend( shell_split(self.arguments) ) self.process.readyReadStandardOutput.connect(self.write_output) self.process.finished.connect(self.finished) self.kill_button.clicked.connect(self.process.kill) if os.name == 'nt': self.process.start('cmd.exe', p_args) else: # Using bash: self.process.start('bash', p_args) self.send_to_process('PS1="\\u@\\h:\\w> "\n') running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("Process failed to start")) else: self.shell.setFocus() self.started.emit() return self.process
def _create_process( self, installer: InstallerTypes = "pip", ): process = QProcess() if installer != "pip": process.setProgram(installer) else: process.setProgram(self._sys_executable_or_bundled_python()) process.setProcessChannelMode(QProcess.MergedChannels) process.readyReadStandardOutput.connect( lambda process=process: self._on_stdout_ready(process) ) # setup process path env = QProcessEnvironment() combined_paths = os.pathsep.join( [user_site_packages(), env.systemEnvironment().value("PYTHONPATH")] ) env.insert("PYTHONPATH", combined_paths) # use path of parent process env.insert( "PATH", QProcessEnvironment.systemEnvironment().value("PATH") ) process.setProcessEnvironment(env) self.set_output_widget(self._output_widget) process.finished.connect( lambda ec, es: self._on_process_finished(process, ec, es) ) # FIXME connecting lambda to finished signal is bug creating and may end with segfault when garbage # collection will consume Installer object before process end. return process
def run(self): """Handle the connection with the server. """ # Set up the zmq port. self.socket = self.context.socket(zmq.PAIR) self.port = self.socket.bind_to_random_port('tcp://*') # Set up the process. self.process = QProcess(self) if self.cwd: self.process.setWorkingDirectory(self.cwd) p_args = ['-u', self.target, str(self.port)] if self.extra_args is not None: p_args += self.extra_args # Set up environment variables. processEnvironment = QProcessEnvironment() env = self.process.systemEnvironment() if (self.env and 'PYTHONPATH' not in self.env) or DEV: python_path = osp.dirname(get_module_path('spyderlib')) # Add the libs to the python path. for lib in self.libs: try: path = osp.dirname(imp.find_module(lib)[1]) python_path = osp.pathsep.join([python_path, path]) except ImportError: pass env.append("PYTHONPATH=%s" % python_path) if self.env: env.update(self.env) for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) # Start the process and wait for started. self.process.start(self.executable, p_args) self.process.finished.connect(self._on_finished) running = self.process.waitForStarted() if not running: raise IOError('Could not start %s' % self) # Set up the socket notifer. fid = self.socket.getsockopt(zmq.FD) self.notifier = QSocketNotifier(fid, QSocketNotifier.Read, self) self.notifier.activated.connect(self._on_msg_received)
def start(self): """Start the code analysis.""" filename = str(self.filecombo.currentText()) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(getcwd_or_home()) self.process.readyReadStandardOutput.connect(self.read_output) self.process.readyReadStandardError.connect( lambda: self.read_output(error=True)) self.process.finished.connect( lambda ec, es=QProcess.ExitStatus: self.finished(ec, es)) self.stop_button.clicked.connect(self.process.kill) self.output = '' self.error_output = '' plver = PYLINT_VER if plver is not None: p_args = ['-m', 'pylint', '--output-format=text'] if plver.split('.')[0] == '0': p_args += ['-i', 'yes'] else: # Option '-i' (alias for '--include-ids') was removed in pylint # 1.0 p_args += [ "--msg-template='{msg_id}:{line:3d}," "{column}: {obj}: {msg}" ] pylintrc_path = self.get_pylintrc_path(filename=filename) if pylintrc_path is not None: p_args += ['--rcfile={}'.format(pylintrc_path)] p_args += [filename] processEnvironment = QProcessEnvironment() processEnvironment.insert("PYTHONIOENCODING", "utf8") self.process.setProcessEnvironment(processEnvironment) self.process.start(sys.executable, p_args) running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("Process failed to start"))
def _create_process( self, installer: InstallerTypes = "pip", ): process = QProcess() process.setProcessChannelMode(QProcess.MergedChannels) process.readyReadStandardOutput.connect( lambda process=process: self._on_stdout_ready(process)) env = QProcessEnvironment.systemEnvironment() if installer == "pip": process.setProgram(self._sys_executable_or_bundled_python()) # patch process path combined_paths = os.pathsep.join([ user_site_packages(), env.systemEnvironment().value("PYTHONPATH"), ]) env.insert("PYTHONPATH", combined_paths) else: process.setProgram(installer) if installer == "mamba": from ..._version import version_tuple # To avoid napari version changing when installing a plugin, we # add a pin to the current napari version, that way we can # restrict any changes to the actual napari application. # Conda/mamba also pin python by default, so we effectively # constrain python and napari versions from changing, when # installing plugins inside the constructor bundled application. # See: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-pkgs.html#preventing-packages-from-updating-pinning napari_version = ".".join(str(v) for v in version_tuple[:3]) if env.contains("CONDA_PINNED_PACKAGES"): # str delimiter is '&' system_pins = f"&{env.value('CONDA_PINNED_PACKAGES')}" else: system_pins = "" env.insert( "CONDA_PINNED_PACKAGES", f"napari={napari_version}{system_pins}", ) if os.name == "nt": # workaround https://github.com/napari/napari/issues/4247, 4484 if not env.contains("TEMP"): temp = gettempdir() env.insert("TMP", temp) env.insert("TEMP", temp) if not env.contains("USERPROFILE"): env.insert("HOME", os.path.expanduser("~")) env.insert("USERPROFILE", os.path.expanduser("~")) process.setProcessEnvironment(env) self.set_output_widget(self._output_widget) process.finished.connect( lambda ec, es: self._on_process_finished(process, ec, es) ) # FIXME connecting lambda to finished signal is bug creating and may end with segfault when garbage # collection will consume Installer object before process end. return process
def start_server(self, filename, interpreter): """ Start a notebook server asynchronously. Start a server which can render the given notebook and return immediately. Assume the server uses the given interpreter. The manager will check periodically whether the server is accepting requests and emit `sig_server_started` or `sig_server_timed_out` when appropriate. Parameters ---------- filename : str File name of notebook to be rendered by the server. interpreter : str File name of Python interpreter to be used. """ home_dir = get_home_dir() if filename.startswith(home_dir): nbdir = home_dir else: nbdir = osp.dirname(filename) logger.debug('Starting new notebook server for %s', nbdir) process = QProcess(None) serverscript = osp.join(osp.dirname(__file__), '../server/main.py') serverscript = osp.normpath(serverscript) arguments = [ serverscript, '--no-browser', '--notebook-dir={}'.format(nbdir), '--NotebookApp.password='******'--KernelSpecManager.kernel_spec_class={}'.format(KERNELSPEC) ] if self.dark_theme: arguments.append('--dark') logger.debug('Arguments: %s', repr(arguments)) if DEV: env = QProcessEnvironment.systemEnvironment() env.insert('PYTHONPATH', osp.dirname(get_module_path('spyder'))) process.setProcessEnvironment(env) server_process = ServerProcess(process, notebook_dir=nbdir, interpreter=interpreter) process.setProcessChannelMode(QProcess.MergedChannels) process.readyReadStandardOutput.connect( lambda: self.read_server_output(server_process)) process.errorOccurred.connect( lambda error: self.handle_error(server_process, error)) process.finished.connect(lambda code, status: self.handle_finished( server_process, code, status)) process.start(sys.executable, arguments) self.servers.append(server_process) self._check_server_started(server_process)
def __init__(self, output_widget: QTextEdit = None): from ...plugins import plugin_manager # create install process self._output_widget = None self.process = QProcess() self.process.setProgram(sys.executable) self.process.setProcessChannelMode(QProcess.MergedChannels) self.process.readyReadStandardOutput.connect(self._on_stdout_ready) # setup process path env = QProcessEnvironment() combined_paths = os.pathsep.join([ user_site_packages(), env.systemEnvironment().value("PYTHONPATH") ]) env.insert("PYTHONPATH", combined_paths) self.process.setProcessEnvironment(env) self.process.finished.connect(lambda: plugin_manager.discover()) self.process.finished.connect(lambda: plugin_manager.prune()) self.set_output_widget(output_widget)
def _prepare_process(self, config, pythonpath): """ Prepare and return process for running the unit test suite. This sets the working directory and environment. """ process = QProcess(self) process.setProcessChannelMode(QProcess.MergedChannels) process.setWorkingDirectory(config.wdir) process.finished.connect(self.finished) if pythonpath is not None: env = [ to_text_string(_pth) for _pth in process.systemEnvironment() ] add_pathlist_to_PYTHONPATH(env, pythonpath) processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) process.setProcessEnvironment(processEnvironment) return process
def _start(self): """Start the code analysis.""" self.start_spinner() self.output = "" self.error_output = "" self._process = process = QProcess(self) process.setProcessChannelMode(QProcess.SeparateChannels) process.setWorkingDirectory(getcwd_or_home()) process.readyReadStandardOutput.connect(self._read_output) process.readyReadStandardError.connect( lambda: self._read_output(error=True)) process.finished.connect( lambda ec, es=QProcess.ExitStatus: self._finished(ec, es)) command_args = self.get_command(self.get_filename()) processEnvironment = QProcessEnvironment() processEnvironment.insert("PYTHONIOENCODING", "utf8") # resolve spyder-ide/spyder#14262 if running_in_mac_app(): pyhome = os.environ.get("PYTHONHOME") processEnvironment.insert("PYTHONHOME", pyhome) process.setProcessEnvironment(processEnvironment) process.start(sys.executable, command_args) running = process.waitForStarted() if not running: self.stop_spinner() QMessageBox.critical( self, _("Error"), _("Process failed to start"), )
def _get_environment(): env = QProcessEnvironment.systemEnvironment() env.insert("PYTHONUNBUFFERED", "y") env.insert("PYTHONPATH", dirname(SCRIPT_DIRECTORY)) if os.name == 'nt': anaconda_home = conda_prefix() path = env.value('PATH') new_path = os.pathsep.join([ join(anaconda_home, 'Library', 'mingw-w64', 'bin'), join(anaconda_home, 'Library', 'usr', 'bin'), path ]) env.insert("PATH", new_path) return env
def start(self): """Start the code analysis.""" filename = str(self.filecombo.currentText()) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(getcwd_or_home()) self.process.readyReadStandardOutput.connect(self.read_output) self.process.readyReadStandardError.connect( lambda: self.read_output(error=True)) self.process.finished.connect( lambda ec, es=QProcess.ExitStatus: self.finished(ec, es)) self.stop_button.clicked.connect(self.process.kill) self.output = '' self.error_output = '' if PYLINT_VER is not None: pylint_args = [ '-m', 'pylint', '--output-format=text', '--msg-template=' "'{msg_id}:{symbol}:{line:3d},{column}: {msg}'" ] pylintrc_path = self.get_pylintrc_path(filename=filename) if pylintrc_path is not None: pylint_args += ['--rcfile={}'.format(pylintrc_path)] pylint_args.append(filename) processEnvironment = QProcessEnvironment() processEnvironment.insert("PYTHONIOENCODING", "utf8") self.process.setProcessEnvironment(processEnvironment) self.process.start(sys.executable, pylint_args) running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("Process failed to start"))
def _install( self, pkg_list: Sequence[str], installer: Optional[InstallerTypes] = None, channels: Sequence[str] = ("conda-forge", ), ): installer = installer or self._installer_type process_environment = QProcessEnvironment.systemEnvironment() if installer != "pip": from ..._version import version_tuple # To avoid napari version changing when installing a plugin, we # add a pin to the current napari version, that way we can # restrict any changes to the actual napari application. # Conda/mamba also pin python by default, so we effectively # constrain python and napari versions from changing, when # installing plugins inside the constructor bundled application. # See: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-pkgs.html#preventing-packages-from-updating-pinning napari_version = ".".join(str(v) for v in version_tuple[:3]) process_environment.insert("CONDA_PINNED_PACKAGES", f"napari={napari_version}") cmd = [ 'install', '-y', '--prefix', self._conda_env_path, ] for channel in channels: cmd.extend(["-c", channel]) else: cmd = ['-m', 'pip', 'install', '--upgrade'] if (running_as_bundled_app() and sys.platform.startswith('linux') and not self._conda_env_path): cmd += [ '--no-warn-script-location', '--prefix', user_plugin_dir(), ] process = self._create_process(installer) process.setProcessEnvironment(process_environment) process.setArguments(cmd + list(pkg_list)) if self._output_widget and self._queue: self._output_widget.clear() process.start() return process
def _prepare_process(self, config, pythonpath): """ Prepare and return process for running the unit test suite. This sets the working directory and environment. """ process = QProcess(self) process.setProcessChannelMode(QProcess.MergedChannels) process.setWorkingDirectory(config.wdir) process.finished.connect(self.finished) if pythonpath: env = QProcessEnvironment.systemEnvironment() old_python_path = env.value('PYTHONPATH', None) python_path_str = os.pathsep.join(pythonpath) if old_python_path: python_path_str += os.pathsep + old_python_path env.insert('PYTHONPATH', python_path_str) process.setProcessEnvironment(env) return process
def start_process(self, process, args=None, cwd=None, env=None): """ Starts a process interactively. :param process: Process to run :type process: str :param args: List of arguments (list of str) :type args: list :param cwd: Working directory :type cwd: str :param env: environment variables (dict). """ self.setReadOnly(False) if env is None: env = {} if args is None: args = [] if not self._running: self.process = QProcess() self.process.finished.connect(self._on_process_finished) self.process.started.connect(self.process_started.emit) self.process.error.connect(self._write_error) self.process.readyReadStandardError.connect(self._on_stderr) self.process.readyReadStandardOutput.connect(self._on_stdout) if cwd: self.process.setWorkingDirectory(cwd) e = self.process.systemEnvironment() ev = QProcessEnvironment() for v in e: values = v.split('=') ev.insert(values[0], '='.join(values[1:])) for k, v in env.items(): ev.insert(k, v) self.process.setProcessEnvironment(ev) self._running = True self._process_name = process self._args = args if self._clear_on_start: self.clear() self._user_stop = False self._write_started() self.process.start(process, args) self.process.waitForStarted() else: _logger().warning('a process is already running')
def spawn_flag_process(self, stat, solver): log.debug('Feature testing MFiX %s', solver) key = (stat, solver) proc = self.flag_processes.get(key, None) if proc is not None: proc.kill() exe = self.solver_list.get(solver) exe_dir = os.path.dirname(exe) proc = self.flag_processes[key] = QProcess() proc.setProcessEnvironment(QProcessEnvironment.systemEnvironment()) proc.readyReadStandardOutput.connect( lambda k=key: self.flag_process_out(k)) proc.readyReadStandardError.connect( lambda k=key: self.flag_process_error(k)) proc.finished.connect(lambda ecode, estat, k=key: self. flag_process_finished(k, ecode, estat)) proc.error.connect(lambda e, k=key: self.flag_process_error(k, e)) proc.setWorkingDirectory(exe_dir) proc.start(exe, ["--print-flags"])
def start_transport(self): """Start transport layer.""" self.transport_args = list(map(str, self.transport_args)) logger.info('Starting transport: {0}'.format(' '.join( self.transport_args))) self.transport = QProcess(self) self.transport.errorOccurred.connect(self.handle_process_errors) # Modifying PYTHONPATH to run transport in development mode or # tests if DEV or running_under_pytest(): env = QProcessEnvironment() if running_under_pytest(): env.insert('PYTHONPATH', os.pathsep.join(sys.path)[:]) else: env.insert('PYTHONPATH', os.pathsep.join(sys.path)[1:]) self.transport.setProcessEnvironment(env) # Set transport log file transport_log_file = None if get_debug_level() > 0: transport_log_fname = 'transport_{0}_{1}.log'.format( self.language, os.getpid()) transport_log_file = get_conf_path( osp.join('lsp_logs', transport_log_fname)) if not osp.exists(osp.dirname(transport_log_file)): os.makedirs(osp.dirname(transport_log_file)) # Set channel properties if self.stdio: self.transport_args += self.server_args self.transport.setProcessChannelMode(QProcess.SeparateChannels) if transport_log_file is not None: self.transport.setStandardErrorFile(transport_log_file) else: self.transport.setProcessChannelMode(QProcess.MergedChannels) if transport_log_file is not None: self.transport.setStandardOutputFile(transport_log_file) # Start transport self.transport.start(self.transport_args[0], self.transport_args[1:])
def start(self, wdir=None, args=None, pythonpath=None): """ Start the profiling process. Parameters ---------- wdir: str Working directory path string. Default is None. args: list Arguments to pass to the profiling process. Default is None. pythonpath: str Python path string. Default is None. """ filename = to_text_string(self.filecombo.currentText()) if wdir is None: wdir = self._last_wdir if wdir is None: wdir = osp.basename(filename) if args is None: args = self._last_args if args is None: args = [] if pythonpath is None: pythonpath = self._last_pythonpath self._last_wdir = wdir self._last_args = args self._last_pythonpath = pythonpath self.datelabel.setText(_('Profiling, please wait...')) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(wdir) self.process.readyReadStandardOutput.connect(self._read_output) self.process.readyReadStandardError.connect( lambda: self._read_output(error=True)) self.process.finished.connect( lambda ec, es=QProcess.ExitStatus: self._finished(ec, es)) self.process.finished.connect(self.stop_spinner) if pythonpath is not None: env = [ to_text_string(_pth) for _pth in self.process.systemEnvironment() ] add_pathlist_to_PYTHONPATH(env, pythonpath) processEnvironment = QProcessEnvironment() for envItem in env: envName, __, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) processEnvironment.insert("PYTHONIOENCODING", "utf8") self.process.setProcessEnvironment(processEnvironment) self.output = '' self.error_output = '' self.running = True self.start_spinner() p_args = ['-m', 'cProfile', '-o', self.DATAPATH] if os.name == 'nt': # On Windows, one has to replace backslashes by slashes to avoid # confusion with escape characters (otherwise, for example, '\t' # will be interpreted as a tabulation): p_args.append(osp.normpath(filename).replace(os.sep, '/')) else: p_args.append(filename) if args: p_args.extend(shell_split(args)) executable = self.get_conf('executable', section='main_interpreter') self.process.start(executable, p_args) running = self.process.waitForStarted() if not running: QMessageBox.critical( self, _("Error"), _("Process failed to start"), ) self.update_actions()
def start(self, wdir=None, args=None, pythonpath=None): filename = to_text_string(self.filecombo.currentText()) if wdir is None: wdir = self._last_wdir if wdir is None: wdir = osp.basename(filename) if args is None: args = self._last_args if args is None: args = [] if pythonpath is None: pythonpath = self._last_pythonpath self._last_wdir = wdir self._last_args = args self._last_pythonpath = pythonpath self.datelabel.setText(_('Profiling, please wait...')) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(wdir) self.process.readyReadStandardOutput.connect(self.read_output) self.process.readyReadStandardError.connect( lambda: self.read_output(error=True)) self.process.finished.connect( lambda ec, es=QProcess.ExitStatus: self.finished(ec, es)) self.stop_button.clicked.connect(self.process.kill) if pythonpath is not None: env = [ to_text_string(_pth) for _pth in self.process.systemEnvironment() ] add_pathlist_to_PYTHONPATH(env, pythonpath) processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) self.output = '' self.error_output = '' p_args = ['-m', 'cProfile', '-o', self.DATAPATH] if os.name == 'nt': # On Windows, one has to replace backslashes by slashes to avoid # confusion with escape characters (otherwise, for example, '\t' # will be interpreted as a tabulation): p_args.append(osp.normpath(filename).replace(os.sep, '/')) else: p_args.append(filename) if args: p_args.extend(shell_split(args)) executable = sys.executable if executable.endswith("spyder.exe"): # py2exe distribution executable = "python.exe" self.process.start(executable, p_args) running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("Process failed to start"))
def start(self, wdir=None, args=None, pythonpath=None): filename = to_text_string(self.filecombo.currentText()) if wdir is None: wdir = self._last_wdir if wdir is None: wdir = osp.basename(filename) if args is None: args = self._last_args if args is None: args = [] if pythonpath is None: pythonpath = self._last_pythonpath self._last_wdir = wdir self._last_args = args self._last_pythonpath = pythonpath self.datelabel.setText(_('Profiling, please wait...')) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(wdir) self.process.readyReadStandardOutput.connect(self.read_output) self.process.readyReadStandardError.connect( lambda: self.read_output(error=True)) self.process.finished.connect(self.finished) self.stop_button.clicked.connect(self.process.kill) if pythonpath is not None: env = [ to_text_string(_pth) for _pth in self.process.systemEnvironment() ] add_pathlist_to_PYTHONPATH(env, pythonpath) processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) self.output = '' self.error_output = '' # remove previous results, since memory_profiler appends to output file # instead of replacing if osp.isfile(self.DATAPATH): os.remove(self.DATAPATH) if os.name == 'nt': # On Windows, one has to replace backslashes by slashes to avoid # confusion with escape characters (otherwise, for example, '\t' # will be interpreted as a tabulation): filename = osp.normpath(filename).replace(os.sep, '/') p_args = [ '-m', 'memory_profiler', '-o', '"' + self.DATAPATH + '"', '"' + filename + '"' ] if args: p_args.extend(programs.shell_split(args)) executable = get_python_executable() executable += ' ' + ' '.join(p_args) executable = executable.replace(os.sep, '/') self.process.start(executable) else: p_args = ['-m', 'memory_profiler', '-o', self.DATAPATH, filename] if args: p_args.extend(programs.shell_split(args)) executable = get_python_executable() self.process.start(executable, p_args) running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("Process failed to start"))
def create_process(self): self.shell.clear() self.process = QProcess(self) if self.merge_output_channels: self.process.setProcessChannelMode(QProcess.MergedChannels) else: self.process.setProcessChannelMode(QProcess.SeparateChannels) self.shell.wait_for_ready_read.connect( lambda: self.process.waitForReadyRead(250)) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) #-------------------------Python specific------------------------------ # Python arguments p_args = ['-u'] if DEBUG >= 3: p_args += ['-v'] p_args += get_python_args(self.fname, self.python_args, self.interact_action.isChecked(), self.debug_action.isChecked(), self.arguments) env = [ to_text_string(_path) for _path in self.process.systemEnvironment() ] if self.pythonstartup: env.append('PYTHONSTARTUP=%s' % self.pythonstartup) #-------------------------Python specific------------------------------- # Post mortem debugging if self.post_mortem_action.isChecked(): env.append('SPYDER_EXCEPTHOOK=True') # Set standard input/output encoding for Python consoles # See http://stackoverflow.com/q/26312400/438386, specifically # the comments of Martijn Pieters env.append('PYTHONIOENCODING=UTF-8') # Monitor if self.monitor_enabled: env.append('SPYDER_SHELL_ID=%s' % id(self)) env.append('SPYDER_AR_TIMEOUT=%d' % self.autorefresh_timeout) env.append('SPYDER_AR_STATE=%r' % self.autorefresh_state) from spyder.widgets.externalshell import introspection introspection_server = introspection.start_introspection_server() introspection_server.register(self) notification_server = introspection.start_notification_server() self.notification_thread = notification_server.register(self) self.notification_thread.sig_pdb.connect( lambda fname, lineno: self.sig_pdb.emit(fname, lineno)) self.notification_thread.open_file.connect( lambda fname, lineno: self.open_file.emit(fname, lineno)) if self.namespacebrowser is not None: self.configure_namespacebrowser() env.append('SPYDER_I_PORT=%d' % introspection_server.port) env.append('SPYDER_N_PORT=%d' % notification_server.port) # External modules options env.append('ETS_TOOLKIT=%s' % self.ets_backend) if self.mpl_backend is not None: backends = {0: 'Automatic', 1: 'None', 2: 'TkAgg'} env.append('SPY_MPL_BACKEND=%s' % backends[self.mpl_backend]) if self.qt_api: env.append('QT_API=%s' % self.qt_api) env.append('COLORIZE_SYS_STDERR=%s' % self.colorize_sys_stderr) # # Socket-based alternative (see input hook in sitecustomize.py): # if self.install_qt_inputhook: # from PyQt4.QtNetwork import QLocalServer # self.local_server = QLocalServer() # self.local_server.listen(str(id(self))) # User Module Deleter if self.is_interpreter: env.append('UMR_ENABLED=%r' % self.umr_enabled) env.append('UMR_NAMELIST=%s' % ','.join(self.umr_namelist)) env.append('UMR_VERBOSE=%r' % self.umr_verbose) env.append('MATPLOTLIB_ION=True') else: if self.interact: env.append('MATPLOTLIB_ION=True') else: env.append('MATPLOTLIB_ION=False') # External interpreter env.append('EXTERNAL_INTERPRETER=%r' % self.external_interpreter) # Add sitecustomize path to path list pathlist = [] spy_path = get_module_source_path('spyder') sc_path = osp.join(spy_path, 'utils', 'site') pathlist.append(sc_path) # Adding Spyder path pathlist += self.path # Adding path list to PYTHONPATH environment variable add_pathlist_to_PYTHONPATH(env, pathlist) #-------------------------Python specific------------------------------ self.process.readyReadStandardOutput.connect(self.write_output) self.process.readyReadStandardError.connect(self.write_error) self.process.finished.connect( lambda ec, es=QProcess.ExitStatus: self.finished(ec, es)) self.sig_finished.connect(self.dialog_manager.close_all) self.terminate_button.clicked.connect(self.process.terminate) self.kill_button.clicked.connect(self.process.kill) #-------------------------Python specific------------------------------ # Fixes for our Mac app: # 1. PYTHONPATH and PYTHONHOME are set while bootstrapping the app, # but their values are messing sys.path for external interpreters # (e.g. EPD) so we need to remove them from the environment. # 2. Set PYTHONPATH again but without grabbing entries defined in the # environment (Fixes Issue 1321) # 3. Remove PYTHONOPTIMIZE from env so that we can have assert # statements working with our interpreters (See Issue 1281) if running_in_mac_app(): if MAC_APP_NAME not in self.pythonexecutable: env = [p for p in env if not (p.startswith('PYTHONPATH') or \ p.startswith('PYTHONHOME'))] # 1. add_pathlist_to_PYTHONPATH(env, pathlist, drop_env=True) # 2. env = [p for p in env if not p.startswith('PYTHONOPTIMIZE')] # 3. processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) self.process.start(self.pythonexecutable, p_args) #-------------------------Python specific------------------------------ running = self.process.waitForStarted(3000) self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("A Python console failed to start!")) else: self.shell.setFocus() self.started.emit() return self.process
def start_command(self, cmd, cwd, env): """Start MFIX in QProcess""" self.cmdline = cmd # List of strings, same as psutil self.remove_mfix_stop() self.mfixproc = QProcess() if not self.mfixproc: log.warning("QProcess creation failed") return self.mfixproc.setWorkingDirectory(cwd) def slot_start(): # processId was only added in qt 5.3 if StrictVersion(QT_VERSION) > StrictVersion('5.3'): pid = self.mfixproc.processId() else: pid = self.mfixproc.pid() msg = "MFiX process %d is running" % pid self.parent.signal_update_runbuttons.emit(msg) def slot_read_out(): # Why convert to bytes then decode? out_str = bytes(self.mfixproc.readAllStandardOutput()).decode( 'utf-8', errors='ignore') self.parent.stdout_signal.emit(out_str) def slot_read_err(): err_str = bytes(self.mfixproc.readAllStandardError()).decode( 'utf-8', errors='ignore') self.parent.stderr_signal.emit(err_str) def slot_finish(status): # This should really be in the job manager if self.parent.job_manager.job: self.parent.job_manager.job.cleanup_and_exit() self.parent.job_manager.job = None msg = "MFiX process has stopped" self.parent.signal_update_runbuttons.emit(msg) if self.parent.job_manager.pidfile: try: os.unlink(self.parent.job_manager.pidfile) self.parent.job_manager.pidfile = None except OSError as e: if e.errno != errno.ENOENT: raise def slot_error(error): cmd_str = ' '.join(self.cmdline) if error == QProcess.FailedToStart: msg = "Process failed to start " + cmd_str elif error == QProcess.Crashed: msg = "Process exit " + cmd_str elif error == QProcess.Timedout: msg = "Process timeout " + cmd_str elif error in (QProcess.WriteError, QProcess.ReadError): msg = "Process communication error " + cmd_str else: msg = "Unknown error " + cmd_str log.warning(msg) # make the message print in red self.parent.stderr_signal.emit(msg) self.mfixproc.started.connect(slot_start) self.mfixproc.readyReadStandardOutput.connect(slot_read_out) self.mfixproc.readyReadStandardError.connect(slot_read_err) self.mfixproc.finished.connect(slot_finish) self.mfixproc.error.connect(slot_error) start_detached = True #if sys.platform.startswith('win') or 'mpirun' not in cmd: # start_detached = False # On Windows, start_detached gives a DOS box # What was the issue with mpirun? start_detached = False # https://bugreports.qt.io/browse/QTBUG-2284 # QProcessEnvironment does not work with startDetached, # fixed in Qt5.10 which we aren't using yet saved_env = None if not start_detached: process_env = QProcessEnvironment() add_env = process_env.insert else: add_env = os.environ.__setitem__ saved_env = os.environ.copy() for key, val in env.items(): add_env(key, val) add_env('MFIX_RUN_CMD', ' '.join(cmd)) if not start_detached: self.mfixproc.setProcessEnvironment(process_env) self.mfixproc.start(cmd[0], cmd[1:]) else: self.mfixproc.startDetached(cmd[0], cmd[1:]) # restore environment if saved_env: for (k, v) in list(os.environ.items()): if k not in saved_env: del os.environ[k] elif v != saved_env[k]: os.environ[k] = saved_env[k] # give gui a reference self.parent.mfix_process = self.mfixproc self.parent.slot_rundir_timer()
def start(self, wdir=None, args=None, pythonpath=None): filename = to_text_string(self.filecombo.currentText()) if wdir is None: wdir = self._last_wdir if wdir is None: wdir = osp.basename(filename) if args is None: args = self._last_args if args is None: args = [] if pythonpath is None: pythonpath = self._last_pythonpath self._last_wdir = wdir self._last_args = args self._last_pythonpath = pythonpath self.datelabel.setText(_('Profiling, please wait...')) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(wdir) self.process.readyReadStandardOutput.connect(self.read_output) self.process.readyReadStandardError.connect( lambda: self.read_output(error=True)) self.process.finished.connect(self.finished) self.stop_button.clicked.connect(self.process.kill) if pythonpath is not None: env = [to_text_string(_pth) for _pth in self.process.systemEnvironment()] add_pathlist_to_PYTHONPATH(env, pythonpath) processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) self.output = '' self.error_output = '' if os.name == 'nt': # On Windows, one has to replace backslashes by slashes to avoid # confusion with escape characters (otherwise, for example, '\t' # will be interpreted as a tabulation): filename = osp.normpath(filename).replace(os.sep, '/') p_args = ['-lvb', '-o', '"' + self.DATAPATH + '"', '"' + filename + '"'] if args: p_args.extend(programs.shell_split(args)) executable = '"' + programs.find_program('kernprof') + '"' executable += ' ' + ' '.join(p_args) executable = executable.replace(os.sep, '/') self.process.start(executable) else: p_args = ['-lvb', '-o', self.DATAPATH, filename] if args: p_args.extend(programs.shell_split(args)) executable = 'kernprof' self.process.start(executable, p_args) running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("Process failed to start"))
def create_process(self): self.shell.clear() self.process = QProcess(self) if self.merge_output_channels: self.process.setProcessChannelMode(QProcess.MergedChannels) else: self.process.setProcessChannelMode(QProcess.SeparateChannels) self.shell.wait_for_ready_read.connect( lambda: self.process.waitForReadyRead(250)) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) #-------------------------Python specific------------------------------ # Python arguments p_args = ['-u'] if DEBUG >= 3: p_args += ['-v'] p_args += get_python_args(self.fname, self.python_args, self.interact_action.isChecked(), self.debug_action.isChecked(), self.arguments) env = [to_text_string(_path) for _path in self.process.systemEnvironment()] if self.pythonstartup: env.append('PYTHONSTARTUP=%s' % self.pythonstartup) #-------------------------Python specific------------------------------- # Post mortem debugging if self.post_mortem_action.isChecked(): env.append('SPYDER_EXCEPTHOOK=True') # Set standard input/output encoding for Python consoles # (IPython handles it on its own) # See http://stackoverflow.com/q/26312400/438386, specifically # the comments of Martijn Pieters if not self.is_ipykernel: env.append('PYTHONIOENCODING=UTF-8') # Monitor if self.monitor_enabled: env.append('SPYDER_SHELL_ID=%s' % id(self)) env.append('SPYDER_AR_TIMEOUT=%d' % self.autorefresh_timeout) env.append('SPYDER_AR_STATE=%r' % self.autorefresh_state) from spyderlib.widgets.externalshell import introspection introspection_server = introspection.start_introspection_server() introspection_server.register(self) notification_server = introspection.start_notification_server() self.notification_thread = notification_server.register(self) self.notification_thread.sig_pdb.connect( lambda fname, lineno: self.sig_pdb.emit(fname, lineno)) self.notification_thread.new_ipython_kernel.connect( lambda args: self.create_ipython_client.emit(args)) self.notification_thread.open_file.connect( lambda fname, lineno: self.open_file.emit(fname, lineno)) if self.namespacebrowser is not None: self.configure_namespacebrowser() env.append('SPYDER_I_PORT=%d' % introspection_server.port) env.append('SPYDER_N_PORT=%d' % notification_server.port) # External modules options if not self.is_ipykernel: env.append('ETS_TOOLKIT=%s' % self.ets_backend) if self.mpl_backend is not None: backends = {0: 'Automatic', 1: 'None', 2: 'TkAgg'} env.append('SPY_MPL_BACKEND=%s' % backends[self.mpl_backend]) if self.qt_api and not self.is_ipykernel: env.append('QT_API=%s' % self.qt_api) env.append('COLORIZE_SYS_STDERR=%s' % self.colorize_sys_stderr) # # Socket-based alternative (see input hook in sitecustomize.py): # if self.install_qt_inputhook: # from PyQt4.QtNetwork import QLocalServer # self.local_server = QLocalServer() # self.local_server.listen(str(id(self))) # User Module Deleter if self.is_interpreter: env.append('UMR_ENABLED=%r' % self.umr_enabled) env.append('UMR_NAMELIST=%s' % ','.join(self.umr_namelist)) env.append('UMR_VERBOSE=%r' % self.umr_verbose) env.append('MATPLOTLIB_ION=True') else: if self.interact: env.append('MATPLOTLIB_ION=True') else: env.append('MATPLOTLIB_ION=False') # IPython kernel env.append('IPYTHON_KERNEL=%r' % self.is_ipykernel) # External interpreter env.append('EXTERNAL_INTERPRETER=%r' % self.external_interpreter) # Add sitecustomize path to path list pathlist = [] scpath = osp.dirname(osp.abspath(__file__)) pathlist.append(scpath) # Adding Spyder path pathlist += self.path # Adding path list to PYTHONPATH environment variable add_pathlist_to_PYTHONPATH(env, pathlist) #-------------------------Python specific------------------------------ self.process.readyReadStandardOutput.connect(self.write_output) self.process.readyReadStandardError.connect(self.write_error) self.process.finished.connect(lambda ec, es=QProcess.ExitStatus: self.finished(ec, es)) self.sig_finished.connect(self.dialog_manager.close_all) self.terminate_button.clicked.connect(self.process.terminate) self.kill_button.clicked.connect(self.process.kill) #-------------------------Python specific------------------------------ # Fixes for our Mac app: # 1. PYTHONPATH and PYTHONHOME are set while bootstrapping the app, # but their values are messing sys.path for external interpreters # (e.g. EPD) so we need to remove them from the environment. # 2. Set PYTHONPATH again but without grabbing entries defined in the # environment (Fixes Issue 1321) # 3. Remove PYTHONOPTIMIZE from env so that we can have assert # statements working with our interpreters (See Issue 1281) if running_in_mac_app(): if MAC_APP_NAME not in self.pythonexecutable: env = [p for p in env if not (p.startswith('PYTHONPATH') or \ p.startswith('PYTHONHOME'))] # 1. add_pathlist_to_PYTHONPATH(env, pathlist, drop_env=True) # 2. env = [p for p in env if not p.startswith('PYTHONOPTIMIZE')] # 3. processEnvironment = QProcessEnvironment() for envItem in env: envName, separator, envValue = envItem.partition('=') processEnvironment.insert(envName, envValue) self.process.setProcessEnvironment(processEnvironment) self.process.start(self.pythonexecutable, p_args) #-------------------------Python specific------------------------------ running = self.process.waitForStarted(3000) self.set_running_state(running) if not running: if self.is_ipykernel: self.ipython_kernel_start_error.emit( _("The kernel failed to start!! That's all we know... " "Please close this console and open a new one.")) else: QMessageBox.critical(self, _("Error"), _("A Python console failed to start!")) else: self.shell.setFocus() self.started.emit() return self.process