From 0e8b42a9d868b8ba0e2e40ed85bf218e4be5521c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 23 Mar 2015 07:58:28 +0100 Subject: [PATCH] Add a --relaxed-config options. --- doc/qutebrowser.1.asciidoc | 3 +++ qutebrowser/config/config.py | 21 +++++++++++++++------ qutebrowser/qutebrowser.py | 2 ++ qutebrowser/test/config/test_config.py | 17 +++++++++++++++++ 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/doc/qutebrowser.1.asciidoc b/doc/qutebrowser.1.asciidoc index 8f8a82390..f4f81f2d0 100644 --- a/doc/qutebrowser.1.asciidoc +++ b/doc/qutebrowser.1.asciidoc @@ -65,6 +65,9 @@ It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl. *--harfbuzz* '{old,new,system,auto}':: HarfBuzz engine version to use. Default: auto. +*--relaxed-config*:: + Silently remove unknown config options. + *--nowindow*:: Don't show the main window. diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 92925cdea..9b711928e 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -117,8 +117,9 @@ def _init_main_config(): """Initialize the main config.""" try: app = objreg.get('app') + args = objreg.get('args') config_obj = ConfigManager(standarddir.config(), 'qutebrowser.conf', - app) + args.relaxed_config, app) except (configexc.Error, configparser.Error, UnicodeDecodeError) as e: log.init.exception(e) errstr = "Error while reading config:" @@ -270,7 +271,7 @@ class ConfigManager(QObject): changed = pyqtSignal(str, str) style_changed = pyqtSignal(str, str) - def __init__(self, configdir, fname, parent=None): + def __init__(self, configdir, fname, relaxed=False, parent=None): super().__init__(parent) self._initialized = False self.sections = configdata.DATA @@ -285,7 +286,7 @@ class ConfigManager(QObject): else: self._configdir = configdir parser = ini.ReadConfigParser(configdir, fname) - self._from_cp(parser) + self._from_cp(parser, relaxed) self._initialized = True self._validate_all() @@ -394,17 +395,19 @@ class ConfigManager(QObject): else: return None - def _from_cp(self, cp): + def _from_cp(self, cp, relaxed=False): """Read the config from a configparser instance. Args: cp: The configparser instance to read the values from. + relaxed: Whether to ignore inexistent sections/optons """ for sectname in cp: if sectname in self.RENAMED_SECTIONS: sectname = self.RENAMED_SECTIONS[sectname] if sectname is not 'DEFAULT' and sectname not in self.sections: - raise configexc.NoSectionError(sectname) + if not relaxed: + raise configexc.NoSectionError(sectname) for sectname in self.sections: real_sectname = self._get_real_sectname(cp, sectname) if real_sectname is None: @@ -416,7 +419,13 @@ class ConfigManager(QObject): continue elif (sectname, k) in self.RENAMED_OPTIONS: k = self.RENAMED_OPTIONS[sectname, k] - self.set('conf', sectname, k, v, validate=False) + try: + self.set('conf', sectname, k, v, validate=False) + except configexc.NoOptionError: + if relaxed: + pass + else: + raise def _validate_all(self): """Validate all values set in self._from_cp.""" diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py index 8a331aa8f..219470cab 100644 --- a/qutebrowser/qutebrowser.py +++ b/qutebrowser/qutebrowser.py @@ -73,6 +73,8 @@ def get_argparser(): debug.add_argument('--harfbuzz', choices=['old', 'new', 'system', 'auto'], default='auto', help="HarfBuzz engine version to use. " "Default: auto.") + debug.add_argument('--relaxed-config', action='store_true', + help="Silently remove unknown config options.") debug.add_argument('--nowindow', action='store_true', help="Don't show " "the main window.") debug.add_argument('--debug-exit', help="Turn on debugging of late exit.", diff --git a/qutebrowser/test/config/test_config.py b/qutebrowser/test/config/test_config.py index 029731e2e..675d8396a 100644 --- a/qutebrowser/test/config/test_config.py +++ b/qutebrowser/test/config/test_config.py @@ -27,6 +27,7 @@ import configparser import tempfile import types import shutil +import argparse from unittest import mock from PyQt5.QtCore import QObject @@ -143,6 +144,20 @@ class ConfigParserTests(unittest.TestCase): with self.assertRaises(configexc.NoOptionError): self.cfg._from_cp(self.cp) + def test_invalid_section_relaxed(self): + """Test an invalid section with relaxed=True.""" + self.cp.read_dict({'foo': {'bar': 'baz'}}) + self.cfg._from_cp(self.cp, relaxed=True) + with self.assertRaises(configexc.NoSectionError): + self.cfg.get('foo', 'bar') + + def test_invalid_option_relaxed(self): + """Test an invalid option with relaxed=True.""" + self.cp.read_dict({'general': {'bar': 'baz'}}) + self.cfg._from_cp(self.cp, relaxed=True) + with self.assertRaises(configexc.NoOptionError): + self.cfg.get('general', 'bar') + class DefaultConfigTests(unittest.TestCase): @@ -173,6 +188,8 @@ class ConfigInitTests(unittest.TestCase): } objreg.register('app', QObject()) objreg.register('save-manager', mock.MagicMock()) + args = argparse.Namespace(relaxed_config=False) + objreg.register('args', args) def tearDown(self): shutil.rmtree(self.temp_dir)