Allow fallback=False with config.get/get_obj
This commit is contained in:
parent
5527d27ba7
commit
f780974d07
@ -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):
|
||||
|
@ -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:
|
||||
|
@ -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."""
|
||||
|
@ -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) == ''
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user