Proxy QProcess signals.
This commit is contained in:
parent
1f67353a40
commit
ad401e035f
@ -101,8 +101,8 @@ class _BaseUserscriptRunner(QObject):
|
||||
self._proc = guiprocess.GUIProcess(self._win_id, 'userscript',
|
||||
additional_env=self._env,
|
||||
parent=self)
|
||||
self._proc.proc.error.connect(self.on_proc_error)
|
||||
self._proc.proc.finished.connect(self.on_proc_finished)
|
||||
self._proc.error.connect(self.on_proc_error)
|
||||
self._proc.finished.connect(self.on_proc_finished)
|
||||
self._proc.start(cmd, args)
|
||||
|
||||
def _cleanup(self):
|
||||
|
@ -116,8 +116,8 @@ class ExternalEditor(QObject):
|
||||
return
|
||||
self._proc = guiprocess.GUIProcess(self._win_id, what='editor',
|
||||
parent=self)
|
||||
self._proc.proc.finished.connect(self.on_proc_closed)
|
||||
self._proc.proc.error.connect(self.on_proc_error)
|
||||
self._proc.finished.connect(self.on_proc_closed)
|
||||
self._proc.error.connect(self.on_proc_error)
|
||||
editor = config.get('general', 'editor')
|
||||
executable = editor[0]
|
||||
args = [self._filename if arg == '{}' else arg for arg in editor[1:]]
|
||||
|
@ -21,7 +21,8 @@
|
||||
|
||||
import shlex
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QProcess, QIODevice, QProcessEnvironment
|
||||
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QProcess,
|
||||
QProcessEnvironment)
|
||||
|
||||
from qutebrowser.utils import message, log
|
||||
|
||||
@ -39,23 +40,31 @@ ERROR_STRINGS = {
|
||||
}
|
||||
|
||||
|
||||
class GUIProcess:
|
||||
class GUIProcess(QObject):
|
||||
|
||||
"""An external process which shows notifications in the GUI.
|
||||
|
||||
Args:
|
||||
proc: The underlying QProcess.
|
||||
cmd: The command which was started.
|
||||
args: A list of arguments which gets passed.
|
||||
started: Whether the underlying process is started.
|
||||
_proc: The underlying QProcess.
|
||||
_win_id: The window ID this process is used in.
|
||||
_what: What kind of thing is spawned (process/editor/userscript/...).
|
||||
Used in messages.
|
||||
_verbose: Whether to show more messages.
|
||||
|
||||
Signals:
|
||||
error/finished/started signals proxied from QProcess.
|
||||
"""
|
||||
|
||||
error = pyqtSignal(QProcess.ProcessError)
|
||||
finished = pyqtSignal(int, QProcess.ExitStatus)
|
||||
started = pyqtSignal()
|
||||
|
||||
def __init__(self, win_id, what, *, verbose=False, additional_env=None,
|
||||
parent=None):
|
||||
super().__init__(parent)
|
||||
self._win_id = win_id
|
||||
self._what = what
|
||||
self._verbose = verbose
|
||||
@ -63,16 +72,19 @@ class GUIProcess:
|
||||
self.cmd = None
|
||||
self.args = None
|
||||
|
||||
self.proc = QProcess(parent)
|
||||
self.proc.error.connect(self.on_error)
|
||||
self.proc.finished.connect(self.on_finished)
|
||||
self.proc.started.connect(self.on_started)
|
||||
self._proc = QProcess(self)
|
||||
self._proc.error.connect(self.on_error)
|
||||
self._proc.error.connect(self.error)
|
||||
self._proc.finished.connect(self.on_finished)
|
||||
self._proc.finished.connect(self.finished)
|
||||
self._proc.started.connect(self.on_started)
|
||||
self._proc.started.connect(self.started)
|
||||
|
||||
if additional_env is not None:
|
||||
procenv = QProcessEnvironment.systemEnvironment()
|
||||
for k, v in additional_env.items():
|
||||
procenv.insert(k, v)
|
||||
self.proc.setProcessEnvironment(procenv)
|
||||
self._proc.setProcessEnvironment(procenv)
|
||||
|
||||
@pyqtSlot(QProcess.ProcessError)
|
||||
def on_error(self, error):
|
||||
@ -117,21 +129,24 @@ class GUIProcess:
|
||||
fake_cmdline = ' '.join(shlex.quote(e) for e in [cmd] + list(args))
|
||||
message.info(self._win_id, 'Executing: ' + fake_cmdline)
|
||||
|
||||
def start(self, cmd, args, mode=QIODevice.ReadWrite):
|
||||
def start(self, cmd, args, mode=None):
|
||||
"""Convenience wrapper around QProcess::start."""
|
||||
log.procs.debug("Starting process.")
|
||||
self._pre_start(cmd, args)
|
||||
self.proc.start(cmd, args, mode)
|
||||
if mode is None:
|
||||
self._proc.start(cmd, args)
|
||||
else:
|
||||
self._proc.start(cmd, args, mode)
|
||||
|
||||
def start_detached(self, cmd, args, cwd=None):
|
||||
"""Convenience wrapper around QProcess::startDetached."""
|
||||
log.procs.debug("Starting detached.")
|
||||
self._pre_start(cmd, args)
|
||||
ok = self.proc.startDetached(cmd, args, cwd)
|
||||
ok = self._proc.startDetached(cmd, args, cwd)
|
||||
|
||||
if ok:
|
||||
log.procs.debug("Process started.")
|
||||
self.started = True
|
||||
else:
|
||||
message.error(self._win_id, "Error while spawning {}: {}.".format(
|
||||
self._what, self.proc.error()), immediately=True)
|
||||
self._what, self._proc.error()), immediately=True)
|
||||
|
@ -60,7 +60,7 @@ class TestArg:
|
||||
stubbed_config.data = {
|
||||
'general': {'editor': ['bin'], 'editor-encoding': 'utf-8'}}
|
||||
self.editor.edit("")
|
||||
self.editor._proc.proc.start.assert_called_with("bin", [])
|
||||
self.editor._proc._proc.start.assert_called_with("bin", [])
|
||||
|
||||
def test_start_args(self, stubbed_config):
|
||||
"""Test starting editor with static arguments."""
|
||||
@ -68,7 +68,7 @@ class TestArg:
|
||||
'general': {'editor': ['bin', 'foo', 'bar'],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
self.editor.edit("")
|
||||
self.editor._proc.proc.start.assert_called_with("bin", ["foo", "bar"])
|
||||
self.editor._proc._proc.start.assert_called_with("bin", ["foo", "bar"])
|
||||
|
||||
def test_placeholder(self, stubbed_config):
|
||||
"""Test starting editor with placeholder argument."""
|
||||
@ -77,7 +77,7 @@ class TestArg:
|
||||
'editor-encoding': 'utf-8'}}
|
||||
self.editor.edit("")
|
||||
filename = self.editor._filename
|
||||
self.editor._proc.proc.start.assert_called_with(
|
||||
self.editor._proc._proc.start.assert_called_with(
|
||||
"bin", ["foo", filename, "bar"])
|
||||
|
||||
def test_in_arg_placeholder(self, stubbed_config):
|
||||
@ -86,7 +86,7 @@ class TestArg:
|
||||
'general': {'editor': ['bin', 'foo{}bar'],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
self.editor.edit("")
|
||||
self.editor._proc.proc.start.assert_called_with("bin", ["foo{}bar"])
|
||||
self.editor._proc._proc.start.assert_called_with("bin", ["foo{}bar"])
|
||||
|
||||
|
||||
class TestFileHandling:
|
||||
@ -113,7 +113,7 @@ class TestFileHandling:
|
||||
self.editor.edit("")
|
||||
filename = self.editor._filename
|
||||
assert os.path.exists(filename)
|
||||
self.editor._proc.proc.finished.emit(0, QProcess.NormalExit)
|
||||
self.editor._proc.finished.emit(0, QProcess.NormalExit)
|
||||
assert not os.path.exists(filename)
|
||||
|
||||
def test_file_handling_closed_error(self, caplog):
|
||||
@ -122,7 +122,7 @@ class TestFileHandling:
|
||||
filename = self.editor._filename
|
||||
assert os.path.exists(filename)
|
||||
with caplog.atLevel(logging.ERROR):
|
||||
self.editor._proc.proc.finished.emit(1, QProcess.NormalExit)
|
||||
self.editor._proc.finished.emit(1, QProcess.NormalExit)
|
||||
assert len(caplog.records()) == 2
|
||||
assert not os.path.exists(filename)
|
||||
|
||||
@ -132,9 +132,9 @@ class TestFileHandling:
|
||||
filename = self.editor._filename
|
||||
assert os.path.exists(filename)
|
||||
with caplog.atLevel(logging.ERROR):
|
||||
self.editor._proc.proc.error.emit(QProcess.Crashed)
|
||||
self.editor._proc.error.emit(QProcess.Crashed)
|
||||
assert len(caplog.records()) == 2
|
||||
self.editor._proc.proc.finished.emit(0, QProcess.CrashExit)
|
||||
self.editor._proc.finished.emit(0, QProcess.CrashExit)
|
||||
assert not os.path.exists(filename)
|
||||
|
||||
|
||||
@ -182,7 +182,7 @@ class TestModifyTests:
|
||||
self.editor.edit("")
|
||||
assert self._read() == ""
|
||||
self._write("Hello")
|
||||
self.editor._proc.proc.finished.emit(0, QProcess.NormalExit)
|
||||
self.editor._proc.finished.emit(0, QProcess.NormalExit)
|
||||
self.editor.editing_finished.emit.assert_called_with("Hello")
|
||||
|
||||
def test_simple_input(self):
|
||||
@ -190,7 +190,7 @@ class TestModifyTests:
|
||||
self.editor.edit("Hello")
|
||||
assert self._read() == "Hello"
|
||||
self._write("World")
|
||||
self.editor._proc.proc.finished.emit(0, QProcess.NormalExit)
|
||||
self.editor._proc.finished.emit(0, QProcess.NormalExit)
|
||||
self.editor.editing_finished.emit.assert_called_with("World")
|
||||
|
||||
def test_umlaut(self):
|
||||
@ -198,7 +198,7 @@ class TestModifyTests:
|
||||
self.editor.edit("Hällö Wörld")
|
||||
assert self._read() == "Hällö Wörld"
|
||||
self._write("Überprüfung")
|
||||
self.editor._proc.proc.finished.emit(0, QProcess.NormalExit)
|
||||
self.editor._proc.finished.emit(0, QProcess.NormalExit)
|
||||
self.editor.editing_finished.emit.assert_called_with("Überprüfung")
|
||||
|
||||
def test_unicode(self):
|
||||
|
Loading…
Reference in New Issue
Block a user