diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 26b0b5552..52e466018 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -187,6 +187,8 @@ Fixed - `:tab-detach` now fails correctly when there's only one tab open. - Various small issues with the command completion - Fixed hang when using multiple spaces in a row with the URL completion +- qutebrowser now still starts with an incorrectly configured + `$XDG_RUNTIME_DIR`. v0.8.3 ------ diff --git a/qutebrowser/utils/standarddir.py b/qutebrowser/utils/standarddir.py index 05fe7ce27..7c756b805 100644 --- a/qutebrowser/utils/standarddir.py +++ b/qutebrowser/utils/standarddir.py @@ -33,6 +33,11 @@ from qutebrowser.utils import log, qtutils, debug _args = None +class EmptyValueError(Exception): + + """Error raised when QStandardPaths returns an empty value.""" + + def config(): """Get a location for configs.""" typ = QStandardPaths.ConfigLocation @@ -104,9 +109,18 @@ def runtime(): else: # pragma: no cover # RuntimeLocation is a weird path on OS X and Windows. typ = QStandardPaths.TempLocation + overridden, path = _from_args(typ, _args) + if not overridden: - path = _writable_location(typ) + try: + path = _writable_location(typ) + except EmptyValueError: + # Fall back to TempLocation when RuntimeLocation is misconfigured + if typ == QStandardPaths.TempLocation: + raise + path = _writable_location(QStandardPaths.TempLocation) + # This is generic, but per-user. # # For TempLocation: @@ -128,7 +142,7 @@ def _writable_location(typ): typ_str = debug.qenum_key(QStandardPaths, typ) log.misc.debug("writable location for {}: {}".format(typ_str, path)) if not path: - raise ValueError("QStandardPaths returned an empty value!") + raise EmptyValueError("QStandardPaths returned an empty value!") # Qt seems to use '/' as path separator even on Windows... path = path.replace('/', os.sep) return path diff --git a/tests/unit/utils/test_standarddir.py b/tests/unit/utils/test_standarddir.py index eb348132b..aa7d59f0b 100644 --- a/tests/unit/utils/test_standarddir.py +++ b/tests/unit/utils/test_standarddir.py @@ -90,7 +90,7 @@ class TestWritableLocation: monkeypatch.setattr( 'qutebrowser.utils.standarddir.QStandardPaths.writableLocation', lambda typ: '') - with pytest.raises(ValueError): + with pytest.raises(standarddir.EmptyValueError): standarddir._writable_location(QStandardPaths.DataLocation) def test_sep(self, monkeypatch): @@ -137,6 +137,23 @@ class TestStandardDir: monkeypatch.delenv('XDG_{}_HOME'.format(var), raising=False) assert func() == str(tmpdir.join(*subdirs)) + @pytest.mark.linux + @pytest.mark.qt_log_ignore(r'^QStandardPaths: XDG_RUNTIME_DIR points to ' + r'non-existing path') + def test_linux_invalid_runtimedir(self, monkeypatch, tmpdir): + """With invalid XDG_RUNTIME_DIR, fall back to TempLocation.""" + monkeypatch.setenv('XDG_RUNTIME_DIR', str(tmpdir / 'does-not-exist')) + monkeypatch.setenv('TMPDIR', str(tmpdir / 'temp')) + assert standarddir.runtime() == str(tmpdir / 'temp' / 'qute_test') + + def test_runtimedir_empty_tempdir(self, monkeypatch, tmpdir): + """With an empty tempdir on non-Linux, we should raise.""" + monkeypatch.setattr(standarddir.sys, 'platform', 'nt') + monkeypatch.setattr(standarddir.QStandardPaths, 'writableLocation', + lambda typ: '') + with pytest.raises(standarddir.EmptyValueError): + standarddir.runtime() + @pytest.mark.parametrize('func, elems, expected', [ (standarddir.data, 2, ['qute_test', 'data']), (standarddir.config, 1, ['qute_test']),