From ff6d3e05a6250ee1557a6f0187ac662bbdc91d2d Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Sat, 7 Nov 2015 16:14:52 +0100 Subject: [PATCH 01/15] log-javascript-console now String option: none, debug, info Make BaseType.valid_values per-instance variable --- qutebrowser/browser/webpage.py | 12 +- qutebrowser/config/config.py | 4 +- qutebrowser/config/configdata.py | 9 +- qutebrowser/config/configtypes.py | 206 ++++++++++++++++++------------ 4 files changed, 145 insertions(+), 86 deletions(-) diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index 16460eaad..32e56d798 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -503,8 +503,16 @@ class BrowserPage(QWebPage): def javaScriptConsoleMessage(self, msg, line, source): """Override javaScriptConsoleMessage to use debug log.""" - if config.get('general', 'log-javascript-console'): - log.js.debug("[{}:{}] {}".format(source, line, msg)) + + log_javascript_console = config.get('general', + 'log-javascript-console' ) + logstring = "[{}:{}] {}".format(source, line, msg) + logmap = { + 'debug': log.js.debug, + 'info': log.js.info, + 'none': lambda arg: None + } + logmap[log_javascript_console](logstring) def chooseFile(self, _frame, suggested_file): """Override QWebPage's chooseFile to be able to chose a file to upload. diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index aea69494b..88ca89e5d 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -356,7 +356,9 @@ class ConfigManager(QObject): ('tabs', 'position'): _transform_position, ('ui', 'downloads-position'): _transform_position, ('ui', 'remove-finished-downloads'): - _get_value_transformer({'false': '-1', 'true': '1000'}) + _get_value_transformer({'false': '-1', 'true': '1000'}), + ('general', 'log-javascript-console'): + _get_value_transformer({'false': 'none', 'true': 'debug'}), } changed = pyqtSignal(str, str) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 7a89b042a..d5083c8f6 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -214,8 +214,13 @@ def data(readonly=False): "launched."), ('log-javascript-console', - SettingValue(typ.Bool(), 'false'), - "Whether to log javascript console messages."), + SettingValue( + typ.String( + valid_values=typ.ValidValues('none', 'debug', 'info')), + 'debug'), + "How to log javascript console messages. " + "None suppresses output, debug logs to stdout if in debug mode, " + "info always logs to stdout."), ('save-session', SettingValue(typ.Bool(), 'false'), diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 4c6a3b4c8..b287c5fb8 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -121,11 +121,11 @@ class BaseType: mentioned in the config file. """ - valid_values = None special = False - def __init__(self, none_ok=False): + def __init__(self, none_ok=False, valid_values=None): self.none_ok = none_ok + self.valid_values = valid_values def _basic_validation(self, value): """Do some basic validation for the value (empty, non-printable chars). @@ -243,8 +243,8 @@ class String(BaseType): """ def __init__(self, minlen=None, maxlen=None, forbidden=None, - none_ok=False, completions=None): - super().__init__(none_ok) + none_ok=False, completions=None, valid_values=None): + super().__init__(none_ok, valid_values) if minlen is not None and minlen < 1: raise ValueError("minlen ({}) needs to be >= 1!".format(minlen)) elif maxlen is not None and maxlen < 1: @@ -650,10 +650,13 @@ class ColorSystem(MappingType): """Color systems for interpolation.""" special = True - valid_values = ValidValues(('rgb', "Interpolate in the RGB color system."), - ('hsv', "Interpolate in the HSV color system."), - ('hsl', "Interpolate in the HSL color system."), - ('none', "Don't show a gradient.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('rgb', "Interpolate in the RGB color system."), + ('hsv', "Interpolate in the HSV color system."), + ('hsl', "Interpolate in the HSL color system."), + ('none', "Don't show a gradient.")) MAPPING = { 'rgb': QColor.Rgb, @@ -1092,9 +1095,12 @@ class HintMode(BaseType): """Base class for the hints -> mode setting.""" special = True - valid_values = ValidValues(('number', "Use numeric hints."), - ('letter', "Use the chars in the hints -> " - "chars setting.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('number', "Use numeric hints."), + ('letter', "Use the chars in the hints -> " + "chars setting.")) class Proxy(BaseType): @@ -1102,8 +1108,11 @@ class Proxy(BaseType): """A proxy URL or special value.""" special = True - valid_values = ValidValues(('system', "Use the system wide proxy."), - ('none', "Don't use any proxy")) + + def __init__(self): + self.valid_values = \ + ValidValues(('system', "Use the system wide proxy."), + ('none', "Don't use any proxy")) PROXY_TYPES = { 'http': QNetworkProxy.HttpProxy, @@ -1330,7 +1339,8 @@ class Position(MappingType): """The position of the tab bar.""" - valid_values = ValidValues('top', 'bottom', 'left', 'right') + def __init__(self): + self.valid_values = ValidValues('top', 'bottom', 'left', 'right') MAPPING = { 'top': QTabWidget.North, @@ -1344,7 +1354,8 @@ class VerticalPosition(BaseType): """The position of the download bar.""" - valid_values = ValidValues('top', 'bottom') + def __init__(self): + self.valid_values = ValidValues('top', 'bottom') class UrlList(List): @@ -1389,10 +1400,11 @@ class SelectOnRemove(MappingType): """Which tab to select when the focused tab is removed.""" special = True - valid_values = ValidValues( - ('left', "Select the tab on the left."), - ('right', "Select the tab on the right."), - ('previous', "Select the previously selected tab.")) + def __init__(self): + self.valid_values = ValidValues( + ('left', "Select the tab on the left."), + ('right', "Select the tab on the right."), + ('previous', "Select the previously selected tab.")) MAPPING = { 'left': QTabBar.SelectLeftTab, @@ -1406,11 +1418,14 @@ class LastClose(BaseType): """Behavior when the last tab is closed.""" special = True - valid_values = ValidValues(('ignore', "Don't do anything."), - ('blank', "Load a blank page."), - ('startpage', "Load the start page."), - ('default-page', "Load the default page."), - ('close', "Close the window.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('ignore', "Don't do anything."), + ('blank', "Load a blank page."), + ('startpage', "Load the start page."), + ('default-page', "Load the default page."), + ('close', "Close the window.")) class AcceptCookies(BaseType): @@ -1418,13 +1433,16 @@ class AcceptCookies(BaseType): """Control which cookies to accept.""" special = True - valid_values = ValidValues(('all', "Accept all cookies."), - ('no-3rdparty', "Accept cookies from the same" - " origin only."), - ('no-unknown-3rdparty', "Accept cookies from " - "the same origin only, unless a cookie is " - "already set for the domain."), - ('never', "Don't accept cookies at all.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('all', "Accept all cookies."), + ('no-3rdparty', "Accept cookies from the same" + " origin only."), + ('no-unknown-3rdparty', "Accept cookies from " + "the same origin only, unless a cookie is " + "already set for the domain."), + ('never', "Don't accept cookies at all.")) class ConfirmQuit(FlagList): @@ -1432,12 +1450,14 @@ class ConfirmQuit(FlagList): """Whether to display a confirmation when the window is closed.""" special = True - valid_values = ValidValues(('always', "Always show a confirmation."), - ('multiple-tabs', "Show a confirmation if " - "multiple tabs are opened."), - ('downloads', "Show a confirmation if " - "downloads are running"), - ('never', "Never show a confirmation.")) + + def __init__(self): + self.valid_values = ValidValues(('always', "Always show a confirmation."), + ('multiple-tabs', "Show a confirmation if " + "multiple tabs are opened."), + ('downloads', "Show a confirmation if " + "downloads are running"), + ('never', "Never show a confirmation.")) # Values that can be combined with commas combinable_values = ('multiple-tabs', 'downloads') @@ -1462,10 +1482,13 @@ class ForwardUnboundKeys(BaseType): """Whether to forward unbound keys.""" special = True - valid_values = ValidValues(('all', "Forward all unbound keys."), - ('auto', "Forward unbound non-alphanumeric " - "keys."), - ('none', "Don't forward any keys.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('all', "Forward all unbound keys."), + ('auto', "Forward unbound non-alphanumeric " + "keys."), + ('none', "Don't forward any keys.")) class CloseButton(BaseType): @@ -1473,9 +1496,12 @@ class CloseButton(BaseType): """Mouse button used to close tabs.""" special = True - valid_values = ValidValues(('right', "Close tabs on right-click."), - ('middle', "Close tabs on middle-click."), - ('none', "Don't close tabs using the mouse.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('right', "Close tabs on right-click."), + ('middle', "Close tabs on middle-click."), + ('none', "Don't close tabs using the mouse.")) class NewTabPosition(BaseType): @@ -1483,10 +1509,13 @@ class NewTabPosition(BaseType): """How new tabs are positioned.""" special = True - valid_values = ValidValues(('left', "On the left of the current tab."), - ('right', "On the right of the current tab."), - ('first', "At the left end."), - ('last', "At the right end.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('left', "On the left of the current tab."), + ('right', "On the right of the current tab."), + ('first', "At the left end."), + ('last', "At the right end.")) class IgnoreCase(Bool): @@ -1494,10 +1523,13 @@ class IgnoreCase(Bool): """Whether to ignore case when searching.""" special = True - valid_values = ValidValues(('true', "Search case-insensitively"), - ('false', "Search case-sensitively"), - ('smart', "Search case-sensitively if there " - "are capital chars")) + + def __init__(self): + self.valid_values = \ + ValidValues(('true', "Search case-insensitively"), + ('false', "Search case-sensitively"), + ('smart', "Search case-sensitively if there " + "are capital chars")) def transform(self, value): if value.lower() == 'smart': @@ -1520,19 +1552,22 @@ class NewInstanceOpenTarget(BaseType): """How to open links in an existing instance if a new one is launched.""" special = True - valid_values = ValidValues(('tab', "Open a new tab in the existing " - "window and activate the window."), - ('tab-bg', "Open a new background tab in the " - "existing window and activate the " - "window."), - ('tab-silent', "Open a new tab in the existing " - "window without activating " - "the window."), - ('tab-bg-silent', "Open a new background tab " - "in the existing window " - "without activating the " - "window."), - ('window', "Open in a new window.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('tab', "Open a new tab in the existing " + "window and activate the window."), + ('tab-bg', "Open a new background tab in the " + "existing window and activate the " + "window."), + ('tab-silent', "Open a new tab in the existing " + "window without activating " + "the window."), + ('tab-bg-silent', "Open a new background tab " + "in the existing window " + "without activating the " + "window."), + ('window', "Open in a new window.")) class DownloadPathSuggestion(BaseType): @@ -1540,21 +1575,26 @@ class DownloadPathSuggestion(BaseType): """How to format the question when downloading.""" special = True - valid_values = ValidValues(('path', "Show only the download path."), - ('filename', "Show only download filename."), - ('both', "Show download path and filename.")) + + def __init__(self): + self.valid_values = \ + ValidValues(('path', "Show only the download path."), + ('filename', "Show only download filename."), + ('both', "Show download path and filename.")) class Referer(BaseType): """Send the Referer header.""" - valid_values = ValidValues(('always', "Always send."), - ('never', "Never send; this is not recommended," - " as some sites may break."), - ('same-domain', "Only send for the same domain." - " This will still protect your privacy, but" - " shouldn't break any sites.")) + def __init__(self): + self.valid_values = \ + ValidValues(('always', "Always send."), + ('never', "Never send; this is not recommended," + " as some sites may break."), + ('same-domain', "Only send for the same domain." + " This will still protect your privacy, but" + " shouldn't break any sites.")) class UserAgent(BaseType): @@ -1624,19 +1664,23 @@ class TabBarShow(BaseType): """When to show the tab bar.""" - valid_values = ValidValues(('always', "Always show the tab bar."), - ('never', "Always hide the tab bar."), - ('multiple', "Hide the tab bar if only one tab " - "is open."), - ('switching', "Show the tab bar when switching " - "tabs.")) + def __init__(self): + self.valid_values = \ + ValidValues(('always', "Always show the tab bar."), + ('never', "Always hide the tab bar."), + ('multiple', "Hide the tab bar if only one tab " + "is open."), + ('switching', "Show the tab bar when switching " + "tabs.")) class URLSegmentList(FlagList): """A list of URL segments.""" - valid_values = ValidValues('host', 'path', 'query', 'anchor') + def __init__(self, none_ok=False): + super().__init__(none_ok) + self.valid_values = ValidValues('host', 'path', 'query', 'anchor') class TimestampTemplate(BaseType): From 75f9f2af8d444817891ccccd5b1d0834c31497bc Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Sun, 8 Nov 2015 09:36:06 +0100 Subject: [PATCH 02/15] get rid of redundant option description --- qutebrowser/config/configdata.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index d5083c8f6..57dca84a9 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -216,11 +216,12 @@ def data(readonly=False): ('log-javascript-console', SettingValue( typ.String( - valid_values=typ.ValidValues('none', 'debug', 'info')), + valid_values=typ.ValidValues( + ('none', 'Not displayed'), + ('debug', 'Display in debug mode'), + ('info', 'Display always'))), 'debug'), - "How to log javascript console messages. " - "None suppresses output, debug logs to stdout if in debug mode, " - "info always logs to stdout."), + "How to log javascript console messages."), ('save-session', SettingValue(typ.Bool(), 'false'), From 2a705e2eb62d5f2e8052f036c8b520203b51f537 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Mon, 9 Nov 2015 09:12:13 +0100 Subject: [PATCH 03/15] Make non-specialized config types String. Closes #1103 --- qutebrowser/config/configdata.py | 99 +++++++++++++--- qutebrowser/config/configtypes.py | 181 +++--------------------------- 2 files changed, 101 insertions(+), 179 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 57dca84a9..a010e9e05 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -209,18 +209,32 @@ def data(readonly=False): "be used."), ('new-instance-open-target', - SettingValue(typ.NewInstanceOpenTarget(), 'tab'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('tab', "Open a new tab in the existing " + "window and activate the window."), + ('tab-bg', "Open a new background tab in the " + "existing window and activate the " + "window."), + ('tab-silent', "Open a new tab in the existing " + "window without activating " + "the window."), + ('tab-bg-silent', "Open a new background tab " + "in the existing window " + "without activating the " + "window."), + ('window', "Open in a new window.") + )), 'tab'), "How to open links in an existing instance if a new one is " "launched."), ('log-javascript-console', - SettingValue( - typ.String( - valid_values=typ.ValidValues( - ('none', 'Not displayed'), - ('debug', 'Display in debug mode'), - ('info', 'Display always'))), - 'debug'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('none', 'Not displayed'), + ('debug', 'Display in debug mode'), + ('info', 'Display always') + )), 'debug'), "How to log javascript console messages."), ('save-session', @@ -351,7 +365,15 @@ def data(readonly=False): "Value to send in the `accept-language` header."), ('referer-header', - SettingValue(typ.Referer(), 'same-domain'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('always', "Always send."), + ('never', "Never send; this is not recommended," + " as some sites may break."), + ('same-domain', "Only send for the same domain." + " This will still protect your privacy, but" + " shouldn't break any sites.") + )), 'same-domain'), "Send the Referer header"), ('user-agent', @@ -385,7 +407,12 @@ def data(readonly=False): "Automatically open completion when typing."), ('download-path-suggestion', - SettingValue(typ.DownloadPathSuggestion(), 'path'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('path', "Show only the download path."), + ('filename', "Show only download filename."), + ('both', "Show download path and filename."))), + 'path'), "What to display in the download filename input."), ('timestamp-format', @@ -458,7 +485,13 @@ def data(readonly=False): "element is focused after page load."), ('forward-unbound-keys', - SettingValue(typ.ForwardUnboundKeys(), 'auto'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('all', "Forward all unbound keys."), + ('auto', "Forward unbound non-alphanumeric " + "keys."), + ('none', "Don't forward any keys.") + )), 'auto'), "Whether to forward unbound keys to the webview in normal mode."), ('spatial-navigation', @@ -508,11 +541,26 @@ def data(readonly=False): "How new tabs opened explicitly are positioned."), ('last-close', - SettingValue(typ.LastClose(), 'ignore'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('ignore', "Don't do anything."), + ('blank', "Load a blank page."), + ('startpage', "Load the start page."), + ('default-page', "Load the default page."), + ('close', "Close the window.") + )), 'ignore'), "Behavior when the last tab is closed."), ('show', - SettingValue(typ.TabBarShow(), 'always'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('always', "Always show the tab bar."), + ('never', "Always hide the tab bar."), + ('multiple', "Hide the tab bar if only one tab " + "is open."), + ('switching', "Show the tab bar when switching " + "tabs.") + )), 'always'), "When to show the tab bar"), ('show-switching-delay', @@ -529,7 +577,12 @@ def data(readonly=False): "Whether tabs should be movable."), ('close-mouse-button', - SettingValue(typ.CloseButton(), 'middle'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('right', "Close tabs on right-click."), + ('middle', "Close tabs on middle-click."), + ('none', "Don't close tabs using the mouse.") + )), 'middle'), "On which mouse button to close tabs."), ('position', @@ -737,7 +790,16 @@ def data(readonly=False): "local urls."), ('cookies-accept', - SettingValue(typ.AcceptCookies(), 'no-3rdparty'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('all', "Accept all cookies."), + ('no-3rdparty', "Accept cookies from the same" + " origin only."), + ('no-unknown-3rdparty', "Accept cookies from " + "the same origin only, unless a cookie is " + "already set for the domain."), + ('never', "Don't accept cookies at all.") + )), 'no-3rdparty'), "Control which cookies to accept."), ('cookies-store', @@ -785,7 +847,12 @@ def data(readonly=False): "Opacity for hints."), ('mode', - SettingValue(typ.HintMode(), 'letter'), + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('number', "Use numeric hints."), + ('letter', "Use the chars in the hints -> " + "chars setting.") + )), 'letter'), "Mode to use for hints."), ('chars', diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index b287c5fb8..1d9ecae3a 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -652,11 +652,11 @@ class ColorSystem(MappingType): special = True def __init__(self): - self.valid_values = \ - ValidValues(('rgb', "Interpolate in the RGB color system."), - ('hsv', "Interpolate in the HSV color system."), - ('hsl', "Interpolate in the HSL color system."), - ('none', "Don't show a gradient.")) + self.valid_values = ValidValues( + ('rgb', "Interpolate in the RGB color system."), + ('hsv', "Interpolate in the HSV color system."), + ('hsl', "Interpolate in the HSL color system."), + ('none', "Don't show a gradient.")) MAPPING = { 'rgb': QColor.Rgb, @@ -1090,19 +1090,6 @@ class ShellCommand(BaseType): return shlex.split(value) -class HintMode(BaseType): - - """Base class for the hints -> mode setting.""" - - special = True - - def __init__(self): - self.valid_values = \ - ValidValues(('number', "Use numeric hints."), - ('letter', "Use the chars in the hints -> " - "chars setting.")) - - class Proxy(BaseType): """A proxy URL or special value.""" @@ -1110,9 +1097,9 @@ class Proxy(BaseType): special = True def __init__(self): - self.valid_values = \ - ValidValues(('system', "Use the system wide proxy."), - ('none', "Don't use any proxy")) + self.valid_values = ValidValues( + ('system', "Use the system wide proxy."), + ('none', "Don't use any proxy")) PROXY_TYPES = { 'http': QNetworkProxy.HttpProxy, @@ -1413,38 +1400,6 @@ class SelectOnRemove(MappingType): } -class LastClose(BaseType): - - """Behavior when the last tab is closed.""" - - special = True - - def __init__(self): - self.valid_values = \ - ValidValues(('ignore', "Don't do anything."), - ('blank', "Load a blank page."), - ('startpage', "Load the start page."), - ('default-page', "Load the default page."), - ('close', "Close the window.")) - - -class AcceptCookies(BaseType): - - """Control which cookies to accept.""" - - special = True - - def __init__(self): - self.valid_values = \ - ValidValues(('all', "Accept all cookies."), - ('no-3rdparty', "Accept cookies from the same" - " origin only."), - ('no-unknown-3rdparty', "Accept cookies from " - "the same origin only, unless a cookie is " - "already set for the domain."), - ('never', "Don't accept cookies at all.")) - - class ConfirmQuit(FlagList): """Whether to display a confirmation when the window is closed.""" @@ -1477,33 +1432,6 @@ class ConfirmQuit(FlagList): value, "List cannot contain always!") -class ForwardUnboundKeys(BaseType): - - """Whether to forward unbound keys.""" - - special = True - - def __init__(self): - self.valid_values = \ - ValidValues(('all', "Forward all unbound keys."), - ('auto', "Forward unbound non-alphanumeric " - "keys."), - ('none', "Don't forward any keys.")) - - -class CloseButton(BaseType): - - """Mouse button used to close tabs.""" - - special = True - - def __init__(self): - self.valid_values = \ - ValidValues(('right', "Close tabs on right-click."), - ('middle', "Close tabs on middle-click."), - ('none', "Don't close tabs using the mouse.")) - - class NewTabPosition(BaseType): """How new tabs are positioned.""" @@ -1511,11 +1439,11 @@ class NewTabPosition(BaseType): special = True def __init__(self): - self.valid_values = \ - ValidValues(('left', "On the left of the current tab."), - ('right', "On the right of the current tab."), - ('first', "At the left end."), - ('last', "At the right end.")) + self.valid_values = ValidValues( + ('left', "On the left of the current tab."), + ('right', "On the right of the current tab."), + ('first', "At the left end."), + ('last', "At the right end.")) class IgnoreCase(Bool): @@ -1525,11 +1453,11 @@ class IgnoreCase(Bool): special = True def __init__(self): - self.valid_values = \ - ValidValues(('true', "Search case-insensitively"), - ('false', "Search case-sensitively"), - ('smart', "Search case-sensitively if there " - "are capital chars")) + self.valid_values = ValidValues( + ('true', "Search case-insensitively"), + ('false', "Search case-sensitively"), + ('smart', "Search case-sensitively if there " + "are capital chars")) def transform(self, value): if value.lower() == 'smart': @@ -1547,56 +1475,6 @@ class IgnoreCase(Bool): super().validate(value) -class NewInstanceOpenTarget(BaseType): - - """How to open links in an existing instance if a new one is launched.""" - - special = True - - def __init__(self): - self.valid_values = \ - ValidValues(('tab', "Open a new tab in the existing " - "window and activate the window."), - ('tab-bg', "Open a new background tab in the " - "existing window and activate the " - "window."), - ('tab-silent', "Open a new tab in the existing " - "window without activating " - "the window."), - ('tab-bg-silent', "Open a new background tab " - "in the existing window " - "without activating the " - "window."), - ('window', "Open in a new window.")) - - -class DownloadPathSuggestion(BaseType): - - """How to format the question when downloading.""" - - special = True - - def __init__(self): - self.valid_values = \ - ValidValues(('path', "Show only the download path."), - ('filename', "Show only download filename."), - ('both', "Show download path and filename.")) - - -class Referer(BaseType): - - """Send the Referer header.""" - - def __init__(self): - self.valid_values = \ - ValidValues(('always', "Always send."), - ('never', "Never send; this is not recommended," - " as some sites may break."), - ('same-domain', "Only send for the same domain." - " This will still protect your privacy, but" - " shouldn't break any sites.")) - - class UserAgent(BaseType): """The user agent to use.""" @@ -1660,29 +1538,6 @@ class UserAgent(BaseType): return out -class TabBarShow(BaseType): - - """When to show the tab bar.""" - - def __init__(self): - self.valid_values = \ - ValidValues(('always', "Always show the tab bar."), - ('never', "Always hide the tab bar."), - ('multiple', "Hide the tab bar if only one tab " - "is open."), - ('switching', "Show the tab bar when switching " - "tabs.")) - - -class URLSegmentList(FlagList): - - """A list of URL segments.""" - - def __init__(self, none_ok=False): - super().__init__(none_ok) - self.valid_values = ValidValues('host', 'path', 'query', 'anchor') - - class TimestampTemplate(BaseType): """A strftime-like template for timestamps. From 6431542eba78b1b510b00b330adf66d7f4349607 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Wed, 25 Nov 2015 11:11:30 +0100 Subject: [PATCH 04/15] fixes to config types, remove unneeded derived __init__ and call base __init__ --- qutebrowser/config/configtypes.py | 85 +++++++++++++------------------ 1 file changed, 36 insertions(+), 49 deletions(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 1d9ecae3a..5d6acc0db 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -123,9 +123,8 @@ class BaseType: special = False - def __init__(self, none_ok=False, valid_values=None): + def __init__(self, none_ok=False): self.none_ok = none_ok - self.valid_values = valid_values def _basic_validation(self, value): """Do some basic validation for the value (empty, non-printable chars). @@ -244,7 +243,8 @@ class String(BaseType): def __init__(self, minlen=None, maxlen=None, forbidden=None, none_ok=False, completions=None, valid_values=None): - super().__init__(none_ok, valid_values) + super().__init__(none_ok) + self.valid_values = valid_values if minlen is not None and minlen < 1: raise ValueError("minlen ({}) needs to be >= 1!".format(minlen)) elif maxlen is not None and maxlen < 1: @@ -651,13 +651,12 @@ class ColorSystem(MappingType): special = True - def __init__(self): - self.valid_values = ValidValues( - ('rgb', "Interpolate in the RGB color system."), - ('hsv', "Interpolate in the HSV color system."), - ('hsl', "Interpolate in the HSL color system."), - ('none', "Don't show a gradient.")) - + valid_values = ValidValues( + ('rgb', "Interpolate in the RGB color system."), + ('hsv', "Interpolate in the HSV color system."), + ('hsl', "Interpolate in the HSL color system."), + ('none', "Don't show a gradient.")) + MAPPING = { 'rgb': QColor.Rgb, 'hsv': QColor.Hsv, @@ -1095,11 +1094,9 @@ class Proxy(BaseType): """A proxy URL or special value.""" special = True - - def __init__(self): - self.valid_values = ValidValues( - ('system', "Use the system wide proxy."), - ('none', "Don't use any proxy")) + valid_values = ValidValues( + ('system', "Use the system wide proxy."), + ('none', "Don't use any proxy")) PROXY_TYPES = { 'http': QNetworkProxy.HttpProxy, @@ -1209,12 +1206,10 @@ class FuzzyUrl(BaseType): PaddingValues = collections.namedtuple('PaddingValues', ['top', 'bottom', 'left', 'right']) - - class Padding(IntList): """Setting for paddings around elements.""" - + def validate(self, value): self._basic_validation(value) if not value: @@ -1326,8 +1321,7 @@ class Position(MappingType): """The position of the tab bar.""" - def __init__(self): - self.valid_values = ValidValues('top', 'bottom', 'left', 'right') + valid_values = ValidValues('top', 'bottom', 'left', 'right') MAPPING = { 'top': QTabWidget.North, @@ -1341,8 +1335,7 @@ class VerticalPosition(BaseType): """The position of the download bar.""" - def __init__(self): - self.valid_values = ValidValues('top', 'bottom') + valid_values = ValidValues('top', 'bottom') class UrlList(List): @@ -1387,11 +1380,11 @@ class SelectOnRemove(MappingType): """Which tab to select when the focused tab is removed.""" special = True - def __init__(self): - self.valid_values = ValidValues( - ('left', "Select the tab on the left."), - ('right', "Select the tab on the right."), - ('previous', "Select the previously selected tab.")) + + valid_values = ValidValues( + ('left', "Select the tab on the left."), + ('right', "Select the tab on the right."), + ('previous', "Select the previously selected tab.")) MAPPING = { 'left': QTabBar.SelectLeftTab, @@ -1406,13 +1399,12 @@ class ConfirmQuit(FlagList): special = True - def __init__(self): - self.valid_values = ValidValues(('always', "Always show a confirmation."), - ('multiple-tabs', "Show a confirmation if " - "multiple tabs are opened."), - ('downloads', "Show a confirmation if " - "downloads are running"), - ('never', "Never show a confirmation.")) + valid_values = ValidValues(('always', "Always show a confirmation."), + ('multiple-tabs', "Show a confirmation if " + "multiple tabs are opened."), + ('downloads', "Show a confirmation if " + "downloads are running"), + ('never', "Never show a confirmation.")) # Values that can be combined with commas combinable_values = ('multiple-tabs', 'downloads') @@ -1438,12 +1430,11 @@ class NewTabPosition(BaseType): special = True - def __init__(self): - self.valid_values = ValidValues( - ('left', "On the left of the current tab."), - ('right', "On the right of the current tab."), - ('first', "At the left end."), - ('last', "At the right end.")) + valid_values = ValidValues( + ('left', "On the left of the current tab."), + ('right', "On the right of the current tab."), + ('first', "At the left end."), + ('last', "At the right end.")) class IgnoreCase(Bool): @@ -1452,12 +1443,11 @@ class IgnoreCase(Bool): special = True - def __init__(self): - self.valid_values = ValidValues( - ('true', "Search case-insensitively"), - ('false', "Search case-sensitively"), - ('smart', "Search case-sensitively if there " - "are capital chars")) + valid_values = ValidValues( + ('true', "Search case-insensitively"), + ('false', "Search case-sensitively"), + ('smart', "Search case-sensitively if there " + "are capital chars")) def transform(self, value): if value.lower() == 'smart': @@ -1481,9 +1471,6 @@ class UserAgent(BaseType): special = True - def __init__(self, none_ok=False): - super().__init__(none_ok) - def validate(self, value): self._basic_validation(value) From 2867df4c21b972b95405ef4b9e37b4c48a09b2b2 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Wed, 25 Nov 2015 12:07:39 +0100 Subject: [PATCH 05/15] revert log-javascript-console changes --- qutebrowser/browser/webpage.py | 12 ++---------- qutebrowser/config/configdata.py | 9 ++------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index 32e56d798..16460eaad 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -503,16 +503,8 @@ class BrowserPage(QWebPage): def javaScriptConsoleMessage(self, msg, line, source): """Override javaScriptConsoleMessage to use debug log.""" - - log_javascript_console = config.get('general', - 'log-javascript-console' ) - logstring = "[{}:{}] {}".format(source, line, msg) - logmap = { - 'debug': log.js.debug, - 'info': log.js.info, - 'none': lambda arg: None - } - logmap[log_javascript_console](logstring) + if config.get('general', 'log-javascript-console'): + log.js.debug("[{}:{}] {}".format(source, line, msg)) def chooseFile(self, _frame, suggested_file): """Override QWebPage's chooseFile to be able to chose a file to upload. diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index a010e9e05..41362d1a7 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -229,13 +229,8 @@ def data(readonly=False): "launched."), ('log-javascript-console', - SettingValue(typ.String( - valid_values=typ.ValidValues( - ('none', 'Not displayed'), - ('debug', 'Display in debug mode'), - ('info', 'Display always') - )), 'debug'), - "How to log javascript console messages."), + SettingValue(typ.Bool(), 'false'), + "Whether to log javascript console messages."), ('save-session', SettingValue(typ.Bool(), 'false'), From 55edd9cda7e16283d13656ed4e1796572e3fc0b4 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Wed, 25 Nov 2015 12:16:11 +0100 Subject: [PATCH 06/15] add valid_values = None to config basetype --- qutebrowser/config/configtypes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 5d6acc0db..46af59069 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -122,6 +122,7 @@ class BaseType: """ special = False + valid_values = None def __init__(self, none_ok=False): self.none_ok = none_ok From 9aaf5c18c122c31f04d8d8c3785d92091e657d2b Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Wed, 25 Nov 2015 14:19:14 +0100 Subject: [PATCH 07/15] set valid_values in __init__ methods, except for BaseType s.t. variable is shared across derived class scopes --- qutebrowser/config/configtypes.py | 105 ++++++++++++++++++------------ 1 file changed, 65 insertions(+), 40 deletions(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 46af59069..066d53e8e 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -244,8 +244,9 @@ class String(BaseType): def __init__(self, minlen=None, maxlen=None, forbidden=None, none_ok=False, completions=None, valid_values=None): - super().__init__(none_ok) self.valid_values = valid_values + super().__init__(none_ok) + if minlen is not None and minlen < 1: raise ValueError("minlen ({}) needs to be >= 1!".format(minlen)) elif maxlen is not None and maxlen < 1: @@ -352,7 +353,9 @@ class Bool(BaseType): """Base class for a boolean setting.""" - valid_values = ValidValues('true', 'false') + def __init__(self, none_ok=False): + self.valid_values = ValidValues('true', 'false') + super().__init__(none_ok) def transform(self, value): if not value: @@ -372,7 +375,9 @@ class BoolAsk(Bool): """A yes/no/ask question.""" - valid_values = ValidValues('true', 'false', 'ask') + def __init__(self, none_ok=False): + self.valid_values = ValidValues('true', 'false', 'ask') + super().__init__(none_ok) def transform(self, value): if value.lower() == 'ask': @@ -652,11 +657,13 @@ class ColorSystem(MappingType): special = True - valid_values = ValidValues( - ('rgb', "Interpolate in the RGB color system."), - ('hsv', "Interpolate in the HSV color system."), - ('hsl', "Interpolate in the HSL color system."), - ('none', "Don't show a gradient.")) + def __init__(self, none_ok=False): + self.valid_values = ValidValues( + ('rgb', "Interpolate in the RGB color system."), + ('hsv', "Interpolate in the HSV color system."), + ('hsl', "Interpolate in the HSL color system."), + ('none', "Don't show a gradient.")) + super().__init__(none_ok) MAPPING = { 'rgb': QColor.Rgb, @@ -1095,9 +1102,6 @@ class Proxy(BaseType): """A proxy URL or special value.""" special = True - valid_values = ValidValues( - ('system', "Use the system wide proxy."), - ('none', "Don't use any proxy")) PROXY_TYPES = { 'http': QNetworkProxy.HttpProxy, @@ -1105,6 +1109,12 @@ class Proxy(BaseType): 'socks5': QNetworkProxy.Socks5Proxy, } + def __init__(self, none_ok=False): + self.valid_values = ValidValues( + ('system', "Use the system wide proxy."), + ('none', "Don't use any proxy")) + super().__init__(none_ok) + def validate(self, value): self._basic_validation(value) if not value: @@ -1289,13 +1299,14 @@ class AutoSearch(BaseType): """Whether to start a search when something else than a URL is entered.""" special = True - valid_values = ValidValues(('naive', "Use simple/naive check."), - ('dns', "Use DNS requests (might be slow!)."), - ('false', "Never search automatically.")) def __init__(self, none_ok=False): - super().__init__(none_ok) self.booltype = Bool(none_ok=none_ok) + self.valid_values = ValidValues( + ('naive', "Use simple/naive check."), + ('dns', "Use DNS requests (might be slow!)."), + ('false', "Never search automatically.")) + super().__init__(none_ok) def validate(self, value): self._basic_validation(value) @@ -1322,8 +1333,6 @@ class Position(MappingType): """The position of the tab bar.""" - valid_values = ValidValues('top', 'bottom', 'left', 'right') - MAPPING = { 'top': QTabWidget.North, 'bottom': QTabWidget.South, @@ -1331,12 +1340,18 @@ class Position(MappingType): 'right': QTabWidget.East, } + def __init__(self, none_ok=False): + self.valid_values = ValidValues('top', 'bottom', 'left', 'right') + super().__init__(none_ok) + class VerticalPosition(BaseType): """The position of the download bar.""" - valid_values = ValidValues('top', 'bottom') + def __init__(self, none_ok=False): + self.valid_values = ValidValues('top', 'bottom') + super().__init__(none_ok) class UrlList(List): @@ -1382,17 +1397,19 @@ class SelectOnRemove(MappingType): special = True - valid_values = ValidValues( - ('left', "Select the tab on the left."), - ('right', "Select the tab on the right."), - ('previous', "Select the previously selected tab.")) - MAPPING = { 'left': QTabBar.SelectLeftTab, 'right': QTabBar.SelectRightTab, 'previous': QTabBar.SelectPreviousTab, } + def __init__(self, none_ok=False): + self.valid_values = ValidValues( + ('left', "Select the tab on the left."), + ('right', "Select the tab on the right."), + ('previous', "Select the previously selected tab.")) + super().__init__(none_ok) + class ConfirmQuit(FlagList): @@ -1400,15 +1417,19 @@ class ConfirmQuit(FlagList): special = True - valid_values = ValidValues(('always', "Always show a confirmation."), - ('multiple-tabs', "Show a confirmation if " - "multiple tabs are opened."), - ('downloads', "Show a confirmation if " - "downloads are running"), - ('never', "Never show a confirmation.")) # Values that can be combined with commas combinable_values = ('multiple-tabs', 'downloads') + def __init__(self, none_ok=False): + self.valid_values = ValidValues( + ('always', "Always show a confirmation."), + ('multiple-tabs', "Show a confirmation if " + "multiple tabs are opened."), + ('downloads', "Show a confirmation if " + "downloads are running"), + ('never', "Never show a confirmation.")) + super().__init__(none_ok) + def validate(self, value): super().validate(value) if not value: @@ -1430,12 +1451,14 @@ class NewTabPosition(BaseType): """How new tabs are positioned.""" special = True - - valid_values = ValidValues( - ('left', "On the left of the current tab."), - ('right', "On the right of the current tab."), - ('first', "At the left end."), - ('last', "At the right end.")) + + def __init__(self, none_ok=False): + self.valid_values = ValidValues( + ('left', "On the left of the current tab."), + ('right', "On the right of the current tab."), + ('first', "At the left end."), + ('last', "At the right end.")) + super().__init__(none_ok) class IgnoreCase(Bool): @@ -1444,11 +1467,13 @@ class IgnoreCase(Bool): special = True - valid_values = ValidValues( - ('true', "Search case-insensitively"), - ('false', "Search case-sensitively"), - ('smart', "Search case-sensitively if there " - "are capital chars")) + def __init__(self, none_ok=False): + self.valid_values = ValidValues( + ('true', "Search case-insensitively"), + ('false', "Search case-sensitively"), + ('smart', "Search case-sensitively if there " + "are capital chars")) + super().__init__(none_ok) def transform(self, value): if value.lower() == 'smart': From 9b453aaad5981bf33078b8c80e391294067e4035 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Wed, 25 Nov 2015 16:35:10 +0100 Subject: [PATCH 08/15] revert config transformation --- qutebrowser/config/config.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 88ca89e5d..aea69494b 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -356,9 +356,7 @@ class ConfigManager(QObject): ('tabs', 'position'): _transform_position, ('ui', 'downloads-position'): _transform_position, ('ui', 'remove-finished-downloads'): - _get_value_transformer({'false': '-1', 'true': '1000'}), - ('general', 'log-javascript-console'): - _get_value_transformer({'false': 'none', 'true': 'debug'}), + _get_value_transformer({'false': '-1', 'true': '1000'}) } changed = pyqtSignal(str, str) From 6f65397dfe3c8add26a7f283d965635ebef46ca8 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Thu, 26 Nov 2015 10:17:16 +0100 Subject: [PATCH 09/15] always set valid_values in __init__ instead of class scope variable --- qutebrowser/config/configtypes.py | 53 +++++++++++++++------------ tests/unit/config/test_configtypes.py | 19 +++++++--- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 066d53e8e..c46d0ae75 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -122,10 +122,10 @@ class BaseType: """ special = False - valid_values = None def __init__(self, none_ok=False): self.none_ok = none_ok + self.valid_values = None def _basic_validation(self, value): """Do some basic validation for the value (empty, non-printable chars). @@ -216,8 +216,10 @@ class MappingType(BaseType): MAPPING = {} - def __init__(self, none_ok=False): + def __init__(self, none_ok=False, + valid_values=None): super().__init__(none_ok) + self.valid_values = valid_values; if list(sorted(self.MAPPING)) != list(sorted(self.valid_values)): raise ValueError("Mapping {!r} doesn't match valid values " "{!r}".format(self.MAPPING, self.valid_values)) @@ -244,8 +246,8 @@ class String(BaseType): def __init__(self, minlen=None, maxlen=None, forbidden=None, none_ok=False, completions=None, valid_values=None): - self.valid_values = valid_values super().__init__(none_ok) + self.valid_values = valid_values if minlen is not None and minlen < 1: raise ValueError("minlen ({}) needs to be >= 1!".format(minlen)) @@ -354,8 +356,8 @@ class Bool(BaseType): """Base class for a boolean setting.""" def __init__(self, none_ok=False): - self.valid_values = ValidValues('true', 'false') super().__init__(none_ok) + self.valid_values = ValidValues('true', 'false') def transform(self, value): if not value: @@ -376,8 +378,8 @@ class BoolAsk(Bool): """A yes/no/ask question.""" def __init__(self, none_ok=False): - self.valid_values = ValidValues('true', 'false', 'ask') super().__init__(none_ok) + self.valid_values = ValidValues('true', 'false', 'ask') def transform(self, value): if value.lower() == 'ask': @@ -658,12 +660,13 @@ class ColorSystem(MappingType): special = True def __init__(self, none_ok=False): - self.valid_values = ValidValues( - ('rgb', "Interpolate in the RGB color system."), - ('hsv', "Interpolate in the HSV color system."), - ('hsl', "Interpolate in the HSL color system."), - ('none', "Don't show a gradient.")) - super().__init__(none_ok) + super().__init__( + none_ok, + valid_values = ValidValues( + ('rgb', "Interpolate in the RGB color system."), + ('hsv', "Interpolate in the HSV color system."), + ('hsl', "Interpolate in the HSL color system."), + ('none', "Don't show a gradient."))) MAPPING = { 'rgb': QColor.Rgb, @@ -1110,10 +1113,10 @@ class Proxy(BaseType): } def __init__(self, none_ok=False): + super().__init__(none_ok) self.valid_values = ValidValues( ('system', "Use the system wide proxy."), ('none', "Don't use any proxy")) - super().__init__(none_ok) def validate(self, value): self._basic_validation(value) @@ -1301,12 +1304,12 @@ class AutoSearch(BaseType): special = True def __init__(self, none_ok=False): + super().__init__(none_ok) self.booltype = Bool(none_ok=none_ok) self.valid_values = ValidValues( ('naive', "Use simple/naive check."), ('dns', "Use DNS requests (might be slow!)."), ('false', "Never search automatically.")) - super().__init__(none_ok) def validate(self, value): self._basic_validation(value) @@ -1341,8 +1344,9 @@ class Position(MappingType): } def __init__(self, none_ok=False): - self.valid_values = ValidValues('top', 'bottom', 'left', 'right') - super().__init__(none_ok) + super().__init__( + none_ok, + valid_values = ValidValues('top', 'bottom', 'left', 'right')) class VerticalPosition(BaseType): @@ -1350,8 +1354,8 @@ class VerticalPosition(BaseType): """The position of the download bar.""" def __init__(self, none_ok=False): - self.valid_values = ValidValues('top', 'bottom') super().__init__(none_ok) + self.valid_values = ValidValues('top', 'bottom') class UrlList(List): @@ -1404,11 +1408,12 @@ class SelectOnRemove(MappingType): } def __init__(self, none_ok=False): - self.valid_values = ValidValues( - ('left', "Select the tab on the left."), - ('right', "Select the tab on the right."), - ('previous', "Select the previously selected tab.")) - super().__init__(none_ok) + super().__init__( + none_ok, + valid_values = ValidValues( + ('left', "Select the tab on the left."), + ('right', "Select the tab on the right."), + ('previous', "Select the previously selected tab."))) class ConfirmQuit(FlagList): @@ -1421,6 +1426,7 @@ class ConfirmQuit(FlagList): combinable_values = ('multiple-tabs', 'downloads') def __init__(self, none_ok=False): + super().__init__(none_ok) self.valid_values = ValidValues( ('always', "Always show a confirmation."), ('multiple-tabs', "Show a confirmation if " @@ -1428,7 +1434,6 @@ class ConfirmQuit(FlagList): ('downloads', "Show a confirmation if " "downloads are running"), ('never', "Never show a confirmation.")) - super().__init__(none_ok) def validate(self, value): super().validate(value) @@ -1453,12 +1458,12 @@ class NewTabPosition(BaseType): special = True def __init__(self, none_ok=False): + super().__init__(none_ok) self.valid_values = ValidValues( ('left', "On the left of the current tab."), ('right', "On the right of the current tab."), ('first', "At the left end."), ('last', "At the right end.")) - super().__init__(none_ok) class IgnoreCase(Bool): @@ -1468,12 +1473,12 @@ class IgnoreCase(Bool): special = True def __init__(self, none_ok=False): + super().__init__(none_ok) self.valid_values = ValidValues( ('true', "Search case-insensitively"), ('false', "Search case-sensitively"), ('smart', "Search case-sensitively if there " "are capital chars")) - super().__init__(none_ok) def transform(self, value): if value.lower() == 'smart': diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 7c8bf8d56..c77701f0d 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -229,24 +229,30 @@ class GoodMappingSubclass(configtypes.MappingType): """A MappingType we use in TestMappingType which is valid/good.""" - valid_values = configtypes.ValidValues('one', 'two') - MAPPING = { 'one': 1, 'two': 2, } + def __init__(self, none_ok=False): + super().__init__( + none_ok, + valid_values = configtypes.ValidValues('one', 'two')) + class BadMappingSubclass(configtypes.MappingType): """A MappingType which is missing a value in MAPPING.""" - valid_values = configtypes.ValidValues('one', 'two') - MAPPING = { 'one': 1, } + def __init__(self, none_ok=False): + super().__init__( + none_ok, + valid_values = configtypes.ValidValues('one', 'two')) + class TestMappingType: @@ -383,9 +389,12 @@ class FlagListSubclass(configtypes.FlagList): Valid values are 'foo', 'bar' and 'baz'. """ - valid_values = configtypes.ValidValues('foo', 'bar', 'baz') combinable_values = ['foo', 'bar'] + def __init__(self, none_ok=False): + super().__init__(none_ok) + self.valid_values = configtypes.ValidValues('foo', 'bar', 'baz') + class TestFlagList: From c322130dc0c1bf88fcb3a9c3b12329f03884ed4e Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Fri, 27 Nov 2015 00:03:04 +0100 Subject: [PATCH 10/15] style changes --- qutebrowser/config/configdata.py | 27 +++++++++++++++------------ qutebrowser/config/configtypes.py | 23 ++++++++++++++++------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 41362d1a7..387d4225b 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -242,7 +242,10 @@ def data(readonly=False): "last loaded session."), ('url-incdec-segments', - SettingValue(typ.URLSegmentList(), 'path,query'), + SettingValue( + typ.FlagList(valid_values=typ.ValidValues( + 'host', 'path', 'query', 'anchor')), + 'path,query'), "The URL segments where `:navigate increment/decrement` will " "search for a number."), @@ -402,12 +405,12 @@ def data(readonly=False): "Automatically open completion when typing."), ('download-path-suggestion', - SettingValue(typ.String( - valid_values=typ.ValidValues( + SettingValue( + typ.String(valid_values=typ.ValidValues( ('path', "Show only the download path."), ('filename', "Show only download filename."), ('both', "Show download path and filename."))), - 'path'), + 'path'), "What to display in the download filename input."), ('timestamp-format', @@ -547,14 +550,14 @@ def data(readonly=False): "Behavior when the last tab is closed."), ('show', - SettingValue(typ.String( - valid_values=typ.ValidValues( - ('always', "Always show the tab bar."), - ('never', "Always hide the tab bar."), - ('multiple', "Hide the tab bar if only one tab " - "is open."), - ('switching', "Show the tab bar when switching " - "tabs.") + SettingValue( + typ.String(valid_values=typ.ValidValues( + ('always', "Always show the tab bar."), + ('never', "Always hide the tab bar."), + ('multiple', "Hide the tab bar if only one tab " + "is open."), + ('switching', "Show the tab bar when switching " + "tabs.") )), 'always'), "When to show the tab bar"), diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index c46d0ae75..c67a37d77 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -219,7 +219,7 @@ class MappingType(BaseType): def __init__(self, none_ok=False, valid_values=None): super().__init__(none_ok) - self.valid_values = valid_values; + self.valid_values = valid_values if list(sorted(self.MAPPING)) != list(sorted(self.valid_values)): raise ValueError("Mapping {!r} doesn't match valid values " "{!r}".format(self.MAPPING, self.valid_values)) @@ -284,6 +284,10 @@ class List(BaseType): """Base class for a (string-)list setting.""" + def __init__(self, none_ok=False, valid_values=None): + super().__init__(none_ok) + self.valid_values = valid_values + def transform(self, value): if not value: return None @@ -309,6 +313,9 @@ class FlagList(List): combinable_values = None + def __init__(self, none_ok=False, valid_values=None): + super().__init__(none_ok, valid_values) + def validate(self, value): self._basic_validation(value) if not value: @@ -662,12 +669,12 @@ class ColorSystem(MappingType): def __init__(self, none_ok=False): super().__init__( none_ok, - valid_values = ValidValues( + valid_values=ValidValues( ('rgb', "Interpolate in the RGB color system."), ('hsv', "Interpolate in the HSV color system."), ('hsl', "Interpolate in the HSL color system."), ('none', "Don't show a gradient."))) - + MAPPING = { 'rgb': QColor.Rgb, 'hsv': QColor.Hsv, @@ -1220,10 +1227,12 @@ class FuzzyUrl(BaseType): PaddingValues = collections.namedtuple('PaddingValues', ['top', 'bottom', 'left', 'right']) + + class Padding(IntList): """Setting for paddings around elements.""" - + def validate(self, value): self._basic_validation(value) if not value: @@ -1346,7 +1355,7 @@ class Position(MappingType): def __init__(self, none_ok=False): super().__init__( none_ok, - valid_values = ValidValues('top', 'bottom', 'left', 'right')) + valid_values=ValidValues('top', 'bottom', 'left', 'right')) class VerticalPosition(BaseType): @@ -1410,7 +1419,7 @@ class SelectOnRemove(MappingType): def __init__(self, none_ok=False): super().__init__( none_ok, - valid_values = ValidValues( + valid_values=ValidValues( ('left', "Select the tab on the left."), ('right', "Select the tab on the right."), ('previous', "Select the previously selected tab."))) @@ -1434,7 +1443,7 @@ class ConfirmQuit(FlagList): ('downloads', "Show a confirmation if " "downloads are running"), ('never', "Never show a confirmation.")) - + def validate(self, value): super().validate(value) if not value: From c14b52f916da5c801186ed1868bf02eb3059a343 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Fri, 27 Nov 2015 16:27:43 +0100 Subject: [PATCH 11/15] initialize valid_values separately, not using base class __init__ parameter --- tests/unit/config/test_configtypes.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index c77701f0d..219519638 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -249,9 +249,8 @@ class BadMappingSubclass(configtypes.MappingType): } def __init__(self, none_ok=False): - super().__init__( - none_ok, - valid_values = configtypes.ValidValues('one', 'two')) + super().__init__(none_ok) + self.valid_values = configtypes.ValidValues('one', 'two')) class TestMappingType: From fdde05569c9b30e22762c2243c78a298daf2101c Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Fri, 27 Nov 2015 16:28:35 +0100 Subject: [PATCH 12/15] remove redundant __init__ and rely on base class --- qutebrowser/config/configtypes.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index c67a37d77..5a7c3f72e 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -313,9 +313,6 @@ class FlagList(List): combinable_values = None - def __init__(self, none_ok=False, valid_values=None): - super().__init__(none_ok, valid_values) - def validate(self, value): self._basic_validation(value) if not value: From 03ba38578e611bef8921a863daa613396f9a1e4b Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Sat, 28 Nov 2015 18:29:21 +0100 Subject: [PATCH 13/15] set valid_values after __init__ consistently, move type validation out of class into pytest --- qutebrowser/config/configtypes.py | 3 --- tests/unit/config/test_configtypes.py | 17 +++++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 5a7c3f72e..d4d498358 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -220,9 +220,6 @@ class MappingType(BaseType): valid_values=None): super().__init__(none_ok) self.valid_values = valid_values - if list(sorted(self.MAPPING)) != list(sorted(self.valid_values)): - raise ValueError("Mapping {!r} doesn't match valid values " - "{!r}".format(self.MAPPING, self.valid_values)) def validate(self, value): super().validate(value.lower()) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 219519638..5a596747e 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -235,9 +235,8 @@ class GoodMappingSubclass(configtypes.MappingType): } def __init__(self, none_ok=False): - super().__init__( - none_ok, - valid_values = configtypes.ValidValues('one', 'two')) + super().__init__(none_ok) + self.valid_values = configtypes.ValidValues('one', 'two') class BadMappingSubclass(configtypes.MappingType): @@ -250,7 +249,7 @@ class BadMappingSubclass(configtypes.MappingType): def __init__(self, none_ok=False): super().__init__(none_ok) - self.valid_values = configtypes.ValidValues('one', 'two')) + self.valid_values = configtypes.ValidValues('one', 'two') class TestMappingType: @@ -281,11 +280,13 @@ class TestMappingType: def test_transform(self, klass, val, expected): assert klass().transform(val) == expected - def test_bad_subclass_init(self): - with pytest.raises(ValueError): - BadMappingSubclass() - + @pytest.mark.parametrize('typ', [configtypes.ColorSystem(), + configtypes.Position(), + configtypes.SelectOnRemove()]) + def test_mapping_type_matches_valid_values(self, typ): + assert list(sorted(typ.MAPPING)) == list(sorted(typ.valid_values)) + class TestString: """Test String.""" From dbc6f63fc05497bbf00fbbdf41a2b3780b35ca47 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Sat, 28 Nov 2015 18:57:41 +0100 Subject: [PATCH 14/15] remove whitespace --- tests/unit/config/test_configtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 5a596747e..62533364e 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -286,7 +286,7 @@ class TestMappingType: def test_mapping_type_matches_valid_values(self, typ): assert list(sorted(typ.MAPPING)) == list(sorted(typ.valid_values)) - + class TestString: """Test String.""" From 913aa209c6062fa0b14dd71510289708f358d9a6 Mon Sep 17 00:00:00 2001 From: Patric Schmitz Date: Sat, 28 Nov 2015 20:17:31 +0100 Subject: [PATCH 15/15] remove BadMappingSubclass and rename MappingSubclass --- tests/unit/config/test_configtypes.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 62533364e..43190c3cf 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -225,7 +225,7 @@ class TestBaseType: assert basetype.complete() == completions -class GoodMappingSubclass(configtypes.MappingType): +class MappingSubclass(configtypes.MappingType): """A MappingType we use in TestMappingType which is valid/good.""" @@ -239,19 +239,6 @@ class GoodMappingSubclass(configtypes.MappingType): self.valid_values = configtypes.ValidValues('one', 'two') -class BadMappingSubclass(configtypes.MappingType): - - """A MappingType which is missing a value in MAPPING.""" - - MAPPING = { - 'one': 1, - } - - def __init__(self, none_ok=False): - super().__init__(none_ok) - self.valid_values = configtypes.ValidValues('one', 'two') - - class TestMappingType: """Test MappingType.""" @@ -265,7 +252,7 @@ class TestMappingType: @pytest.fixture def klass(self): - return GoodMappingSubclass + return MappingSubclass @pytest.mark.parametrize('val', TESTS.keys()) def test_validate_valid(self, klass, val):