Add fallback argument to ConfigManager.get.
This is needed for interpolation since this change in Python 3.4: https://hg.python.org/cpython/rev/267422f7c927 This broke qutebrowser in Debian experimental when updating python from 3.4.3-8 to 3.4.3-9 as they pulled from hg. Fixes #968.
This commit is contained in:
parent
bb9bd40f6b
commit
5db4ed0ed1
@ -42,6 +42,9 @@ from qutebrowser.utils import (message, objreg, utils, standarddir, log,
|
|||||||
from qutebrowser.utils.usertypes import Completion
|
from qutebrowser.utils.usertypes import Completion
|
||||||
|
|
||||||
|
|
||||||
|
UNSET = object()
|
||||||
|
|
||||||
|
|
||||||
class change_filter: # pylint: disable=invalid-name
|
class change_filter: # pylint: disable=invalid-name
|
||||||
|
|
||||||
"""Decorator to filter calls based on a config section/option matching.
|
"""Decorator to filter calls based on a config section/option matching.
|
||||||
@ -621,9 +624,13 @@ class ConfigManager(QObject):
|
|||||||
return existed
|
return existed
|
||||||
|
|
||||||
@functools.lru_cache()
|
@functools.lru_cache()
|
||||||
def get(self, sectname, optname, raw=False, transformed=True):
|
def get(self, sectname, optname, raw=False, transformed=True,
|
||||||
|
fallback=UNSET):
|
||||||
"""Get the value from a section/option.
|
"""Get the value from a section/option.
|
||||||
|
|
||||||
|
We don't support the vars argument from configparser.get as it's not
|
||||||
|
hashable.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sectname: The section to get the option from.
|
sectname: The section to get the option from.
|
||||||
optname: The option name
|
optname: The option name
|
||||||
@ -636,13 +643,18 @@ class ConfigManager(QObject):
|
|||||||
if not self._initialized:
|
if not self._initialized:
|
||||||
raise Exception("get got called before initialization was "
|
raise Exception("get got called before initialization was "
|
||||||
"complete!")
|
"complete!")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sect = self.sections[sectname]
|
sect = self.sections[sectname]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
if fallback is not UNSET:
|
||||||
|
return fallback
|
||||||
raise configexc.NoSectionError(sectname)
|
raise configexc.NoSectionError(sectname)
|
||||||
try:
|
try:
|
||||||
val = sect[optname]
|
val = sect[optname]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
if fallback is not UNSET:
|
||||||
|
return fallback
|
||||||
raise configexc.NoOptionError(optname, sectname)
|
raise configexc.NoOptionError(optname, sectname)
|
||||||
if raw:
|
if raw:
|
||||||
return val.value()
|
return val.value()
|
||||||
|
@ -66,6 +66,9 @@ class TestConfigParser:
|
|||||||
|
|
||||||
def test_transformed_option_old(self):
|
def test_transformed_option_old(self):
|
||||||
"""Test a transformed option with the old name."""
|
"""Test a transformed option with the old name."""
|
||||||
|
# WORKAROUND
|
||||||
|
# Instance of 'object' has no 'name' member (no-member)
|
||||||
|
# pylint: disable=no-member
|
||||||
self.cp.read_dict({'colors': {'tab.fg.odd': 'pink'}})
|
self.cp.read_dict({'colors': {'tab.fg.odd': 'pink'}})
|
||||||
self.cfg._from_cp(self.cp)
|
self.cfg._from_cp(self.cp)
|
||||||
actual = self.cfg.get('colors', 'tabs.fg.odd').name()
|
actual = self.cfg.get('colors', 'tabs.fg.odd').name()
|
||||||
@ -74,6 +77,9 @@ class TestConfigParser:
|
|||||||
|
|
||||||
def test_transformed_option_new(self):
|
def test_transformed_option_new(self):
|
||||||
"""Test a transformed section with the new name."""
|
"""Test a transformed section with the new name."""
|
||||||
|
# WORKAROUND
|
||||||
|
# Instance of 'object' has no 'name' member (no-member)
|
||||||
|
# pylint: disable=no-member
|
||||||
self.cp.read_dict({'colors': {'tabs.fg.odd': 'pink'}})
|
self.cp.read_dict({'colors': {'tabs.fg.odd': 'pink'}})
|
||||||
self.cfg._from_cp(self.cp)
|
self.cfg._from_cp(self.cp)
|
||||||
actual = self.cfg.get('colors', 'tabs.fg.odd').name()
|
actual = self.cfg.get('colors', 'tabs.fg.odd').name()
|
||||||
@ -154,6 +160,27 @@ class TestConfigParser:
|
|||||||
with pytest.raises(configexc.NoOptionError):
|
with pytest.raises(configexc.NoOptionError):
|
||||||
self.cfg.get('general', 'bar') # pylint: disable=bad-config-call
|
self.cfg.get('general', 'bar') # pylint: disable=bad-config-call
|
||||||
|
|
||||||
|
def test_fallback(self):
|
||||||
|
"""Test getting an option with fallback.
|
||||||
|
|
||||||
|
This is done during interpolation in later Python 3.4 versions.
|
||||||
|
|
||||||
|
See https://github.com/The-Compiler/qutebrowser/issues/968
|
||||||
|
"""
|
||||||
|
# pylint: disable=bad-config-call
|
||||||
|
assert self.cfg.get('general', 'blabla', fallback='blub') == 'blub'
|
||||||
|
|
||||||
|
def test_sectionproxy(self):
|
||||||
|
"""Test getting an option via the section proxy."""
|
||||||
|
self.cp.read_dict({'general': {'ignore-case': 'false'}})
|
||||||
|
self.cfg._from_cp(self.cp)
|
||||||
|
assert not self.cfg['general'].get('ignore-case')
|
||||||
|
|
||||||
|
def test_sectionproxy_keyerror(self):
|
||||||
|
"""Test getting an inexistent option via the section proxy."""
|
||||||
|
with pytest.raises(configexc.NoOptionError):
|
||||||
|
self.cfg['general'].get('blahblahblub')
|
||||||
|
|
||||||
|
|
||||||
class TestKeyConfigParser:
|
class TestKeyConfigParser:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user