Simplify config exception tree and handling.

Also make sure we catch all config-related errors in all related places.
Fixes #324.
This commit is contained in:
Florian Bruhin 2014-12-17 11:17:18 +01:00
parent 30b5319068
commit 512d7c4448
10 changed files with 251 additions and 291 deletions

View File

@ -35,7 +35,7 @@ import pygments.lexers
import pygments.formatters import pygments.formatters
from qutebrowser.commands import userscripts, cmdexc, cmdutils 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.browser import webelem
from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils, from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils,
objreg, utils) objreg, utils)
@ -921,10 +921,10 @@ class CommandDispatcher:
topic)) topic))
try: try:
config.get(*parts) config.get(*parts)
except config.NoSectionError: except configexc.NoSectionError:
raise cmdexc.CommandError("Invalid section {}!".format( raise cmdexc.CommandError("Invalid section {}!".format(
parts[0])) parts[0]))
except config.NoOptionError: except configexc.NoOptionError:
raise cmdexc.CommandError("Invalid option {}!".format( raise cmdexc.CommandError("Invalid option {}!".format(
parts[1])) parts[1]))
path = 'settings.html#{}'.format(topic.replace('->', '-')) path = 'settings.html#{}'.format(topic.replace('->', '-'))

View File

@ -27,6 +27,8 @@ Module attributes:
pyeval_output: The output of the last :pyeval command. pyeval_output: The output of the last :pyeval command.
""" """
import configparser
from PyQt5.QtCore import pyqtSlot, QObject from PyQt5.QtCore import pyqtSlot, QObject
from PyQt5.QtNetwork import QNetworkReply from PyQt5.QtNetwork import QNetworkReply
@ -34,7 +36,7 @@ import qutebrowser
from qutebrowser.browser.network import schemehandler, networkreply from qutebrowser.browser.network import schemehandler, networkreply
from qutebrowser.utils import (version, utils, jinja, log, message, docutils, from qutebrowser.utils import (version, utils, jinja, log, message, docutils,
objreg) objreg)
from qutebrowser.config import configtypes, configdata from qutebrowser.config import configexc, configdata
pyeval_output = ":pyeval was never called" pyeval_output = ":pyeval was never called"
@ -93,7 +95,7 @@ class JSBridge(QObject):
"""Slot to set a setting from qute:settings.""" """Slot to set a setting from qute:settings."""
try: try:
objreg.get('config').set('conf', sectname, optname, value) 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) message.error(win_id, e)

View File

@ -24,7 +24,7 @@ import re
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QUrl from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QUrl
from PyQt5.QtWebKitWidgets import QWebPage from PyQt5.QtWebKitWidgets import QWebPage
from qutebrowser.config import config from qutebrowser.config import config, configexc
from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.commands import cmdexc, cmdutils
from qutebrowser.utils import message, log, utils, objreg from qutebrowser.utils import message, log, utils, objreg
from qutebrowser.misc import split from qutebrowser.misc import split
@ -180,7 +180,7 @@ class CommandRunner(QObject):
parts = text.strip().split(maxsplit=1) parts = text.strip().split(maxsplit=1)
try: try:
alias = config.get('aliases', parts[0]) alias = config.get('aliases', parts[0])
except (config.NoOptionError, config.NoSectionError): except (configexc.NoOptionError, configexc.NoSectionError):
return None return None
try: try:
new_cmd = '{} {}'.format(alias, parts[1]) new_cmd = '{} {}'.format(alias, parts[1])

View File

@ -28,7 +28,7 @@ from PyQt5.QtCore import QRectF, QSize, Qt
from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption, from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption,
QAbstractTextDocumentLayout) QAbstractTextDocumentLayout)
from qutebrowser.config import config, style from qutebrowser.config import config, configexc, style
from qutebrowser.utils import qtutils from qutebrowser.utils import qtutils
@ -154,7 +154,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
option = 'completion.fg' option = 'completion.fg'
try: try:
self._painter.setPen(config.get('colors', option)) self._painter.setPen(config.get('colors', option))
except config.NoOptionError: except configexc.NoOptionError:
self._painter.setPen(config.get('colors', 'completion.fg')) self._painter.setPen(config.get('colors', 'completion.fg'))
ctx = QAbstractTextDocumentLayout.PaintContext() ctx = QAbstractTextDocumentLayout.PaintContext()
ctx.palette.setColor(QPalette.Text, self._painter.pen().color()) ctx.palette.setColor(QPalette.Text, self._painter.pen().color())

View File

@ -35,7 +35,7 @@ import collections.abc
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QStandardPaths, QUrl from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QStandardPaths, QUrl
from PyQt5.QtWidgets import QMessageBox 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.config.parsers import ini, keyconf
from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.commands import cmdexc, cmdutils
from qutebrowser.utils import message, objreg, utils, standarddir, log, qtutils from qutebrowser.utils import message, objreg, utils, standarddir, log, qtutils
@ -63,11 +63,9 @@ class change_filter: # pylint: disable=invalid-name
See class attributes. See class attributes.
""" """
if sectname not in configdata.DATA: if sectname not in configdata.DATA:
raise NoSectionError("Section '{}' does not exist!".format( raise configexc.NoSectionError(sectname)
sectname))
if optname is not None and optname not in configdata.DATA[sectname]: if optname is not None and optname not in configdata.DATA[sectname]:
raise NoOptionError("Option '{}' does not exist in section " raise configexc.NoOptionError(optname, sectname)
"'{}'!".format(optname, sectname))
self._sectname = sectname self._sectname = sectname
self._optname = optname self._optname = optname
@ -125,16 +123,14 @@ def init(args):
try: try:
app = objreg.get('app') app = objreg.get('app')
config_obj = ConfigManager(confdir, 'qutebrowser.conf', app) config_obj = ConfigManager(confdir, 'qutebrowser.conf', app)
except (configtypes.ValidationError, NoOptionError, NoSectionError, except (configexc.Error, configparser.Error) as e:
UnknownSectionError, InterpolationSyntaxError,
configparser.InterpolationError,
configparser.DuplicateSectionError,
configparser.DuplicateOptionError,
configparser.ParsingError) as e:
log.init.exception(e) log.init.exception(e)
errstr = "Error while reading config:" errstr = "Error while reading config:"
if hasattr(e, 'section') and hasattr(e, 'option'): try:
errstr += "\n\n{} -> {}:".format(e.section, e.option) errstr += "\n\n{} -> {}:".format(
e.section, e.option) # pylint: disable=no-member
except AttributeError:
pass
errstr += "\n{}".format(e) errstr += "\n{}".format(e)
msgbox = QMessageBox(QMessageBox.Critical, msgbox = QMessageBox(QMessageBox.Critical,
"Error while reading config!", errstr) "Error while reading config!", errstr)
@ -169,34 +165,6 @@ def init(args):
objreg.register('command-history', command_history) 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): class ConfigManager(QObject):
"""Configuration manager for qutebrowser. """Configuration manager for qutebrowser.
@ -378,8 +346,7 @@ class ConfigManager(QObject):
if sectname in self.RENAMED_SECTIONS: if sectname in self.RENAMED_SECTIONS:
sectname = self.RENAMED_SECTIONS[sectname] sectname = self.RENAMED_SECTIONS[sectname]
if sectname is not 'DEFAULT' and sectname not in self.sections: if sectname is not 'DEFAULT' and sectname not in self.sections:
raise UnknownSectionError("Unknown section '{}'!".format( raise configexc.NoSectionError(sectname)
sectname))
for sectname in self.sections: for sectname in self.sections:
real_sectname = self._get_real_sectname(cp, sectname) real_sectname = self._get_real_sectname(cp, sectname)
if real_sectname is None: if real_sectname is None:
@ -401,7 +368,7 @@ class ConfigManager(QObject):
self, sectname, optname, opt.value(), mapping) self, sectname, optname, opt.value(), mapping)
try: try:
opt.typ.validate(interpolated) opt.typ.validate(interpolated)
except configtypes.ValidationError as e: except configexc.ValidationError as e:
e.section = sectname e.section = sectname
e.option = optname e.option = optname
raise raise
@ -473,7 +440,7 @@ class ConfigManager(QObject):
try: try:
sectdict = self.sections[sectname] sectdict = self.sections[sectname]
except KeyError: except KeyError:
raise NoSectionError(sectname) raise configexc.NoSectionError(sectname)
optname = self.optionxform(optname) optname = self.optionxform(optname)
existed = optname in sectdict existed = optname in sectdict
if existed: if existed:
@ -500,11 +467,11 @@ class ConfigManager(QObject):
try: try:
sect = self.sections[sectname] sect = self.sections[sectname]
except KeyError: except KeyError:
raise NoSectionError(sectname) raise configexc.NoSectionError(sectname)
try: try:
val = sect[optname] val = sect[optname]
except KeyError: except KeyError:
raise NoOptionError(optname, sectname) raise configexc.NoOptionError(optname, sectname)
if raw: if raw:
return val.value() return val.value()
mapping = {key: val.value() for key, val in sect.values.items()} mapping = {key: val.value() for key, val in sect.values.items()}
@ -555,8 +522,7 @@ class ConfigManager(QObject):
"are required: value") "are required: value")
layer = 'temp' if temp else 'conf' layer = 'temp' if temp else 'conf'
self.set(layer, sectname, optname, value) self.set(layer, sectname, optname, value)
except (NoOptionError, NoSectionError, configtypes.ValidationError, except (configexc.Error, configparser.Error) as e:
ValueError) as e:
raise cmdexc.CommandError("set: {} - {}".format( raise cmdexc.CommandError("set: {} - {}".format(
e.__class__.__name__, e)) e.__class__.__name__, e))
@ -574,11 +540,11 @@ class ConfigManager(QObject):
value = self._interpolation.before_set(self, sectname, optname, value = self._interpolation.before_set(self, sectname, optname,
value) value)
except ValueError as e: except ValueError as e:
raise InterpolationSyntaxError(e) raise configexc.InterpolationSyntaxError(optname, sectname, str(e))
try: try:
sect = self.sections[sectname] sect = self.sections[sectname]
except KeyError: except KeyError:
raise NoSectionError(sectname) raise configexc.NoSectionError(sectname)
mapping = {key: val.value() for key, val in sect.values.items()} mapping = {key: val.value() for key, val in sect.values.items()}
if validate: if validate:
interpolated = self._interpolation.before_get( interpolated = self._interpolation.before_get(
@ -588,7 +554,7 @@ class ConfigManager(QObject):
try: try:
sect.setv(layer, optname, value, interpolated) sect.setv(layer, optname, value, interpolated)
except KeyError: except KeyError:
raise NoOptionError(optname, sectname) raise configexc.NoOptionError(optname, sectname)
else: else:
if self._initialized: if self._initialized:
self._after_set(sectname, optname) self._after_set(sectname, optname)

View File

@ -32,28 +32,12 @@ from PyQt5.QtNetwork import QNetworkProxy
from PyQt5.QtWidgets import QTabWidget, QTabBar from PyQt5.QtWidgets import QTabWidget, QTabBar
from qutebrowser.commands import cmdutils from qutebrowser.commands import cmdutils
from qutebrowser.config import configexc
SYSTEM_PROXY = object() # Return value for Proxy type 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: class ValidValues:
"""Container for valid values for a given type. """Container for valid values for a given type.
@ -133,8 +117,9 @@ class BaseType:
return return
if self.valid_values is not None: if self.valid_values is not None:
if value not in self.valid_values: if value not in self.valid_values:
raise ValidationError(value, "valid values: {}".format( raise configexc.ValidationError(
', '.join(self.valid_values))) value, "valid values: {}".format(', '.join(
self.valid_values)))
else: else:
return return
else: else:
@ -196,17 +181,17 @@ class String(BaseType):
if self._none_ok: if self._none_ok:
return return
else: 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 if self.forbidden is not None and any(c in value
for c in self.forbidden): for c in self.forbidden):
raise ValidationError(value, "may not contain the chars " raise configexc.ValidationError(value, "may not contain the chars "
"'{}'".format(self.forbidden)) "'{}'".format(self.forbidden))
if self.minlen is not None and len(value) < self.minlen: if self.minlen is not None and len(value) < self.minlen:
raise ValidationError(value, "must be at least {} chars " raise configexc.ValidationError(value, "must be at least {} chars "
"long!".format(self.minlen)) "long!".format(self.minlen))
if self.maxlen is not None and len(value) > self.maxlen: if self.maxlen is not None and len(value) > self.maxlen:
raise ValidationError(value, "must be at most {} long!".format( raise configexc.ValidationError(value, "must be at most {} chars "
self.maxlen)) "long!".format(self.maxlen))
class List(BaseType): class List(BaseType):
@ -226,10 +211,11 @@ class List(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "list may not be empty!") raise configexc.ValidationError(value, "list may not be "
"empty!")
vals = self.transform(value) vals = self.transform(value)
if None in vals: if None in vals:
raise ValidationError(value, "items may not be empty!") raise configexc.ValidationError(value, "items may not be empty!")
class Bool(BaseType): class Bool(BaseType):
@ -259,9 +245,9 @@ class Bool(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
if value.lower() not in Bool._BOOLEAN_STATES: 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): class BoolAsk(Bool):
@ -313,17 +299,17 @@ class Int(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
try: try:
intval = int(value) intval = int(value)
except ValueError: 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: if self.minval is not None and intval < self.minval:
raise ValidationError(value, "must be {} or bigger!".format( raise configexc.ValidationError(value, "must be {} or "
self.minval)) "bigger!".format(self.minval))
if self.maxval is not None and intval > self.maxval: if self.maxval is not None and intval > self.maxval:
raise ValidationError(value, "must be {} or smaller!".format( raise configexc.ValidationError(value, "must be {} or "
self.maxval)) "smaller!".format(self.maxval))
class IntList(List): class IntList(List):
@ -340,9 +326,10 @@ class IntList(List):
try: try:
vals = self.transform(value) vals = self.transform(value)
except ValueError: 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: 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): class Float(BaseType):
@ -375,17 +362,17 @@ class Float(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
try: try:
floatval = float(value) floatval = float(value)
except ValueError: 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: if self.minval is not None and floatval < self.minval:
raise ValidationError(value, "must be {} or bigger!".format( raise configexc.ValidationError(value, "must be {} or "
self.minval)) "bigger!".format(self.minval))
if self.maxval is not None and floatval > self.maxval: if self.maxval is not None and floatval > self.maxval:
raise ValidationError(value, "must be {} or smaller!".format( raise configexc.ValidationError(value, "must be {} or "
self.maxval)) "smaller!".format(self.maxval))
class Perc(BaseType): class Perc(BaseType):
@ -418,19 +405,19 @@ class Perc(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty") raise configexc.ValidationError(value, "may not be empty")
if not value.endswith('%'): if not value.endswith('%'):
raise ValidationError(value, "does not end with %") raise configexc.ValidationError(value, "does not end with %")
try: try:
intval = int(value[:-1]) intval = int(value[:-1])
except ValueError: except ValueError:
raise ValidationError(value, "invalid percentage!") raise configexc.ValidationError(value, "invalid percentage!")
if self.minval is not None and intval < self.minval: if self.minval is not None and intval < self.minval:
raise ValidationError(value, "must be {}% or more!".format( raise configexc.ValidationError(value, "must be {}% or "
self.minval)) "more!".format(self.minval))
if self.maxval is not None and intval > self.maxval: if self.maxval is not None and intval > self.maxval:
raise ValidationError(value, "must be {}% or less!".format( raise configexc.ValidationError(value, "must be {}% or "
self.maxval)) "less!".format(self.maxval))
class PercList(List): class PercList(List):
@ -465,11 +452,13 @@ class PercList(List):
if self._none_ok: if self._none_ok:
continue continue
else: else:
raise ValidationError(value, "items may not be empty!") raise configexc.ValidationError(value, "items may not "
"be empty!")
else: else:
perctype.validate(val) perctype.validate(val)
except ValidationError: except configexc.ValidationError:
raise ValidationError(value, "must be a list of percentages!") raise configexc.ValidationError(value, "must be a list of "
"percentages!")
class PercOrInt(BaseType): class PercOrInt(BaseType):
@ -504,29 +493,30 @@ class PercOrInt(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
if value.endswith('%'): if value.endswith('%'):
try: try:
intval = int(value[:-1]) intval = int(value[:-1])
except ValueError: except ValueError:
raise ValidationError(value, "invalid percentage!") raise configexc.ValidationError(value, "invalid percentage!")
if self.minperc is not None and intval < self.minperc: if self.minperc is not None and intval < self.minperc:
raise ValidationError(value, "must be {}% or more!".format( raise configexc.ValidationError(value, "must be {}% or "
self.minperc)) "more!".format(self.minperc))
if self.maxperc is not None and intval > self.maxperc: if self.maxperc is not None and intval > self.maxperc:
raise ValidationError(value, "must be {}% or less!".format( raise configexc.ValidationError(value, "must be {}% or "
self.maxperc)) "less!".format(self.maxperc))
else: else:
try: try:
intval = int(value) intval = int(value)
except ValueError: 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: if self.minint is not None and intval < self.minint:
raise ValidationError(value, "must be {} or bigger!".format( raise configexc.ValidationError(value, "must be {} or "
self.minint)) "bigger!".format(self.minint))
if self.maxint is not None and intval > self.maxint: if self.maxint is not None and intval > self.maxint:
raise ValidationError(value, "must be {} or smaller!".format( raise configexc.ValidationError(value, "must be {} or "
self.maxint)) "smaller!".format(self.maxint))
class Command(BaseType): class Command(BaseType):
@ -540,9 +530,9 @@ class Command(BaseType):
if self._none_ok: if self._none_ok:
return return
else: 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: 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): def complete(self):
out = [] out = []
@ -585,11 +575,11 @@ class QtColor(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
elif QColor.isValidColor(value): elif QColor.isValidColor(value):
pass pass
else: else:
raise ValidationError(value, "must be a valid color") raise configexc.ValidationError(value, "must be a valid color")
def transform(self, value): def transform(self, value):
if not value: if not value:
@ -609,14 +599,14 @@ class CssColor(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
if value.startswith('-'): if value.startswith('-'):
# custom function name, won't validate. # custom function name, won't validate.
pass pass
elif QColor.isValidColor(value): elif QColor.isValidColor(value):
pass pass
else: else:
raise ValidationError(value, "must be a valid color") raise configexc.ValidationError(value, "must be a valid color")
class QssColor(CssColor): class QssColor(CssColor):
@ -644,14 +634,14 @@ class QssColor(CssColor):
if self._none_ok: if self._none_ok:
return return
else: 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): 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 # QColor doesn't handle these, so we do the best we can easily
pass pass
elif QColor.isValidColor(value): elif QColor.isValidColor(value):
pass pass
else: else:
raise ValidationError(value, "must be a valid color") raise configexc.ValidationError(value, "must be a valid color")
class Font(BaseType): class Font(BaseType):
@ -680,9 +670,9 @@ class Font(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
if not self.font_regex.match(value): 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): class QtFont(Font):
@ -747,11 +737,12 @@ class Regex(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
try: try:
re.compile(value, self.flags) re.compile(value, self.flags)
except sre_constants.error as e: 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): def transform(self, value):
if not value: if not value:
@ -779,10 +770,10 @@ class RegexList(List):
try: try:
vals = self.transform(value) vals = self.transform(value)
except sre_constants.error as e: except sre_constants.error as e:
raise ValidationError(value, "must be a list valid regexes - " + raise configexc.ValidationError(value, "must be a list valid "
str(e)) "regexes - " + str(e))
if not self._none_ok and None in vals: 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): class File(BaseType):
@ -796,12 +787,12 @@ class File(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
value = os.path.expanduser(value) value = os.path.expanduser(value)
if not os.path.isfile(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): 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): def transform(self, value):
if not value: if not value:
@ -820,12 +811,13 @@ class Directory(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
value = os.path.expanduser(value) value = os.path.expanduser(value)
if not os.path.isdir(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): 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): def transform(self, value):
if not value: if not value:
@ -868,13 +860,13 @@ class WebKitBytes(BaseType):
try: try:
val = self.transform(value) val = self.transform(value)
except ValueError: except ValueError:
raise ValidationError(value, "must be a valid integer with " raise configexc.ValidationError(value, "must be a valid integer "
"optional suffix!") "with optional suffix!")
if self.maxsize is not None and val > self.maxsize: if self.maxsize is not None and val > self.maxsize:
raise ValidationError(value, "must be {} " raise configexc.ValidationError(value, "must be {} "
"maximum!".format(self.maxsize)) "maximum!".format(self.maxsize))
if val < 0: if val < 0:
raise ValidationError(value, "must be 0 minimum!") raise configexc.ValidationError(value, "must be 0 minimum!")
def transform(self, value): def transform(self, value):
if not value: if not value:
@ -919,10 +911,10 @@ class WebKitBytesList(List):
for val in vals: for val in vals:
self.bytestype.validate(val) self.bytestype.validate(val)
if None in vals and not self._none_ok: 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: if self.length is not None and len(vals) != self.length:
raise ValidationError(value, "exactly {} values need to be " raise configexc.ValidationError(value, "exactly {} values need to "
"set!".format(self.length)) "be set!".format(self.length))
class ShellCommand(BaseType): class ShellCommand(BaseType):
@ -944,13 +936,14 @@ class ShellCommand(BaseType):
if self._none_ok: if self._none_ok:
return return
else: 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): 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: try:
shlex.split(value) shlex.split(value)
except ValueError as e: except ValueError as e:
raise ValidationError(value, str(e)) raise configexc.ValidationError(value, str(e))
def transform(self, value): def transform(self, value):
if not value: if not value:
@ -986,16 +979,17 @@ class Proxy(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
if value in self.valid_values: if value in self.valid_values:
return return
url = QUrl(value) url = QUrl(value)
if not url.isValid(): if not url.isValid():
raise ValidationError(value, "invalid url, {}".format( raise configexc.ValidationError(value, "invalid url, {}".format(
url.errorString())) url.errorString()))
elif url.scheme() not in self.PROXY_TYPES: elif url.scheme() not in self.PROXY_TYPES:
raise ValidationError(value, "must be a proxy URL (http://... or " raise configexc.ValidationError(value, "must be a proxy URL "
"socks://...) or system/none!") "(http://... or socks://...) or "
"system/none!")
def complete(self): def complete(self):
out = [] out = []
@ -1033,7 +1027,7 @@ class SearchEngineName(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
class SearchEngineUrl(BaseType): class SearchEngineUrl(BaseType):
@ -1045,12 +1039,12 @@ class SearchEngineUrl(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
if '{}' not in value: if '{}' not in value:
raise ValidationError(value, "must contain \"{}\"") raise configexc.ValidationError(value, "must contain \"{}\"")
url = QUrl(value.replace('{}', 'foobar')) url = QUrl(value.replace('{}', 'foobar'))
if not url.isValid(): if not url.isValid():
raise ValidationError(value, "invalid url, {}".format( raise configexc.ValidationError(value, "invalid url, {}".format(
url.errorString())) url.errorString()))
@ -1065,11 +1059,11 @@ class Encoding(BaseType):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
try: try:
codecs.lookup(value) codecs.lookup(value)
except LookupError: except LookupError:
raise ValidationError(value, "is not a valid encoding!") raise configexc.ValidationError(value, "is not a valid encoding!")
class UserStyleSheet(File): class UserStyleSheet(File):
@ -1086,7 +1080,7 @@ class UserStyleSheet(File):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
value = os.path.expanduser(value) value = os.path.expanduser(value)
if not os.path.isabs(value): if not os.path.isabs(value):
# probably a CSS, so we don't handle it as filename. # probably a CSS, so we don't handle it as filename.
@ -1096,10 +1090,10 @@ class UserStyleSheet(File):
try: try:
value.encode('utf-8') value.encode('utf-8')
except UnicodeEncodeError as e: except UnicodeEncodeError as e:
raise ValidationError(value, str(e)) raise configexc.ValidationError(value, str(e))
return return
elif not os.path.isfile(value): 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): def transform(self, value):
path = os.path.expanduser(value) path = os.path.expanduser(value)
@ -1179,14 +1173,16 @@ class UrlList(List):
if self._none_ok: if self._none_ok:
return return
else: else:
raise ValidationError(value, "list may not be empty!") raise configexc.ValidationError(value, "list may not be "
"empty!")
vals = self.transform(value) vals = self.transform(value)
for val in vals: for val in vals:
if val is None: 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(): elif not val.isValid():
raise ValidationError(value, "invalid URL - {}".format( raise configexc.ValidationError(value, "invalid URL - "
val.errorString())) "{}".format(val.errorString()))
class SelectOnRemove(BaseType): class SelectOnRemove(BaseType):

View File

@ -25,7 +25,7 @@ import configparser
from PyQt5.QtGui import QColor from PyQt5.QtGui import QColor
from qutebrowser.config import config, configtypes from qutebrowser.config import config, configexc
class ConfigParserTests(unittest.TestCase): class ConfigParserTests(unittest.TestCase):
@ -73,14 +73,14 @@ class ConfigParserTests(unittest.TestCase):
def test_invalid_value(self): def test_invalid_value(self):
"""Test setting an invalid value.""" """Test setting an invalid value."""
self.cp.read_dict({'general': {'ignore-case': 'invalid'}}) self.cp.read_dict({'general': {'ignore-case': 'invalid'}})
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.cfg._from_cp(self.cp) self.cfg._from_cp(self.cp)
def test_invalid_value_interpolated(self): def test_invalid_value_interpolated(self):
"""Test setting an invalid interpolated value.""" """Test setting an invalid interpolated value."""
self.cp.read_dict({'general': {'ignore-case': 'smart', self.cp.read_dict({'general': {'ignore-case': 'smart',
'wrap-search': '${ignore-case}'}}) 'wrap-search': '${ignore-case}'}})
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.cfg._from_cp(self.cp) self.cfg._from_cp(self.cp)
def test_interpolation(self): def test_interpolation(self):
@ -112,19 +112,19 @@ class ConfigParserTests(unittest.TestCase):
def test_invalid_interpolation_syntax(self): def test_invalid_interpolation_syntax(self):
"""Test an invalid interpolation syntax.""" """Test an invalid interpolation syntax."""
self.cp.read_dict({'general': {'ignore-case': '${'}}) self.cp.read_dict({'general': {'ignore-case': '${'}})
with self.assertRaises(config.InterpolationSyntaxError): with self.assertRaises(configexc.InterpolationSyntaxError):
self.cfg._from_cp(self.cp) self.cfg._from_cp(self.cp)
def test_invalid_section(self): def test_invalid_section(self):
"""Test an invalid section.""" """Test an invalid section."""
self.cp.read_dict({'foo': {'bar': 'baz'}}) self.cp.read_dict({'foo': {'bar': 'baz'}})
with self.assertRaises(config.UnknownSectionError): with self.assertRaises(configexc.NoSectionError):
self.cfg._from_cp(self.cp) self.cfg._from_cp(self.cp)
def test_invalid_option(self): def test_invalid_option(self):
"""Test an invalid option.""" """Test an invalid option."""
self.cp.read_dict({'general': {'bar': 'baz'}}) self.cp.read_dict({'general': {'bar': 'baz'}})
with self.assertRaises(config.NoOptionError): with self.assertRaises(configexc.NoOptionError):
self.cfg._from_cp(self.cp) self.cfg._from_cp(self.cp)

View File

@ -25,7 +25,7 @@ import os.path
import base64 import base64
from unittest import mock from unittest import mock
from qutebrowser.config import configtypes from qutebrowser.config import configtypes, configexc
from qutebrowser.test import stubs from qutebrowser.test import stubs
from qutebrowser.utils import debug, utils from qutebrowser.utils import debug, utils
@ -147,7 +147,7 @@ class BaseTypeTests(unittest.TestCase):
"""Test validate with valid_values set.""" """Test validate with valid_values set."""
self.t.valid_values = configtypes.ValidValues('foo', 'bar') self.t.valid_values = configtypes.ValidValues('foo', 'bar')
self.t.validate('bar') self.t.validate('bar')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('baz') self.t.validate('baz')
def test_complete_none(self): def test_complete_none(self):
@ -204,7 +204,7 @@ class StringTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
t = configtypes.String() t = configtypes.String()
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate("") t.validate("")
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -222,15 +222,15 @@ class StringTests(unittest.TestCase):
t = configtypes.String(forbidden='xyz') t = configtypes.String(forbidden='xyz')
t.validate("foobar") t.validate("foobar")
t.validate("foXbar") t.validate("foXbar")
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate("foybar") t.validate("foybar")
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate("foxbar") t.validate("foxbar")
def test_validate_minlen_toosmall(self): def test_validate_minlen_toosmall(self):
"""Test validate with a minlen and a too short string.""" """Test validate with a minlen and a too short string."""
t = configtypes.String(minlen=2) t = configtypes.String(minlen=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('f') t.validate('f')
def test_validate_minlen_ok(self): def test_validate_minlen_ok(self):
@ -241,7 +241,7 @@ class StringTests(unittest.TestCase):
def test_validate_maxlen_toolarge(self): def test_validate_maxlen_toolarge(self):
"""Test validate with a maxlen and a too long string.""" """Test validate with a maxlen and a too long string."""
t = configtypes.String(maxlen=2) t = configtypes.String(maxlen=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('fob') t.validate('fob')
def test_validate_maxlen_ok(self): def test_validate_maxlen_ok(self):
@ -258,9 +258,9 @@ class StringTests(unittest.TestCase):
def test_validate_range_bad(self): def test_validate_range_bad(self):
"""Test validate with both min/maxlen and a bad string.""" """Test validate with both min/maxlen and a bad string."""
t = configtypes.String(minlen=2, maxlen=3) t = configtypes.String(minlen=2, maxlen=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('f') t.validate('f')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('fooo') t.validate('fooo')
def test_transform(self): def test_transform(self):
@ -286,7 +286,7 @@ class ListTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -296,13 +296,13 @@ class ListTests(unittest.TestCase):
def test_validate_empty_item(self): def test_validate_empty_item(self):
"""Test validate with empty item and none_ok = False.""" """Test validate with empty item and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('foo,,bar') self.t.validate('foo,,bar')
def test_validate_empty_item_none_ok(self): def test_validate_empty_item_none_ok(self):
"""Test validate with empty item and none_ok = True.""" """Test validate with empty item and none_ok = True."""
t = configtypes.List(none_ok=True) t = configtypes.List(none_ok=True)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('foo,,bar') t.validate('foo,,bar')
def test_transform_single(self): def test_transform_single(self):
@ -353,13 +353,13 @@ class BoolTests(unittest.TestCase):
"""Test validate with invalid values.""" """Test validate with invalid values."""
for val in self.INVALID: for val in self.INVALID:
with self.subTest(val=val): with self.subTest(val=val):
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate(val) self.t.validate(val)
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
t = configtypes.Bool() t = configtypes.Bool()
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('') t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -385,13 +385,13 @@ class IntTests(unittest.TestCase):
def test_validate_string(self): def test_validate_string(self):
"""Test validate with something which isn't an int.""" """Test validate with something which isn't an int."""
t = configtypes.Int() t = configtypes.Int()
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('foobar') t.validate('foobar')
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
t = configtypes.Int() t = configtypes.Int()
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('') t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -402,7 +402,7 @@ class IntTests(unittest.TestCase):
def test_validate_minval_toosmall(self): def test_validate_minval_toosmall(self):
"""Test validate with a minval and a too small int.""" """Test validate with a minval and a too small int."""
t = configtypes.Int(minval=2) t = configtypes.Int(minval=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1') t.validate('1')
def test_validate_minval_ok(self): def test_validate_minval_ok(self):
@ -413,7 +413,7 @@ class IntTests(unittest.TestCase):
def test_validate_maxval_toolarge(self): def test_validate_maxval_toolarge(self):
"""Test validate with a maxval and a too big int.""" """Test validate with a maxval and a too big int."""
t = configtypes.Int(maxval=2) t = configtypes.Int(maxval=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('3') t.validate('3')
def test_validate_maxval_ok(self): def test_validate_maxval_ok(self):
@ -430,9 +430,9 @@ class IntTests(unittest.TestCase):
def test_validate_range_bad(self): def test_validate_range_bad(self):
"""Test validate with both min/maxval and a bad int.""" """Test validate with both min/maxval and a bad int."""
t = configtypes.Int(minval=2, maxval=3) t = configtypes.Int(minval=2, maxval=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1') t.validate('1')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('4') t.validate('4')
def test_transform_none(self): def test_transform_none(self):
@ -459,7 +459,7 @@ class IntListTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty value.""" """Test validate with an empty value."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('23,,42') self.t.validate('23,,42')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -469,7 +469,7 @@ class IntListTests(unittest.TestCase):
def test_validate_bad(self): def test_validate_bad(self):
"""Test validate with bad values.""" """Test validate with bad values."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('23,foo,1337') self.t.validate('23,foo,1337')
def test_transform_single(self): def test_transform_single(self):
@ -508,13 +508,13 @@ class FloatTests(unittest.TestCase):
def test_validate_string(self): def test_validate_string(self):
"""Test validate with something which isn't an float.""" """Test validate with something which isn't an float."""
t = configtypes.Float() t = configtypes.Float()
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('foobar') t.validate('foobar')
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
t = configtypes.Float() t = configtypes.Float()
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('') t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -525,7 +525,7 @@ class FloatTests(unittest.TestCase):
def test_validate_minval_toosmall(self): def test_validate_minval_toosmall(self):
"""Test validate with a minval and a too small float.""" """Test validate with a minval and a too small float."""
t = configtypes.Float(minval=2) t = configtypes.Float(minval=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1.99') t.validate('1.99')
def test_validate_minval_ok(self): def test_validate_minval_ok(self):
@ -536,7 +536,7 @@ class FloatTests(unittest.TestCase):
def test_validate_maxval_toolarge(self): def test_validate_maxval_toolarge(self):
"""Test validate with a maxval and a too big float.""" """Test validate with a maxval and a too big float."""
t = configtypes.Float(maxval=2) t = configtypes.Float(maxval=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('2.01') t.validate('2.01')
def test_validate_maxval_ok(self): def test_validate_maxval_ok(self):
@ -553,9 +553,9 @@ class FloatTests(unittest.TestCase):
def test_validate_range_bad(self): def test_validate_range_bad(self):
"""Test validate with both min/maxval and a bad float.""" """Test validate with both min/maxval and a bad float."""
t = configtypes.Float(minval=2, maxval=3) t = configtypes.Float(minval=2, maxval=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1.99') t.validate('1.99')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('3.01') t.validate('3.01')
def test_transform_empty(self): def test_transform_empty(self):
@ -588,12 +588,12 @@ class PercTests(unittest.TestCase):
def test_validate_int(self): def test_validate_int(self):
"""Test validate with a normal int (not a percentage).""" """Test validate with a normal int (not a percentage)."""
with self.assertRaises(ValueError): with self.assertRaises(configexc.ValidationError):
self.t.validate('1337') self.t.validate('1337')
def test_validate_string(self): def test_validate_string(self):
"""Test validate with something which isn't a percentage.""" """Test validate with something which isn't a percentage."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('1337%%') self.t.validate('1337%%')
def test_validate_perc(self): def test_validate_perc(self):
@ -602,7 +602,7 @@ class PercTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -613,7 +613,7 @@ class PercTests(unittest.TestCase):
def test_validate_minval_toosmall(self): def test_validate_minval_toosmall(self):
"""Test validate with a minval and a too small percentage.""" """Test validate with a minval and a too small percentage."""
t = configtypes.Perc(minval=2) t = configtypes.Perc(minval=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1%') t.validate('1%')
def test_validate_minval_ok(self): def test_validate_minval_ok(self):
@ -624,7 +624,7 @@ class PercTests(unittest.TestCase):
def test_validate_maxval_toolarge(self): def test_validate_maxval_toolarge(self):
"""Test validate with a maxval and a too big percentage.""" """Test validate with a maxval and a too big percentage."""
t = configtypes.Perc(maxval=2) t = configtypes.Perc(maxval=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('3%') t.validate('3%')
def test_validate_maxval_ok(self): def test_validate_maxval_ok(self):
@ -641,9 +641,9 @@ class PercTests(unittest.TestCase):
def test_validate_range_bad(self): def test_validate_range_bad(self):
"""Test validate with both min/maxval and a bad percentage.""" """Test validate with both min/maxval and a bad percentage."""
t = configtypes.Perc(minval=2, maxval=3) t = configtypes.Perc(minval=2, maxval=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1%') t.validate('1%')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('4%') t.validate('4%')
def test_transform_empty(self): def test_transform_empty(self):
@ -673,13 +673,13 @@ class PercListTests(unittest.TestCase):
def test_validate_bad(self): def test_validate_bad(self):
"""Test validate with bad values.""" """Test validate with bad values."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('23%,42%%,1337%') self.t.validate('23%,42%%,1337%')
def test_validate_minval_toosmall(self): def test_validate_minval_toosmall(self):
"""Test validate with a minval and a too small percentage.""" """Test validate with a minval and a too small percentage."""
t = configtypes.PercList(minval=2) t = configtypes.PercList(minval=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1%') t.validate('1%')
def test_validate_minval_ok(self): def test_validate_minval_ok(self):
@ -690,7 +690,7 @@ class PercListTests(unittest.TestCase):
def test_validate_maxval_toolarge(self): def test_validate_maxval_toolarge(self):
"""Test validate with a maxval and a too big percentage.""" """Test validate with a maxval and a too big percentage."""
t = configtypes.PercList(maxval=2) t = configtypes.PercList(maxval=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('3%') t.validate('3%')
def test_validate_maxval_ok(self): def test_validate_maxval_ok(self):
@ -707,14 +707,14 @@ class PercListTests(unittest.TestCase):
def test_validate_range_bad(self): def test_validate_range_bad(self):
"""Test validate with both min/maxval and a bad percentage.""" """Test validate with both min/maxval and a bad percentage."""
t = configtypes.PercList(minval=2, maxval=3) t = configtypes.PercList(minval=2, maxval=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1%') t.validate('1%')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('4%') t.validate('4%')
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty value.""" """Test validate with an empty value."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('23%,,42%') self.t.validate('23%,,42%')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -754,7 +754,7 @@ class PercOrIntTests(unittest.TestCase):
def test_validate_string(self): def test_validate_string(self):
"""Test validate with something which isn't a percentage.""" """Test validate with something which isn't a percentage."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('1337%%') self.t.validate('1337%%')
def test_validate_perc(self): def test_validate_perc(self):
@ -767,7 +767,7 @@ class PercOrIntTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -778,7 +778,7 @@ class PercOrIntTests(unittest.TestCase):
def test_validate_minint_toosmall(self): def test_validate_minint_toosmall(self):
"""Test validate with a minint and a too small int.""" """Test validate with a minint and a too small int."""
t = configtypes.PercOrInt(minint=2) t = configtypes.PercOrInt(minint=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1') t.validate('1')
def test_validate_minint_ok(self): def test_validate_minint_ok(self):
@ -789,7 +789,7 @@ class PercOrIntTests(unittest.TestCase):
def test_validate_maxint_toolarge(self): def test_validate_maxint_toolarge(self):
"""Test validate with a maxint and a too big int.""" """Test validate with a maxint and a too big int."""
t = configtypes.PercOrInt(maxint=2) t = configtypes.PercOrInt(maxint=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('3') t.validate('3')
def test_validate_maxint_ok(self): def test_validate_maxint_ok(self):
@ -806,15 +806,15 @@ class PercOrIntTests(unittest.TestCase):
def test_validate_int_range_bad(self): def test_validate_int_range_bad(self):
"""Test validate with both min/maxint and a bad int.""" """Test validate with both min/maxint and a bad int."""
t = configtypes.PercOrInt(minint=2, maxint=3) t = configtypes.PercOrInt(minint=2, maxint=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1') t.validate('1')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('4') t.validate('4')
def test_validate_minperc_toosmall(self): def test_validate_minperc_toosmall(self):
"""Test validate with a minperc and a too small perc.""" """Test validate with a minperc and a too small perc."""
t = configtypes.PercOrInt(minperc=2) t = configtypes.PercOrInt(minperc=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1%') t.validate('1%')
def test_validate_minperc_ok(self): def test_validate_minperc_ok(self):
@ -825,7 +825,7 @@ class PercOrIntTests(unittest.TestCase):
def test_validate_maxperc_toolarge(self): def test_validate_maxperc_toolarge(self):
"""Test validate with a maxperc and a too big perc.""" """Test validate with a maxperc and a too big perc."""
t = configtypes.PercOrInt(maxperc=2) t = configtypes.PercOrInt(maxperc=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('3%') t.validate('3%')
def test_validate_maxperc_ok(self): def test_validate_maxperc_ok(self):
@ -842,9 +842,9 @@ class PercOrIntTests(unittest.TestCase):
def test_validate_perc_range_bad(self): def test_validate_perc_range_bad(self):
"""Test validate with both min/maxperc and a bad perc.""" """Test validate with both min/maxperc and a bad perc."""
t = configtypes.PercOrInt(minperc=2, maxperc=3) t = configtypes.PercOrInt(minperc=2, maxperc=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1%') t.validate('1%')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('4%') t.validate('4%')
def test_validate_both_range_int(self): def test_validate_both_range_int(self):
@ -890,7 +890,7 @@ class CommandTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty string.""" """Test validate with an empty string."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -910,12 +910,12 @@ class CommandTests(unittest.TestCase):
def test_validate_invalid_command(self): def test_validate_invalid_command(self):
"""Test validate with an invalid command.""" """Test validate with an invalid command."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('cmd3') self.t.validate('cmd3')
def test_validate_invalid_command_args(self): def test_validate_invalid_command_args(self):
"""Test validate with an invalid command and arguments.""" """Test validate with an invalid command and arguments."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('cmd3 foo bar') self.t.validate('cmd3 foo bar')
def test_transform(self): def test_transform(self):
@ -953,7 +953,7 @@ class ColorSystemTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty string.""" """Test validate with an empty string."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -971,7 +971,7 @@ class ColorSystemTests(unittest.TestCase):
"""Test validate with invalid values.""" """Test validate with invalid values."""
for val in self.INVALID: for val in self.INVALID:
with self.subTest(val=val): with self.subTest(val=val):
with self.assertRaises(configtypes.ValidationError, msg=val): with self.assertRaises(configexc.ValidationError, msg=val):
self.t.validate(val) self.t.validate(val)
def test_transform(self): def test_transform(self):
@ -998,7 +998,7 @@ class QtColorTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty string.""" """Test validate with an empty string."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1016,7 +1016,7 @@ class QtColorTests(unittest.TestCase):
"""Test validate with invalid values.""" """Test validate with invalid values."""
for val in self.INVALID + self.INVALID_QT: for val in self.INVALID + self.INVALID_QT:
with self.subTest(val=val): with self.subTest(val=val):
with self.assertRaises(configtypes.ValidationError, msg=val): with self.assertRaises(configexc.ValidationError, msg=val):
self.t.validate(val) self.t.validate(val)
def test_transform(self): def test_transform(self):
@ -1135,7 +1135,7 @@ class FontTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty string.""" """Test validate with an empty string."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1162,11 +1162,11 @@ class FontTests(unittest.TestCase):
for val in self.INVALID: for val in self.INVALID:
with self.subTest(val=val): with self.subTest(val=val):
with self.subTest(t="t1"): with self.subTest(t="t1"):
with self.assertRaises(configtypes.ValidationError, with self.assertRaises(configexc.ValidationError,
msg=val): msg=val):
self.t.validate(val) self.t.validate(val)
with self.subTest(t="t2"): with self.subTest(t="t2"):
with self.assertRaises(configtypes.ValidationError, with self.assertRaises(configexc.ValidationError,
msg=val): msg=val):
self.t2.validate(val) self.t2.validate(val)
@ -1208,7 +1208,7 @@ class RegexTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty string.""" """Test validate with an empty string."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1222,7 +1222,7 @@ class RegexTests(unittest.TestCase):
def test_validate_invalid(self): def test_validate_invalid(self):
"""Test validate with an invalid regex.""" """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') self.t.validate(r'(foo|bar))?baz[fis]h')
def test_transform_empty(self): def test_transform_empty(self):
@ -1247,7 +1247,7 @@ class RegexListTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty value.""" """Test validate with an empty value."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate(r'(foo|bar),,1337{42}') self.t.validate(r'(foo|bar),,1337{42}')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1257,7 +1257,7 @@ class RegexListTests(unittest.TestCase):
def test_validate_bad(self): def test_validate_bad(self):
"""Test validate with bad values.""" """Test validate with bad values."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate(r'(foo|bar),((),1337{42}') self.t.validate(r'(foo|bar),((),1337{42}')
def test_transform_single(self): def test_transform_single(self):
@ -1286,7 +1286,7 @@ class FileTests(unittest.TestCase):
def test_validate_empty(self, _os_path): def test_validate_empty(self, _os_path):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate("") self.t.validate("")
def test_validate_empty_none_ok(self, _os_path): 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.""" """Test validate with a file which does not exist."""
os_path.expanduser.side_effect = lambda x: x os_path.expanduser.side_effect = lambda x: x
os_path.isfile.return_value = False os_path.isfile.return_value = False
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('foobar') self.t.validate('foobar')
def test_validate_exists_abs(self, os_path): 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.expanduser.side_effect = lambda x: x
os_path.isfile.return_value = True os_path.isfile.return_value = True
os_path.isabs.return_value = False os_path.isabs.return_value = False
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('foobar') self.t.validate('foobar')
def test_validate_expanduser(self, os_path): def test_validate_expanduser(self, os_path):
@ -1345,7 +1345,7 @@ class DirectoryTests(unittest.TestCase):
def test_validate_empty(self, _os_path): def test_validate_empty(self, _os_path):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate("") self.t.validate("")
def test_validate_empty_none_ok(self, _os_path): 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.""" """Test validate with a directory which does not exist."""
os_path.expanduser.side_effect = lambda x: x os_path.expanduser.side_effect = lambda x: x
os_path.isdir.return_value = False os_path.isdir.return_value = False
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('foobar') self.t.validate('foobar')
def test_validate_exists_abs(self, os_path): 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.expanduser.side_effect = lambda x: x
os_path.isdir.return_value = True os_path.isdir.return_value = True
os_path.isabs.return_value = False os_path.isabs.return_value = False
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('foobar') self.t.validate('foobar')
def test_validate_expanduser(self, os_path): def test_validate_expanduser(self, os_path):
@ -1420,18 +1420,18 @@ class WebKitByteTests(unittest.TestCase):
def test_validate_int_negative(self): def test_validate_int_negative(self):
"""Test validate with a negative int.""" """Test validate with a negative int."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('-1') self.t.validate('-1')
def test_validate_int_negative_suffix(self): def test_validate_int_negative_suffix(self):
"""Test validate with a negative int with suffix.""" """Test validate with a negative int with suffix."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('-1k') self.t.validate('-1k')
def test_validate_int_toobig(self): def test_validate_int_toobig(self):
"""Test validate with an int which is too big.""" """Test validate with an int which is too big."""
t = configtypes.WebKitBytes(maxsize=10) t = configtypes.WebKitBytes(maxsize=10)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('11') t.validate('11')
def test_validate_int_not_toobig(self): def test_validate_int_not_toobig(self):
@ -1442,17 +1442,17 @@ class WebKitByteTests(unittest.TestCase):
def test_validate_int_toobig_suffix(self): def test_validate_int_toobig_suffix(self):
"""Test validate with an int which is too big with suffix.""" """Test validate with an int which is too big with suffix."""
t = configtypes.WebKitBytes(maxsize=10) t = configtypes.WebKitBytes(maxsize=10)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1k') t.validate('1k')
def test_validate_int_invalid_suffix(self): def test_validate_int_invalid_suffix(self):
"""Test validate with an int with an invalid suffix.""" """Test validate with an int with an invalid suffix."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('56x') self.t.validate('56x')
def test_validate_int_double_suffix(self): def test_validate_int_double_suffix(self):
"""Test validate with an int with a double suffix.""" """Test validate with an int with a double suffix."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('56kk') self.t.validate('56kk')
def test_transform_empty(self): def test_transform_empty(self):
@ -1483,15 +1483,15 @@ class WebKitBytesListTests(unittest.TestCase):
def test_validate_bad(self): def test_validate_bad(self):
"""Test validate with bad values.""" """Test validate with bad values."""
t = configtypes.WebKitBytesList() t = configtypes.WebKitBytesList()
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('23,56kk,1337') t.validate('23,56kk,1337')
def test_validate_maxsize_toolarge(self): def test_validate_maxsize_toolarge(self):
"""Test validate with a maxsize and a too big size.""" """Test validate with a maxsize and a too big size."""
t = configtypes.WebKitBytesList(maxsize=2) t = configtypes.WebKitBytesList(maxsize=2)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('3') t.validate('3')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('3k') t.validate('3k')
def test_validate_maxsize_ok(self): def test_validate_maxsize_ok(self):
@ -1501,7 +1501,7 @@ class WebKitBytesListTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with an empty value.""" """Test validate with an empty value."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('23,,42') self.t.validate('23,,42')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1512,7 +1512,7 @@ class WebKitBytesListTests(unittest.TestCase):
def test_validate_len_tooshort(self): def test_validate_len_tooshort(self):
"""Test validate with a too short length.""" """Test validate with a too short length."""
t = configtypes.WebKitBytesList(length=3) t = configtypes.WebKitBytesList(length=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1,2') t.validate('1,2')
def test_validate_len_ok(self): def test_validate_len_ok(self):
@ -1523,7 +1523,7 @@ class WebKitBytesListTests(unittest.TestCase):
def test_validate_len_toolong(self): def test_validate_len_toolong(self):
"""Test validate with a too long length.""" """Test validate with a too long length."""
t = configtypes.WebKitBytesList(length=3) t = configtypes.WebKitBytesList(length=3)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('1,2,3,4') t.validate('1,2,3,4')
def test_transform_single(self): def test_transform_single(self):
@ -1548,7 +1548,7 @@ class ShellCommandTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate("") self.t.validate("")
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1568,7 +1568,7 @@ class ShellCommandTests(unittest.TestCase):
def test_validate_placeholder_invalid(self): def test_validate_placeholder_invalid(self):
"""Test validate with an invalid placeholder.""" """Test validate with an invalid placeholder."""
t = configtypes.ShellCommand(placeholder='{}') t = configtypes.ShellCommand(placeholder='{}')
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('foo{} bar') t.validate('foo{} bar')
def test_transform_single(self): def test_transform_single(self):
@ -1598,7 +1598,7 @@ class ProxyTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1616,12 +1616,12 @@ class ProxyTests(unittest.TestCase):
def test_validate_invalid(self): def test_validate_invalid(self):
"""Test validate with an invalid URL.""" """Test validate with an invalid URL."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate(':') self.t.validate(':')
def test_validate_scheme(self): def test_validate_scheme(self):
"""Test validate with a URL with wrong scheme.""" """Test validate with a URL with wrong scheme."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('ftp://example.com/') self.t.validate('ftp://example.com/')
def test_validate_http(self): def test_validate_http(self):
@ -1707,7 +1707,7 @@ class SearchEngineNameTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1733,7 +1733,7 @@ class SearchEngineUrlTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1743,7 +1743,7 @@ class SearchEngineUrlTests(unittest.TestCase):
def test_validate_no_placeholder(self): def test_validate_no_placeholder(self):
"""Test validate with no placeholder.""" """Test validate with no placeholder."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('foo') self.t.validate('foo')
def test_validate(self): def test_validate(self):
@ -1752,7 +1752,7 @@ class SearchEngineUrlTests(unittest.TestCase):
def test_validate_invalid_url(self): def test_validate_invalid_url(self):
"""Test validate with an invalud URL.""" """Test validate with an invalud URL."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate(':{}') self.t.validate(':{}')
def test_transform_empty(self): def test_transform_empty(self):
@ -1803,7 +1803,7 @@ class AutoSearchTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1822,7 +1822,7 @@ class AutoSearchTests(unittest.TestCase):
"""Test validate with invalid values.""" """Test validate with invalid values."""
for val in self.INVALID: for val in self.INVALID:
with self.subTest(val=val): with self.subTest(val=val):
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate(val) self.t.validate(val)
def test_transform(self): def test_transform(self):
@ -1853,7 +1853,7 @@ class IgnoreCaseTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1872,7 +1872,7 @@ class IgnoreCaseTests(unittest.TestCase):
"""Test validate with invalid values.""" """Test validate with invalid values."""
for val in self.INVALID: for val in self.INVALID:
with self.subTest(val=val): with self.subTest(val=val):
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate(val) self.t.validate(val)
def test_transform(self): def test_transform(self):
@ -1896,7 +1896,7 @@ class EncodingTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1912,7 +1912,7 @@ class EncodingTests(unittest.TestCase):
def test_validate_invalid(self): def test_validate_invalid(self):
"""Test validate with an invalid value.""" """Test validate with an invalid value."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('blubber') self.t.validate('blubber')
def test_transform(self): def test_transform(self):
@ -1941,7 +1941,7 @@ class UrlListTests(unittest.TestCase):
def test_validate_empty(self): def test_validate_empty(self):
"""Test validate with empty string and none_ok = False.""" """Test validate with empty string and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('') self.t.validate('')
def test_validate_empty_none_ok(self): def test_validate_empty_none_ok(self):
@ -1951,13 +1951,13 @@ class UrlListTests(unittest.TestCase):
def test_validate_empty_item(self): def test_validate_empty_item(self):
"""Test validate with empty item and none_ok = False.""" """Test validate with empty item and none_ok = False."""
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
self.t.validate('foo,,bar') self.t.validate('foo,,bar')
def test_validate_empty_item_none_ok(self): def test_validate_empty_item_none_ok(self):
"""Test validate with empty item and none_ok = True.""" """Test validate with empty item and none_ok = True."""
t = configtypes.UrlList(none_ok=True) t = configtypes.UrlList(none_ok=True)
with self.assertRaises(configtypes.ValidationError): with self.assertRaises(configexc.ValidationError):
t.validate('foo,,bar') t.validate('foo,,bar')
def test_transform_single(self): def test_transform_single(self):

View File

@ -26,6 +26,8 @@ from unittest import mock
from PyQt5.QtCore import QPoint, QProcess from PyQt5.QtCore import QPoint, QProcess
from PyQt5.QtNetwork import QNetworkRequest from PyQt5.QtNetwork import QNetworkRequest
from qutebrowser.config import configexc
class ConfigStub: class ConfigStub:
@ -35,12 +37,6 @@ class ConfigStub:
data: The config data to return. data: The config data to return.
""" """
class NoOptionError(Exception):
"""NoOptionError exception."""
pass
def __init__(self, data): def __init__(self, data):
self.data = data self.data = data
@ -61,7 +57,7 @@ class ConfigStub:
try: try:
return data[opt] return data[opt]
except KeyError: except KeyError:
raise self.NoOptionError('{} -> {}'.format(sect, opt)) raise configexc.NoOptionError(opt, sect)
class FakeKeyEvent: class FakeKeyEvent:

View File

@ -28,7 +28,7 @@ import urllib.parse
from PyQt5.QtCore import QUrl from PyQt5.QtCore import QUrl
from PyQt5.QtNetwork import QHostInfo 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.utils import log, qtutils, message, utils
from qutebrowser.commands import cmdexc from qutebrowser.commands import cmdexc
@ -53,7 +53,7 @@ def _get_search_url(txt):
engine = m.group(1) engine = m.group(1)
try: try:
template = config.get('searchengines', engine) template = config.get('searchengines', engine)
except config.NoOptionError: except configexc.NoOptionError:
template = config.get('searchengines', 'DEFAULT') template = config.get('searchengines', 'DEFAULT')
term = txt term = txt
else: else: