From 5db4ed0ed116c09335457be3ec57a7e097ccd513 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 29 Sep 2015 07:35:38 +0200 Subject: [PATCH] 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. --- qutebrowser/config/config.py | 14 +++++++++++++- tests/unit/config/test_config.py | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index e67f5777b..9dbcaf4cf 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -42,6 +42,9 @@ from qutebrowser.utils import (message, objreg, utils, standarddir, log, from qutebrowser.utils.usertypes import Completion +UNSET = object() + + class change_filter: # pylint: disable=invalid-name """Decorator to filter calls based on a config section/option matching. @@ -621,9 +624,13 @@ class ConfigManager(QObject): return existed @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. + We don't support the vars argument from configparser.get as it's not + hashable. + Args: sectname: The section to get the option from. optname: The option name @@ -636,13 +643,18 @@ class ConfigManager(QObject): if not self._initialized: raise Exception("get got called before initialization was " "complete!") + try: sect = self.sections[sectname] except KeyError: + if fallback is not UNSET: + return fallback raise configexc.NoSectionError(sectname) try: val = sect[optname] except KeyError: + if fallback is not UNSET: + return fallback raise configexc.NoOptionError(optname, sectname) if raw: return val.value() diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index 6f47f6aa0..de19e0fdf 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -66,6 +66,9 @@ class TestConfigParser: def test_transformed_option_old(self): """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.cfg._from_cp(self.cp) actual = self.cfg.get('colors', 'tabs.fg.odd').name() @@ -74,6 +77,9 @@ class TestConfigParser: def test_transformed_option_new(self): """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.cfg._from_cp(self.cp) actual = self.cfg.get('colors', 'tabs.fg.odd').name() @@ -154,6 +160,27 @@ class TestConfigParser: with pytest.raises(configexc.NoOptionError): 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: