From 512d7c4448b0610bc133d83d8280a94469841968 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 17 Dec 2014 11:17:18 +0100 Subject: [PATCH] Simplify config exception tree and handling. Also make sure we catch all config-related errors in all related places. Fixes #324. --- qutebrowser/browser/commands.py | 6 +- qutebrowser/browser/network/qutescheme.py | 6 +- qutebrowser/commands/runners.py | 4 +- qutebrowser/completion/completiondelegate.py | 4 +- qutebrowser/config/config.py | 70 ++---- qutebrowser/config/configtypes.py | 224 +++++++++---------- qutebrowser/test/config/test_config.py | 12 +- qutebrowser/test/config/test_configtypes.py | 202 ++++++++--------- qutebrowser/test/stubs.py | 10 +- qutebrowser/utils/urlutils.py | 4 +- 10 files changed, 251 insertions(+), 291 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index cca95531a..9f0792629 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -35,7 +35,7 @@ import pygments.lexers import pygments.formatters from qutebrowser.commands import userscripts, cmdexc, cmdutils -from qutebrowser.config import config +from qutebrowser.config import config, configexc from qutebrowser.browser import webelem from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils, objreg, utils) @@ -921,10 +921,10 @@ class CommandDispatcher: topic)) try: config.get(*parts) - except config.NoSectionError: + except configexc.NoSectionError: raise cmdexc.CommandError("Invalid section {}!".format( parts[0])) - except config.NoOptionError: + except configexc.NoOptionError: raise cmdexc.CommandError("Invalid option {}!".format( parts[1])) path = 'settings.html#{}'.format(topic.replace('->', '-')) diff --git a/qutebrowser/browser/network/qutescheme.py b/qutebrowser/browser/network/qutescheme.py index 60825d785..5427b4d86 100644 --- a/qutebrowser/browser/network/qutescheme.py +++ b/qutebrowser/browser/network/qutescheme.py @@ -27,6 +27,8 @@ Module attributes: pyeval_output: The output of the last :pyeval command. """ +import configparser + from PyQt5.QtCore import pyqtSlot, QObject from PyQt5.QtNetwork import QNetworkReply @@ -34,7 +36,7 @@ import qutebrowser from qutebrowser.browser.network import schemehandler, networkreply from qutebrowser.utils import (version, utils, jinja, log, message, docutils, objreg) -from qutebrowser.config import configtypes, configdata +from qutebrowser.config import configexc, configdata pyeval_output = ":pyeval was never called" @@ -93,7 +95,7 @@ class JSBridge(QObject): """Slot to set a setting from qute:settings.""" try: objreg.get('config').set('conf', sectname, optname, value) - except configtypes.ValidationError as e: + except (configexc.Error, configparser.Error) as e: message.error(win_id, e) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 9208ab895..820013028 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -24,7 +24,7 @@ import re from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QUrl from PyQt5.QtWebKitWidgets import QWebPage -from qutebrowser.config import config +from qutebrowser.config import config, configexc from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.utils import message, log, utils, objreg from qutebrowser.misc import split @@ -180,7 +180,7 @@ class CommandRunner(QObject): parts = text.strip().split(maxsplit=1) try: alias = config.get('aliases', parts[0]) - except (config.NoOptionError, config.NoSectionError): + except (configexc.NoOptionError, configexc.NoSectionError): return None try: new_cmd = '{} {}'.format(alias, parts[1]) diff --git a/qutebrowser/completion/completiondelegate.py b/qutebrowser/completion/completiondelegate.py index 3adab86b2..f9ec83a7a 100644 --- a/qutebrowser/completion/completiondelegate.py +++ b/qutebrowser/completion/completiondelegate.py @@ -28,7 +28,7 @@ from PyQt5.QtCore import QRectF, QSize, Qt from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption, QAbstractTextDocumentLayout) -from qutebrowser.config import config, style +from qutebrowser.config import config, configexc, style from qutebrowser.utils import qtutils @@ -154,7 +154,7 @@ class CompletionItemDelegate(QStyledItemDelegate): option = 'completion.fg' try: self._painter.setPen(config.get('colors', option)) - except config.NoOptionError: + except configexc.NoOptionError: self._painter.setPen(config.get('colors', 'completion.fg')) ctx = QAbstractTextDocumentLayout.PaintContext() ctx.palette.setColor(QPalette.Text, self._painter.pen().color()) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index cc51dc117..326682133 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -35,7 +35,7 @@ import collections.abc from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QStandardPaths, QUrl from PyQt5.QtWidgets import QMessageBox -from qutebrowser.config import configdata, configtypes, textwrapper +from qutebrowser.config import configdata, configexc, textwrapper from qutebrowser.config.parsers import ini, keyconf from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.utils import message, objreg, utils, standarddir, log, qtutils @@ -63,11 +63,9 @@ class change_filter: # pylint: disable=invalid-name See class attributes. """ if sectname not in configdata.DATA: - raise NoSectionError("Section '{}' does not exist!".format( - sectname)) + raise configexc.NoSectionError(sectname) if optname is not None and optname not in configdata.DATA[sectname]: - raise NoOptionError("Option '{}' does not exist in section " - "'{}'!".format(optname, sectname)) + raise configexc.NoOptionError(optname, sectname) self._sectname = sectname self._optname = optname @@ -125,16 +123,14 @@ def init(args): try: app = objreg.get('app') config_obj = ConfigManager(confdir, 'qutebrowser.conf', app) - except (configtypes.ValidationError, NoOptionError, NoSectionError, - UnknownSectionError, InterpolationSyntaxError, - configparser.InterpolationError, - configparser.DuplicateSectionError, - configparser.DuplicateOptionError, - configparser.ParsingError) as e: + except (configexc.Error, configparser.Error) as e: log.init.exception(e) errstr = "Error while reading config:" - if hasattr(e, 'section') and hasattr(e, 'option'): - errstr += "\n\n{} -> {}:".format(e.section, e.option) + try: + errstr += "\n\n{} -> {}:".format( + e.section, e.option) # pylint: disable=no-member + except AttributeError: + pass errstr += "\n{}".format(e) msgbox = QMessageBox(QMessageBox.Critical, "Error while reading config!", errstr) @@ -169,34 +165,6 @@ def init(args): objreg.register('command-history', command_history) -class NoSectionError(configparser.NoSectionError): - - """Exception raised when a section was not found.""" - - pass - - -class NoOptionError(configparser.NoOptionError): - - """Exception raised when an option was not found.""" - - pass - - -class InterpolationSyntaxError(ValueError): - - """Exception raised when configparser interpolation raised an error.""" - - pass - - -class UnknownSectionError(Exception): - - """Exception raised when there was an unknwon section in the config.""" - - pass - - class ConfigManager(QObject): """Configuration manager for qutebrowser. @@ -378,8 +346,7 @@ class ConfigManager(QObject): if sectname in self.RENAMED_SECTIONS: sectname = self.RENAMED_SECTIONS[sectname] if sectname is not 'DEFAULT' and sectname not in self.sections: - raise UnknownSectionError("Unknown section '{}'!".format( - sectname)) + raise configexc.NoSectionError(sectname) for sectname in self.sections: real_sectname = self._get_real_sectname(cp, sectname) if real_sectname is None: @@ -401,7 +368,7 @@ class ConfigManager(QObject): self, sectname, optname, opt.value(), mapping) try: opt.typ.validate(interpolated) - except configtypes.ValidationError as e: + except configexc.ValidationError as e: e.section = sectname e.option = optname raise @@ -473,7 +440,7 @@ class ConfigManager(QObject): try: sectdict = self.sections[sectname] except KeyError: - raise NoSectionError(sectname) + raise configexc.NoSectionError(sectname) optname = self.optionxform(optname) existed = optname in sectdict if existed: @@ -500,11 +467,11 @@ class ConfigManager(QObject): try: sect = self.sections[sectname] except KeyError: - raise NoSectionError(sectname) + raise configexc.NoSectionError(sectname) try: val = sect[optname] except KeyError: - raise NoOptionError(optname, sectname) + raise configexc.NoOptionError(optname, sectname) if raw: return val.value() mapping = {key: val.value() for key, val in sect.values.items()} @@ -555,8 +522,7 @@ class ConfigManager(QObject): "are required: value") layer = 'temp' if temp else 'conf' self.set(layer, sectname, optname, value) - except (NoOptionError, NoSectionError, configtypes.ValidationError, - ValueError) as e: + except (configexc.Error, configparser.Error) as e: raise cmdexc.CommandError("set: {} - {}".format( e.__class__.__name__, e)) @@ -574,11 +540,11 @@ class ConfigManager(QObject): value = self._interpolation.before_set(self, sectname, optname, value) except ValueError as e: - raise InterpolationSyntaxError(e) + raise configexc.InterpolationSyntaxError(optname, sectname, str(e)) try: sect = self.sections[sectname] except KeyError: - raise NoSectionError(sectname) + raise configexc.NoSectionError(sectname) mapping = {key: val.value() for key, val in sect.values.items()} if validate: interpolated = self._interpolation.before_get( @@ -588,7 +554,7 @@ class ConfigManager(QObject): try: sect.setv(layer, optname, value, interpolated) except KeyError: - raise NoOptionError(optname, sectname) + raise configexc.NoOptionError(optname, sectname) else: if self._initialized: self._after_set(sectname, optname) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 458487f7d..0019fe742 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -32,28 +32,12 @@ from PyQt5.QtNetwork import QNetworkProxy from PyQt5.QtWidgets import QTabWidget, QTabBar from qutebrowser.commands import cmdutils +from qutebrowser.config import configexc SYSTEM_PROXY = object() # Return value for Proxy type -class ValidationError(ValueError): - - """Exception raised when a value for a config type was invalid. - - Class attributes: - section: Section in which the error occured (added when catching and - re-raising the exception). - option: Option in which the error occured. - """ - - section = None - option = None - - def __init__(self, value, msg): - super().__init__("Invalid value '{}' - {}".format(value, msg)) - - class ValidValues: """Container for valid values for a given type. @@ -133,8 +117,9 @@ class BaseType: return if self.valid_values is not None: if value not in self.valid_values: - raise ValidationError(value, "valid values: {}".format( - ', '.join(self.valid_values))) + raise configexc.ValidationError( + value, "valid values: {}".format(', '.join( + self.valid_values))) else: return else: @@ -196,17 +181,17 @@ class String(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if self.forbidden is not None and any(c in value for c in self.forbidden): - raise ValidationError(value, "may not contain the chars " - "'{}'".format(self.forbidden)) + raise configexc.ValidationError(value, "may not contain the chars " + "'{}'".format(self.forbidden)) if self.minlen is not None and len(value) < self.minlen: - raise ValidationError(value, "must be at least {} chars " - "long!".format(self.minlen)) + raise configexc.ValidationError(value, "must be at least {} chars " + "long!".format(self.minlen)) if self.maxlen is not None and len(value) > self.maxlen: - raise ValidationError(value, "must be at most {} long!".format( - self.maxlen)) + raise configexc.ValidationError(value, "must be at most {} chars " + "long!".format(self.maxlen)) class List(BaseType): @@ -226,10 +211,11 @@ class List(BaseType): if self._none_ok: return else: - raise ValidationError(value, "list may not be empty!") + raise configexc.ValidationError(value, "list may not be " + "empty!") vals = self.transform(value) if None in vals: - raise ValidationError(value, "items may not be empty!") + raise configexc.ValidationError(value, "items may not be empty!") class Bool(BaseType): @@ -259,9 +245,9 @@ class Bool(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if value.lower() not in Bool._BOOLEAN_STATES: - raise ValidationError(value, "must be a boolean!") + raise configexc.ValidationError(value, "must be a boolean!") class BoolAsk(Bool): @@ -313,17 +299,17 @@ class Int(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") try: intval = int(value) except ValueError: - raise ValidationError(value, "must be an integer!") + raise configexc.ValidationError(value, "must be an integer!") if self.minval is not None and intval < self.minval: - raise ValidationError(value, "must be {} or bigger!".format( - self.minval)) + raise configexc.ValidationError(value, "must be {} or " + "bigger!".format(self.minval)) if self.maxval is not None and intval > self.maxval: - raise ValidationError(value, "must be {} or smaller!".format( - self.maxval)) + raise configexc.ValidationError(value, "must be {} or " + "smaller!".format(self.maxval)) class IntList(List): @@ -340,9 +326,10 @@ class IntList(List): try: vals = self.transform(value) except ValueError: - raise ValidationError(value, "must be a list of integers!") + raise configexc.ValidationError(value, "must be a list of " + "integers!") if None in vals and not self._none_ok: - raise ValidationError(value, "items may not be empty!") + raise configexc.ValidationError(value, "items may not be empty!") class Float(BaseType): @@ -375,17 +362,17 @@ class Float(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") try: floatval = float(value) except ValueError: - raise ValidationError(value, "must be a float!") + raise configexc.ValidationError(value, "must be a float!") if self.minval is not None and floatval < self.minval: - raise ValidationError(value, "must be {} or bigger!".format( - self.minval)) + raise configexc.ValidationError(value, "must be {} or " + "bigger!".format(self.minval)) if self.maxval is not None and floatval > self.maxval: - raise ValidationError(value, "must be {} or smaller!".format( - self.maxval)) + raise configexc.ValidationError(value, "must be {} or " + "smaller!".format(self.maxval)) class Perc(BaseType): @@ -418,19 +405,19 @@ class Perc(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty") + raise configexc.ValidationError(value, "may not be empty") if not value.endswith('%'): - raise ValidationError(value, "does not end with %") + raise configexc.ValidationError(value, "does not end with %") try: intval = int(value[:-1]) except ValueError: - raise ValidationError(value, "invalid percentage!") + raise configexc.ValidationError(value, "invalid percentage!") if self.minval is not None and intval < self.minval: - raise ValidationError(value, "must be {}% or more!".format( - self.minval)) + raise configexc.ValidationError(value, "must be {}% or " + "more!".format(self.minval)) if self.maxval is not None and intval > self.maxval: - raise ValidationError(value, "must be {}% or less!".format( - self.maxval)) + raise configexc.ValidationError(value, "must be {}% or " + "less!".format(self.maxval)) class PercList(List): @@ -465,11 +452,13 @@ class PercList(List): if self._none_ok: continue else: - raise ValidationError(value, "items may not be empty!") + raise configexc.ValidationError(value, "items may not " + "be empty!") else: perctype.validate(val) - except ValidationError: - raise ValidationError(value, "must be a list of percentages!") + except configexc.ValidationError: + raise configexc.ValidationError(value, "must be a list of " + "percentages!") class PercOrInt(BaseType): @@ -504,29 +493,30 @@ class PercOrInt(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if value.endswith('%'): try: intval = int(value[:-1]) except ValueError: - raise ValidationError(value, "invalid percentage!") + raise configexc.ValidationError(value, "invalid percentage!") if self.minperc is not None and intval < self.minperc: - raise ValidationError(value, "must be {}% or more!".format( - self.minperc)) + raise configexc.ValidationError(value, "must be {}% or " + "more!".format(self.minperc)) if self.maxperc is not None and intval > self.maxperc: - raise ValidationError(value, "must be {}% or less!".format( - self.maxperc)) + raise configexc.ValidationError(value, "must be {}% or " + "less!".format(self.maxperc)) else: try: intval = int(value) except ValueError: - raise ValidationError(value, "must be integer or percentage!") + raise configexc.ValidationError(value, "must be integer or " + "percentage!") if self.minint is not None and intval < self.minint: - raise ValidationError(value, "must be {} or bigger!".format( - self.minint)) + raise configexc.ValidationError(value, "must be {} or " + "bigger!".format(self.minint)) if self.maxint is not None and intval > self.maxint: - raise ValidationError(value, "must be {} or smaller!".format( - self.maxint)) + raise configexc.ValidationError(value, "must be {} or " + "smaller!".format(self.maxint)) class Command(BaseType): @@ -540,9 +530,9 @@ class Command(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if value.split()[0] not in cmdutils.cmd_dict: - raise ValidationError(value, "must be a valid command!") + raise configexc.ValidationError(value, "must be a valid command!") def complete(self): out = [] @@ -585,11 +575,11 @@ class QtColor(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") elif QColor.isValidColor(value): pass else: - raise ValidationError(value, "must be a valid color") + raise configexc.ValidationError(value, "must be a valid color") def transform(self, value): if not value: @@ -609,14 +599,14 @@ class CssColor(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if value.startswith('-'): # custom function name, won't validate. pass elif QColor.isValidColor(value): pass else: - raise ValidationError(value, "must be a valid color") + raise configexc.ValidationError(value, "must be a valid color") class QssColor(CssColor): @@ -644,14 +634,14 @@ class QssColor(CssColor): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") elif any(re.match(r, value) for r in self.color_func_regexes): # QColor doesn't handle these, so we do the best we can easily pass elif QColor.isValidColor(value): pass else: - raise ValidationError(value, "must be a valid color") + raise configexc.ValidationError(value, "must be a valid color") class Font(BaseType): @@ -680,9 +670,9 @@ class Font(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if not self.font_regex.match(value): - raise ValidationError(value, "must be a valid font") + raise configexc.ValidationError(value, "must be a valid font") class QtFont(Font): @@ -747,11 +737,12 @@ class Regex(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") try: re.compile(value, self.flags) except sre_constants.error as e: - raise ValidationError(value, "must be a valid regex - " + str(e)) + raise configexc.ValidationError(value, "must be a valid regex - " + + str(e)) def transform(self, value): if not value: @@ -779,10 +770,10 @@ class RegexList(List): try: vals = self.transform(value) except sre_constants.error as e: - raise ValidationError(value, "must be a list valid regexes - " + - str(e)) + raise configexc.ValidationError(value, "must be a list valid " + "regexes - " + str(e)) if not self._none_ok and None in vals: - raise ValidationError(value, "items may not be empty!") + raise configexc.ValidationError(value, "items may not be empty!") class File(BaseType): @@ -796,12 +787,12 @@ class File(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") value = os.path.expanduser(value) if not os.path.isfile(value): - raise ValidationError(value, "must be a valid file!") + raise configexc.ValidationError(value, "must be a valid file!") if not os.path.isabs(value): - raise ValidationError(value, "must be an absolute path!") + raise configexc.ValidationError(value, "must be an absolute path!") def transform(self, value): if not value: @@ -820,12 +811,13 @@ class Directory(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") value = os.path.expanduser(value) if not os.path.isdir(value): - raise ValidationError(value, "must be a valid directory!") + raise configexc.ValidationError(value, "must be a valid " + "directory!") if not os.path.isabs(value): - raise ValidationError(value, "must be an absolute path!") + raise configexc.ValidationError(value, "must be an absolute path!") def transform(self, value): if not value: @@ -868,13 +860,13 @@ class WebKitBytes(BaseType): try: val = self.transform(value) except ValueError: - raise ValidationError(value, "must be a valid integer with " - "optional suffix!") + raise configexc.ValidationError(value, "must be a valid integer " + "with optional suffix!") if self.maxsize is not None and val > self.maxsize: - raise ValidationError(value, "must be {} " - "maximum!".format(self.maxsize)) + raise configexc.ValidationError(value, "must be {} " + "maximum!".format(self.maxsize)) if val < 0: - raise ValidationError(value, "must be 0 minimum!") + raise configexc.ValidationError(value, "must be 0 minimum!") def transform(self, value): if not value: @@ -919,10 +911,10 @@ class WebKitBytesList(List): for val in vals: self.bytestype.validate(val) if None in vals and not self._none_ok: - raise ValidationError(value, "items may not be empty!") + raise configexc.ValidationError(value, "items may not be empty!") if self.length is not None and len(vals) != self.length: - raise ValidationError(value, "exactly {} values need to be " - "set!".format(self.length)) + raise configexc.ValidationError(value, "exactly {} values need to " + "be set!".format(self.length)) class ShellCommand(BaseType): @@ -944,13 +936,14 @@ class ShellCommand(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if self.placeholder and '{}' not in self.transform(value): - raise ValidationError(value, "needs to contain a {}-placeholder.") + raise configexc.ValidationError(value, "needs to contain a " + "{}-placeholder.") try: shlex.split(value) except ValueError as e: - raise ValidationError(value, str(e)) + raise configexc.ValidationError(value, str(e)) def transform(self, value): if not value: @@ -986,16 +979,17 @@ class Proxy(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if value in self.valid_values: return url = QUrl(value) if not url.isValid(): - raise ValidationError(value, "invalid url, {}".format( + raise configexc.ValidationError(value, "invalid url, {}".format( url.errorString())) elif url.scheme() not in self.PROXY_TYPES: - raise ValidationError(value, "must be a proxy URL (http://... or " - "socks://...) or system/none!") + raise configexc.ValidationError(value, "must be a proxy URL " + "(http://... or socks://...) or " + "system/none!") def complete(self): out = [] @@ -1033,7 +1027,7 @@ class SearchEngineName(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") class SearchEngineUrl(BaseType): @@ -1045,12 +1039,12 @@ class SearchEngineUrl(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") if '{}' not in value: - raise ValidationError(value, "must contain \"{}\"") + raise configexc.ValidationError(value, "must contain \"{}\"") url = QUrl(value.replace('{}', 'foobar')) if not url.isValid(): - raise ValidationError(value, "invalid url, {}".format( + raise configexc.ValidationError(value, "invalid url, {}".format( url.errorString())) @@ -1065,11 +1059,11 @@ class Encoding(BaseType): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") try: codecs.lookup(value) except LookupError: - raise ValidationError(value, "is not a valid encoding!") + raise configexc.ValidationError(value, "is not a valid encoding!") class UserStyleSheet(File): @@ -1086,7 +1080,7 @@ class UserStyleSheet(File): if self._none_ok: return else: - raise ValidationError(value, "may not be empty!") + raise configexc.ValidationError(value, "may not be empty!") value = os.path.expanduser(value) if not os.path.isabs(value): # probably a CSS, so we don't handle it as filename. @@ -1096,10 +1090,10 @@ class UserStyleSheet(File): try: value.encode('utf-8') except UnicodeEncodeError as e: - raise ValidationError(value, str(e)) + raise configexc.ValidationError(value, str(e)) return elif not os.path.isfile(value): - raise ValidationError(value, "must be a valid file!") + raise configexc.ValidationError(value, "must be a valid file!") def transform(self, value): path = os.path.expanduser(value) @@ -1179,14 +1173,16 @@ class UrlList(List): if self._none_ok: return else: - raise ValidationError(value, "list may not be empty!") + raise configexc.ValidationError(value, "list may not be " + "empty!") vals = self.transform(value) for val in vals: if val is None: - raise ValidationError(value, "values may not be empty!") + raise configexc.ValidationError(value, "values may not be " + "empty!") elif not val.isValid(): - raise ValidationError(value, "invalid URL - {}".format( - val.errorString())) + raise configexc.ValidationError(value, "invalid URL - " + "{}".format(val.errorString())) class SelectOnRemove(BaseType): diff --git a/qutebrowser/test/config/test_config.py b/qutebrowser/test/config/test_config.py index 5e49beb74..f6dfe41fd 100644 --- a/qutebrowser/test/config/test_config.py +++ b/qutebrowser/test/config/test_config.py @@ -25,7 +25,7 @@ import configparser from PyQt5.QtGui import QColor -from qutebrowser.config import config, configtypes +from qutebrowser.config import config, configexc class ConfigParserTests(unittest.TestCase): @@ -73,14 +73,14 @@ class ConfigParserTests(unittest.TestCase): def test_invalid_value(self): """Test setting an invalid value.""" self.cp.read_dict({'general': {'ignore-case': 'invalid'}}) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.cfg._from_cp(self.cp) def test_invalid_value_interpolated(self): """Test setting an invalid interpolated value.""" self.cp.read_dict({'general': {'ignore-case': 'smart', 'wrap-search': '${ignore-case}'}}) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.cfg._from_cp(self.cp) def test_interpolation(self): @@ -112,19 +112,19 @@ class ConfigParserTests(unittest.TestCase): def test_invalid_interpolation_syntax(self): """Test an invalid interpolation syntax.""" self.cp.read_dict({'general': {'ignore-case': '${'}}) - with self.assertRaises(config.InterpolationSyntaxError): + with self.assertRaises(configexc.InterpolationSyntaxError): self.cfg._from_cp(self.cp) def test_invalid_section(self): """Test an invalid section.""" self.cp.read_dict({'foo': {'bar': 'baz'}}) - with self.assertRaises(config.UnknownSectionError): + with self.assertRaises(configexc.NoSectionError): self.cfg._from_cp(self.cp) def test_invalid_option(self): """Test an invalid option.""" self.cp.read_dict({'general': {'bar': 'baz'}}) - with self.assertRaises(config.NoOptionError): + with self.assertRaises(configexc.NoOptionError): self.cfg._from_cp(self.cp) diff --git a/qutebrowser/test/config/test_configtypes.py b/qutebrowser/test/config/test_configtypes.py index 7b3e066fa..3862a922f 100644 --- a/qutebrowser/test/config/test_configtypes.py +++ b/qutebrowser/test/config/test_configtypes.py @@ -25,7 +25,7 @@ import os.path import base64 from unittest import mock -from qutebrowser.config import configtypes +from qutebrowser.config import configtypes, configexc from qutebrowser.test import stubs from qutebrowser.utils import debug, utils @@ -147,7 +147,7 @@ class BaseTypeTests(unittest.TestCase): """Test validate with valid_values set.""" self.t.valid_values = configtypes.ValidValues('foo', 'bar') self.t.validate('bar') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('baz') def test_complete_none(self): @@ -204,7 +204,7 @@ class StringTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" t = configtypes.String() - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate("") def test_validate_empty_none_ok(self): @@ -222,15 +222,15 @@ class StringTests(unittest.TestCase): t = configtypes.String(forbidden='xyz') t.validate("foobar") t.validate("foXbar") - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate("foybar") - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate("foxbar") def test_validate_minlen_toosmall(self): """Test validate with a minlen and a too short string.""" t = configtypes.String(minlen=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('f') def test_validate_minlen_ok(self): @@ -241,7 +241,7 @@ class StringTests(unittest.TestCase): def test_validate_maxlen_toolarge(self): """Test validate with a maxlen and a too long string.""" t = configtypes.String(maxlen=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('fob') def test_validate_maxlen_ok(self): @@ -258,9 +258,9 @@ class StringTests(unittest.TestCase): def test_validate_range_bad(self): """Test validate with both min/maxlen and a bad string.""" t = configtypes.String(minlen=2, maxlen=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('f') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('fooo') def test_transform(self): @@ -286,7 +286,7 @@ class ListTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -296,13 +296,13 @@ class ListTests(unittest.TestCase): def test_validate_empty_item(self): """Test validate with empty item and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('foo,,bar') def test_validate_empty_item_none_ok(self): """Test validate with empty item and none_ok = True.""" t = configtypes.List(none_ok=True) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('foo,,bar') def test_transform_single(self): @@ -353,13 +353,13 @@ class BoolTests(unittest.TestCase): """Test validate with invalid values.""" for val in self.INVALID: with self.subTest(val=val): - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate(val) def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" t = configtypes.Bool() - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('') def test_validate_empty_none_ok(self): @@ -385,13 +385,13 @@ class IntTests(unittest.TestCase): def test_validate_string(self): """Test validate with something which isn't an int.""" t = configtypes.Int() - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('foobar') def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" t = configtypes.Int() - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('') def test_validate_empty_none_ok(self): @@ -402,7 +402,7 @@ class IntTests(unittest.TestCase): def test_validate_minval_toosmall(self): """Test validate with a minval and a too small int.""" t = configtypes.Int(minval=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1') def test_validate_minval_ok(self): @@ -413,7 +413,7 @@ class IntTests(unittest.TestCase): def test_validate_maxval_toolarge(self): """Test validate with a maxval and a too big int.""" t = configtypes.Int(maxval=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('3') def test_validate_maxval_ok(self): @@ -430,9 +430,9 @@ class IntTests(unittest.TestCase): def test_validate_range_bad(self): """Test validate with both min/maxval and a bad int.""" t = configtypes.Int(minval=2, maxval=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('4') def test_transform_none(self): @@ -459,7 +459,7 @@ class IntListTests(unittest.TestCase): def test_validate_empty(self): """Test validate with an empty value.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('23,,42') def test_validate_empty_none_ok(self): @@ -469,7 +469,7 @@ class IntListTests(unittest.TestCase): def test_validate_bad(self): """Test validate with bad values.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('23,foo,1337') def test_transform_single(self): @@ -508,13 +508,13 @@ class FloatTests(unittest.TestCase): def test_validate_string(self): """Test validate with something which isn't an float.""" t = configtypes.Float() - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('foobar') def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" t = configtypes.Float() - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('') def test_validate_empty_none_ok(self): @@ -525,7 +525,7 @@ class FloatTests(unittest.TestCase): def test_validate_minval_toosmall(self): """Test validate with a minval and a too small float.""" t = configtypes.Float(minval=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1.99') def test_validate_minval_ok(self): @@ -536,7 +536,7 @@ class FloatTests(unittest.TestCase): def test_validate_maxval_toolarge(self): """Test validate with a maxval and a too big float.""" t = configtypes.Float(maxval=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('2.01') def test_validate_maxval_ok(self): @@ -553,9 +553,9 @@ class FloatTests(unittest.TestCase): def test_validate_range_bad(self): """Test validate with both min/maxval and a bad float.""" t = configtypes.Float(minval=2, maxval=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1.99') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('3.01') def test_transform_empty(self): @@ -588,12 +588,12 @@ class PercTests(unittest.TestCase): def test_validate_int(self): """Test validate with a normal int (not a percentage).""" - with self.assertRaises(ValueError): + with self.assertRaises(configexc.ValidationError): self.t.validate('1337') def test_validate_string(self): """Test validate with something which isn't a percentage.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('1337%%') def test_validate_perc(self): @@ -602,7 +602,7 @@ class PercTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -613,7 +613,7 @@ class PercTests(unittest.TestCase): def test_validate_minval_toosmall(self): """Test validate with a minval and a too small percentage.""" t = configtypes.Perc(minval=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1%') def test_validate_minval_ok(self): @@ -624,7 +624,7 @@ class PercTests(unittest.TestCase): def test_validate_maxval_toolarge(self): """Test validate with a maxval and a too big percentage.""" t = configtypes.Perc(maxval=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('3%') def test_validate_maxval_ok(self): @@ -641,9 +641,9 @@ class PercTests(unittest.TestCase): def test_validate_range_bad(self): """Test validate with both min/maxval and a bad percentage.""" t = configtypes.Perc(minval=2, maxval=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1%') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('4%') def test_transform_empty(self): @@ -673,13 +673,13 @@ class PercListTests(unittest.TestCase): def test_validate_bad(self): """Test validate with bad values.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('23%,42%%,1337%') def test_validate_minval_toosmall(self): """Test validate with a minval and a too small percentage.""" t = configtypes.PercList(minval=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1%') def test_validate_minval_ok(self): @@ -690,7 +690,7 @@ class PercListTests(unittest.TestCase): def test_validate_maxval_toolarge(self): """Test validate with a maxval and a too big percentage.""" t = configtypes.PercList(maxval=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('3%') def test_validate_maxval_ok(self): @@ -707,14 +707,14 @@ class PercListTests(unittest.TestCase): def test_validate_range_bad(self): """Test validate with both min/maxval and a bad percentage.""" t = configtypes.PercList(minval=2, maxval=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1%') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('4%') def test_validate_empty(self): """Test validate with an empty value.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('23%,,42%') def test_validate_empty_none_ok(self): @@ -754,7 +754,7 @@ class PercOrIntTests(unittest.TestCase): def test_validate_string(self): """Test validate with something which isn't a percentage.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('1337%%') def test_validate_perc(self): @@ -767,7 +767,7 @@ class PercOrIntTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -778,7 +778,7 @@ class PercOrIntTests(unittest.TestCase): def test_validate_minint_toosmall(self): """Test validate with a minint and a too small int.""" t = configtypes.PercOrInt(minint=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1') def test_validate_minint_ok(self): @@ -789,7 +789,7 @@ class PercOrIntTests(unittest.TestCase): def test_validate_maxint_toolarge(self): """Test validate with a maxint and a too big int.""" t = configtypes.PercOrInt(maxint=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('3') def test_validate_maxint_ok(self): @@ -806,15 +806,15 @@ class PercOrIntTests(unittest.TestCase): def test_validate_int_range_bad(self): """Test validate with both min/maxint and a bad int.""" t = configtypes.PercOrInt(minint=2, maxint=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('4') def test_validate_minperc_toosmall(self): """Test validate with a minperc and a too small perc.""" t = configtypes.PercOrInt(minperc=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1%') def test_validate_minperc_ok(self): @@ -825,7 +825,7 @@ class PercOrIntTests(unittest.TestCase): def test_validate_maxperc_toolarge(self): """Test validate with a maxperc and a too big perc.""" t = configtypes.PercOrInt(maxperc=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('3%') def test_validate_maxperc_ok(self): @@ -842,9 +842,9 @@ class PercOrIntTests(unittest.TestCase): def test_validate_perc_range_bad(self): """Test validate with both min/maxperc and a bad perc.""" t = configtypes.PercOrInt(minperc=2, maxperc=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1%') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('4%') def test_validate_both_range_int(self): @@ -890,7 +890,7 @@ class CommandTests(unittest.TestCase): def test_validate_empty(self): """Test validate with an empty string.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -910,12 +910,12 @@ class CommandTests(unittest.TestCase): def test_validate_invalid_command(self): """Test validate with an invalid command.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('cmd3') def test_validate_invalid_command_args(self): """Test validate with an invalid command and arguments.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('cmd3 foo bar') def test_transform(self): @@ -953,7 +953,7 @@ class ColorSystemTests(unittest.TestCase): def test_validate_empty(self): """Test validate with an empty string.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -971,7 +971,7 @@ class ColorSystemTests(unittest.TestCase): """Test validate with invalid values.""" for val in self.INVALID: with self.subTest(val=val): - with self.assertRaises(configtypes.ValidationError, msg=val): + with self.assertRaises(configexc.ValidationError, msg=val): self.t.validate(val) def test_transform(self): @@ -998,7 +998,7 @@ class QtColorTests(unittest.TestCase): def test_validate_empty(self): """Test validate with an empty string.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1016,7 +1016,7 @@ class QtColorTests(unittest.TestCase): """Test validate with invalid values.""" for val in self.INVALID + self.INVALID_QT: with self.subTest(val=val): - with self.assertRaises(configtypes.ValidationError, msg=val): + with self.assertRaises(configexc.ValidationError, msg=val): self.t.validate(val) def test_transform(self): @@ -1135,7 +1135,7 @@ class FontTests(unittest.TestCase): def test_validate_empty(self): """Test validate with an empty string.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1162,11 +1162,11 @@ class FontTests(unittest.TestCase): for val in self.INVALID: with self.subTest(val=val): with self.subTest(t="t1"): - with self.assertRaises(configtypes.ValidationError, + with self.assertRaises(configexc.ValidationError, msg=val): self.t.validate(val) with self.subTest(t="t2"): - with self.assertRaises(configtypes.ValidationError, + with self.assertRaises(configexc.ValidationError, msg=val): self.t2.validate(val) @@ -1208,7 +1208,7 @@ class RegexTests(unittest.TestCase): def test_validate_empty(self): """Test validate with an empty string.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1222,7 +1222,7 @@ class RegexTests(unittest.TestCase): def test_validate_invalid(self): """Test validate with an invalid regex.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate(r'(foo|bar))?baz[fis]h') def test_transform_empty(self): @@ -1247,7 +1247,7 @@ class RegexListTests(unittest.TestCase): def test_validate_empty(self): """Test validate with an empty value.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate(r'(foo|bar),,1337{42}') def test_validate_empty_none_ok(self): @@ -1257,7 +1257,7 @@ class RegexListTests(unittest.TestCase): def test_validate_bad(self): """Test validate with bad values.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate(r'(foo|bar),((),1337{42}') def test_transform_single(self): @@ -1286,7 +1286,7 @@ class FileTests(unittest.TestCase): def test_validate_empty(self, _os_path): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate("") def test_validate_empty_none_ok(self, _os_path): @@ -1298,7 +1298,7 @@ class FileTests(unittest.TestCase): """Test validate with a file which does not exist.""" os_path.expanduser.side_effect = lambda x: x os_path.isfile.return_value = False - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('foobar') def test_validate_exists_abs(self, os_path): @@ -1313,7 +1313,7 @@ class FileTests(unittest.TestCase): os_path.expanduser.side_effect = lambda x: x os_path.isfile.return_value = True os_path.isabs.return_value = False - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('foobar') def test_validate_expanduser(self, os_path): @@ -1345,7 +1345,7 @@ class DirectoryTests(unittest.TestCase): def test_validate_empty(self, _os_path): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate("") def test_validate_empty_none_ok(self, _os_path): @@ -1357,7 +1357,7 @@ class DirectoryTests(unittest.TestCase): """Test validate with a directory which does not exist.""" os_path.expanduser.side_effect = lambda x: x os_path.isdir.return_value = False - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('foobar') def test_validate_exists_abs(self, os_path): @@ -1372,7 +1372,7 @@ class DirectoryTests(unittest.TestCase): os_path.expanduser.side_effect = lambda x: x os_path.isdir.return_value = True os_path.isabs.return_value = False - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('foobar') def test_validate_expanduser(self, os_path): @@ -1420,18 +1420,18 @@ class WebKitByteTests(unittest.TestCase): def test_validate_int_negative(self): """Test validate with a negative int.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('-1') def test_validate_int_negative_suffix(self): """Test validate with a negative int with suffix.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('-1k') def test_validate_int_toobig(self): """Test validate with an int which is too big.""" t = configtypes.WebKitBytes(maxsize=10) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('11') def test_validate_int_not_toobig(self): @@ -1442,17 +1442,17 @@ class WebKitByteTests(unittest.TestCase): def test_validate_int_toobig_suffix(self): """Test validate with an int which is too big with suffix.""" t = configtypes.WebKitBytes(maxsize=10) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1k') def test_validate_int_invalid_suffix(self): """Test validate with an int with an invalid suffix.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('56x') def test_validate_int_double_suffix(self): """Test validate with an int with a double suffix.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('56kk') def test_transform_empty(self): @@ -1483,15 +1483,15 @@ class WebKitBytesListTests(unittest.TestCase): def test_validate_bad(self): """Test validate with bad values.""" t = configtypes.WebKitBytesList() - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('23,56kk,1337') def test_validate_maxsize_toolarge(self): """Test validate with a maxsize and a too big size.""" t = configtypes.WebKitBytesList(maxsize=2) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('3') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('3k') def test_validate_maxsize_ok(self): @@ -1501,7 +1501,7 @@ class WebKitBytesListTests(unittest.TestCase): def test_validate_empty(self): """Test validate with an empty value.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('23,,42') def test_validate_empty_none_ok(self): @@ -1512,7 +1512,7 @@ class WebKitBytesListTests(unittest.TestCase): def test_validate_len_tooshort(self): """Test validate with a too short length.""" t = configtypes.WebKitBytesList(length=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1,2') def test_validate_len_ok(self): @@ -1523,7 +1523,7 @@ class WebKitBytesListTests(unittest.TestCase): def test_validate_len_toolong(self): """Test validate with a too long length.""" t = configtypes.WebKitBytesList(length=3) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('1,2,3,4') def test_transform_single(self): @@ -1548,7 +1548,7 @@ class ShellCommandTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate("") def test_validate_empty_none_ok(self): @@ -1568,7 +1568,7 @@ class ShellCommandTests(unittest.TestCase): def test_validate_placeholder_invalid(self): """Test validate with an invalid placeholder.""" t = configtypes.ShellCommand(placeholder='{}') - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('foo{} bar') def test_transform_single(self): @@ -1598,7 +1598,7 @@ class ProxyTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1616,12 +1616,12 @@ class ProxyTests(unittest.TestCase): def test_validate_invalid(self): """Test validate with an invalid URL.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate(':') def test_validate_scheme(self): """Test validate with a URL with wrong scheme.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('ftp://example.com/') def test_validate_http(self): @@ -1707,7 +1707,7 @@ class SearchEngineNameTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1733,7 +1733,7 @@ class SearchEngineUrlTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1743,7 +1743,7 @@ class SearchEngineUrlTests(unittest.TestCase): def test_validate_no_placeholder(self): """Test validate with no placeholder.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('foo') def test_validate(self): @@ -1752,7 +1752,7 @@ class SearchEngineUrlTests(unittest.TestCase): def test_validate_invalid_url(self): """Test validate with an invalud URL.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate(':{}') def test_transform_empty(self): @@ -1803,7 +1803,7 @@ class AutoSearchTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1822,7 +1822,7 @@ class AutoSearchTests(unittest.TestCase): """Test validate with invalid values.""" for val in self.INVALID: with self.subTest(val=val): - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate(val) def test_transform(self): @@ -1853,7 +1853,7 @@ class IgnoreCaseTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1872,7 +1872,7 @@ class IgnoreCaseTests(unittest.TestCase): """Test validate with invalid values.""" for val in self.INVALID: with self.subTest(val=val): - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate(val) def test_transform(self): @@ -1896,7 +1896,7 @@ class EncodingTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1912,7 +1912,7 @@ class EncodingTests(unittest.TestCase): def test_validate_invalid(self): """Test validate with an invalid value.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('blubber') def test_transform(self): @@ -1941,7 +1941,7 @@ class UrlListTests(unittest.TestCase): def test_validate_empty(self): """Test validate with empty string and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('') def test_validate_empty_none_ok(self): @@ -1951,13 +1951,13 @@ class UrlListTests(unittest.TestCase): def test_validate_empty_item(self): """Test validate with empty item and none_ok = False.""" - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): self.t.validate('foo,,bar') def test_validate_empty_item_none_ok(self): """Test validate with empty item and none_ok = True.""" t = configtypes.UrlList(none_ok=True) - with self.assertRaises(configtypes.ValidationError): + with self.assertRaises(configexc.ValidationError): t.validate('foo,,bar') def test_transform_single(self): diff --git a/qutebrowser/test/stubs.py b/qutebrowser/test/stubs.py index 8d9e99399..22a184652 100644 --- a/qutebrowser/test/stubs.py +++ b/qutebrowser/test/stubs.py @@ -26,6 +26,8 @@ from unittest import mock from PyQt5.QtCore import QPoint, QProcess from PyQt5.QtNetwork import QNetworkRequest +from qutebrowser.config import configexc + class ConfigStub: @@ -35,12 +37,6 @@ class ConfigStub: data: The config data to return. """ - class NoOptionError(Exception): - - """NoOptionError exception.""" - - pass - def __init__(self, data): self.data = data @@ -61,7 +57,7 @@ class ConfigStub: try: return data[opt] except KeyError: - raise self.NoOptionError('{} -> {}'.format(sect, opt)) + raise configexc.NoOptionError(opt, sect) class FakeKeyEvent: diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index f66e7559b..041299a75 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -28,7 +28,7 @@ import urllib.parse from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QHostInfo -from qutebrowser.config import config +from qutebrowser.config import config, configexc from qutebrowser.utils import log, qtutils, message, utils from qutebrowser.commands import cmdexc @@ -53,7 +53,7 @@ def _get_search_url(txt): engine = m.group(1) try: template = config.get('searchengines', engine) - except config.NoOptionError: + except configexc.NoOptionError: template = config.get('searchengines', 'DEFAULT') term = txt else: