summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2018-09-28 13:33:42 +0200
committerFlorian Bruhin <me@the-compiler.org>2018-09-28 16:40:08 +0200
commitf780974d071f663c639e58d1df25c5cf902d0162 (patch)
tree17992b65e95c7b04571dc3a13ce1f7ba58df696d
parent5527d27ba7b3a56d9f0d9b3f84f51bade76d8d8a (diff)
downloadqutebrowser-f780974d071f663c639e58d1df25c5cf902d0162.tar.gz
qutebrowser-f780974d071f663c639e58d1df25c5cf902d0162.zip
Allow fallback=False with config.get/get_obj
-rw-r--r--qutebrowser/config/config.py14
-rw-r--r--qutebrowser/config/configtypes.py116
-rw-r--r--tests/unit/config/test_config.py11
-rw-r--r--tests/unit/config/test_configtypes.py7
4 files changed, 114 insertions, 34 deletions
diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py
index 98f2c67b3..facfcc553 100644
--- a/qutebrowser/config/config.py
+++ b/qutebrowser/config/config.py
@@ -312,10 +312,14 @@ class Config(QObject):
name, deleted=deleted, renamed=renamed)
raise exception from None
- def get(self, name, url=None):
- """Get the given setting converted for Python code."""
+ def get(self, name, url=None, *, fallback=True):
+ """Get the given setting converted for Python code.
+
+ Args:
+ fallback: Use the global value if there's no URL-specific one.
+ """
opt = self.get_opt(name)
- obj = self.get_obj(name, url=url)
+ obj = self.get_obj(name, url=url, fallback=fallback)
return opt.typ.to_py(obj)
def _maybe_copy(self, value):
@@ -329,14 +333,14 @@ class Config(QObject):
assert value.__hash__ is not None, value
return value
- def get_obj(self, name, *, url=None):
+ def get_obj(self, name, *, url=None, fallback=True):
"""Get the given setting as object (for YAML/config.py).
Note that the returned values are not watched for mutation.
If a URL is given, return the value which should be used for that URL.
"""
self.get_opt(name) # To make sure it exists
- value = self._values[name].get_for_url(url)
+ value = self._values[name].get_for_url(url, fallback=fallback)
return self._maybe_copy(value)
def get_obj_for_pattern(self, name, *, pattern):
diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py
index 1c3bff8fb..f2bd12a74 100644
--- a/qutebrowser/config/configtypes.py
+++ b/qutebrowser/config/configtypes.py
@@ -60,7 +60,7 @@ from PyQt5.QtGui import QColor, QFont
from PyQt5.QtWidgets import QTabWidget, QTabBar
from qutebrowser.commands import cmdutils
-from qutebrowser.config import configexc
+from qutebrowser.config import configexc, configutils
from qutebrowser.utils import standarddir, utils, qtutils, urlutils, urlmatch
from qutebrowser.keyinput import keyutils
@@ -149,6 +149,9 @@ class BaseType:
value: The value to check.
pytype: A Python type to check the value against.
"""
+ if value is configutils.UNSET:
+ return
+
if (value is None or (pytype == list and value == []) or
(pytype == dict and value == {})):
if not self.none_ok:
@@ -309,7 +312,9 @@ class MappingType(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
self._validate_valid_values(value.lower())
return self.MAPPING[value.lower()]
@@ -367,7 +372,9 @@ class String(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
self._validate_encoding(value)
@@ -399,7 +406,9 @@ class UniqueCharString(String):
def to_py(self, value):
value = super().to_py(value)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
# Check for duplicate values
@@ -455,7 +464,9 @@ class List(BaseType):
def to_py(self, value):
self._basic_py_validation(value, list)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return []
for val in value:
@@ -534,6 +545,9 @@ class ListOrValue(BaseType):
return value
def to_py(self, value):
+ if value is configutils.UNSET:
+ return value
+
try:
return [self.valtype.to_py(value)]
except configexc.ValidationError:
@@ -577,7 +591,8 @@ class FlagList(List):
def to_py(self, value):
vals = super().to_py(value)
- self._check_duplicates(vals)
+ if vals is not configutils.UNSET:
+ self._check_duplicates(vals)
return vals
def complete(self):
@@ -764,7 +779,9 @@ class Perc(_Numeric):
def to_py(self, value):
self._basic_py_validation(value, (float, int, str))
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
if isinstance(value, str):
@@ -907,7 +924,9 @@ class QtColor(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
color = QColor(value)
@@ -936,7 +955,9 @@ class QssColor(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
functions = ['rgb', 'rgba', 'hsv', 'hsva', 'qlineargradient',
@@ -981,7 +1002,9 @@ class Font(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
if not self.font_regex.fullmatch(value): # pragma: no cover
@@ -1000,7 +1023,9 @@ class FontFamily(Font):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
match = self.font_regex.fullmatch(value)
@@ -1024,7 +1049,9 @@ class QtFont(Font):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
style_map = {
@@ -1136,7 +1163,9 @@ class Regex(BaseType):
def to_py(self, value):
"""Get a compiled regex from either a string or a regex object."""
self._basic_py_validation(value, (str, self._regex_type))
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
elif isinstance(value, str):
return self._compile_regex(value)
@@ -1214,7 +1243,9 @@ class Dict(BaseType):
def to_py(self, value):
self._basic_py_validation(value, dict)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return self._fill_fixed_keys({})
self._validate_keys(value)
@@ -1256,7 +1287,9 @@ class File(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
value = os.path.expanduser(value)
@@ -1282,7 +1315,9 @@ class Directory(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
value = os.path.expandvars(value)
value = os.path.expanduser(value)
@@ -1309,7 +1344,9 @@ class FormatString(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
try:
@@ -1341,7 +1378,9 @@ class ShellCommand(List):
def to_py(self, value):
value = super().to_py(value)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return value
if (self.placeholder and
@@ -1365,7 +1404,9 @@ class Proxy(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
try:
@@ -1401,7 +1442,9 @@ class SearchEngineUrl(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
if not ('{}' in value or '{0}' in value):
@@ -1429,7 +1472,9 @@ class FuzzyUrl(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
try:
@@ -1463,6 +1508,9 @@ class Padding(Dict):
def to_py(self, value):
d = super().to_py(value)
+ if d is configutils.UNSET:
+ return d
+
return PaddingValues(**d)
@@ -1472,7 +1520,9 @@ class Encoding(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
try:
codecs.lookup(value)
@@ -1529,7 +1579,9 @@ class Url(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
qurl = QUrl.fromUserInput(value)
@@ -1545,7 +1597,9 @@ class SessionName(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
if value.startswith('_'):
raise configexc.ValidationError(value, "may not start with '_'!")
@@ -1593,7 +1647,7 @@ class ConfirmQuit(FlagList):
def to_py(self, value):
values = super().to_py(value)
- if not values:
+ if not values or values is configutils.UNSET:
return values
# Never can't be set with other options
@@ -1630,7 +1684,9 @@ class TimestampTemplate(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
try:
@@ -1654,7 +1710,9 @@ class Key(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
try:
@@ -1673,7 +1731,9 @@ class UrlPattern(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
- if not value:
+ if value is configutils.UNSET:
+ return value
+ elif not value:
return None
try:
diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py
index bf4f7c02d..6cef14130 100644
--- a/tests/unit/config/test_config.py
+++ b/tests/unit/config/test_config.py
@@ -480,6 +480,17 @@ class TestConfig:
conf.set_obj(name, False, pattern=pattern)
assert conf.get(name, url=QUrl('https://example.com/')) is False
+ @pytest.mark.parametrize('fallback, expected', [
+ (True, True),
+ (False, configutils.UNSET)
+ ])
+ def test_get_for_url_fallback(self, conf, fallback, expected):
+ """Test conf.get() with an URL and fallback."""
+ value = conf.get('content.javascript.enabled',
+ url=QUrl('https://example.com/'),
+ fallback=fallback)
+ assert value is expected
+
@pytest.mark.parametrize('value', [{}, {'normal': {'a': 'nop'}}])
def test_get_bindings(self, config_stub, conf, value):
"""Test conf.get() with bindings which have missing keys."""
diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py
index 46119be7e..ee5223a38 100644
--- a/tests/unit/config/test_configtypes.py
+++ b/tests/unit/config/test_configtypes.py
@@ -34,7 +34,7 @@ from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QColor, QFont
from PyQt5.QtNetwork import QNetworkProxy
-from qutebrowser.config import configtypes, configexc
+from qutebrowser.config import configtypes, configexc, configutils
from qutebrowser.utils import debug, utils, qtutils, urlmatch
from qutebrowser.browser.network import pac
from qutebrowser.keyinput import keyutils
@@ -274,6 +274,11 @@ class TestAll:
with pytest.raises(configexc.ValidationError):
meth(value)
+ @pytest.mark.parametrize('none_ok', [True, False])
+ def test_unset(self, klass, none_ok):
+ typ = klass(none_ok=none_ok)
+ assert typ.to_py(configutils.UNSET) is configutils.UNSET
+
def test_to_str_none(self, klass):
assert klass().to_str(None) == ''