Add some type checking for enums

This commit is contained in:
Florian Bruhin 2014-07-29 00:23:20 +02:00
parent 7c8f9bec0f
commit 54246bacbe
10 changed files with 94 additions and 11 deletions

View File

@ -63,12 +63,24 @@ class HintContext:
def __init__(self): def __init__(self):
self.elems = {} self.elems = {}
self.target = None self._target = None
self.baseurl = None self.baseurl = None
self.to_follow = None self.to_follow = None
self.frames = [] self.frames = []
self.connected_frames = [] self.connected_frames = []
@property
def target(self):
"""Getter for target so we can define a setter."""
return self._target
@target.setter
def target(self, val):
"""Setter for target to do type checking."""
if not isinstance(val, Target):
raise TypeError("Target {} is no Target member!".format(val))
self._target = val
class HintManager(QObject): class HintManager(QObject):
@ -433,6 +445,8 @@ class HintManager(QObject):
Emit: Emit:
hint_strings_updated: Emitted to update keypraser. hint_strings_updated: Emitted to update keypraser.
""" """
if not isinstance(target, Target):
raise TypeError("Target {} is no Target member!".format(target))
if mainframe is None: if mainframe is None:
# This should never happen since we check frame before calling # This should never happen since we check frame before calling
# start. But since we had a bug where frame is None in # start. But since we had a bug where frame is None in

View File

@ -29,6 +29,7 @@ from collections import Iterable
import qutebrowser.utils.qt as qtutils import qutebrowser.utils.qt as qtutils
from qutebrowser.commands.command import Command from qutebrowser.commands.command import Command
from qutebrowser.commands.exceptions import CommandError from qutebrowser.commands.exceptions import CommandError
from qutebrowser.utils.usertypes import KeyMode
cmd_dict = {} cmd_dict = {}
@ -132,6 +133,14 @@ class register: # pylint: disable=invalid-name
self.not_modes = not_modes self.not_modes = not_modes
self.needs_js = needs_js self.needs_js = needs_js
self.debug = debug self.debug = debug
if modes is not None:
for m in modes:
if not isinstance(m, KeyMode):
raise TypeError("Mode {} is no KeyMode member!".format(m))
if not_modes is not None:
for m in not_modes:
if not isinstance(m, KeyMode):
raise TypeError("Mode {} is no KeyMode member!".format(m))
def __call__(self, func): def __call__(self, func):
"""Register the command before running the function. """Register the command before running the function.

View File

@ -165,6 +165,8 @@ def _set_setting(typ, arg, value):
arg: The argument (attribute/handler) arg: The argument (attribute/handler)
value: The value to set. value: The value to set.
""" """
if not isinstance(typ, MapType):
raise TypeError("Type {} is no MapType member!".format(typ))
if typ == MapType.attribute: if typ == MapType.attribute:
settings.setAttribute(arg, value) settings.setAttribute(arg, value)
elif typ == MapType.setter and value is not None: elif typ == MapType.setter and value is not None:

View File

@ -180,6 +180,9 @@ class BaseKeyParser(QObject):
match, binding = self._match_key(cmd_input) match, binding = self._match_key(cmd_input)
if not isinstance(match, self.Match):
raise TypeError("Value {} is no Match member!".format(match))
if match == self.Match.definitive: if match == self.Match.definitive:
self._debug_log("Definitive match for '{}'.".format( self._debug_log("Definitive match for '{}'.".format(
self._keystring)) self._keystring))

View File

@ -182,6 +182,8 @@ class ModeManager(QObject):
passthrough: Whether to pass keybindings in this mode through to passthrough: Whether to pass keybindings in this mode through to
the widgets. the widgets.
""" """
if not isinstance(mode, KeyMode):
raise TypeError("Mode {} is no KeyMode member!".format(mode))
self._handlers[mode] = handler self._handlers[mode] = handler
if passthrough: if passthrough:
self.passthrough.append(mode) self.passthrough.append(mode)
@ -196,6 +198,8 @@ class ModeManager(QObject):
Emit: Emit:
entered: With the new mode name. entered: With the new mode name.
""" """
if not isinstance(mode, KeyMode):
raise TypeError("Mode {} is no KeyMode member!".format(mode))
logger.debug("Entering mode {}{}".format( logger.debug("Entering mode {}{}".format(
mode, '' if reason is None else ' (reason: {})'.format(reason))) mode, '' if reason is None else ' (reason: {})'.format(reason)))
if mode not in self._handlers: if mode not in self._handlers:

View File

@ -89,7 +89,7 @@ class HintKeyParser(CommandKeyParser):
Attributes: Attributes:
_filtertext: The text to filter with. _filtertext: The text to filter with.
_last_press: The nature of the last keypress, a LastPress member. last_press: The nature of the last keypress, a LastPress member.
""" """
fire_hint = pyqtSignal(str) fire_hint = pyqtSignal(str)
@ -98,9 +98,22 @@ class HintKeyParser(CommandKeyParser):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent, supports_count=False, supports_chains=True) super().__init__(parent, supports_count=False, supports_chains=True)
self._filtertext = '' self._filtertext = ''
self._last_press = LastPress.none self._last_press = None
self.last_press = LastPress.none
self.read_config('keybind.hint') self.read_config('keybind.hint')
@property
def last_press(self):
"""Getter for last_press so we can define a setter."""
return self._last_press
@last_press.setter
def last_press(self, val):
"""Setter for last_press to do typechecking."""
if not isinstance(val, LastPress):
raise TypeError("Value {} is no LastPress member!".format(val))
self._last_press = val
def _handle_special_key(self, e): def _handle_special_key(self, e):
"""Override _handle_special_key to handle string filtering. """Override _handle_special_key to handle string filtering.
@ -120,13 +133,13 @@ class HintKeyParser(CommandKeyParser):
e.key(), e.text())) e.key(), e.text()))
if e.key() == Qt.Key_Backspace: if e.key() == Qt.Key_Backspace:
logger.debug("Got backspace, mode {}, filtertext '{}', keystring " logger.debug("Got backspace, mode {}, filtertext '{}', keystring "
"'{}'".format(self._last_press, self._filtertext, "'{}'".format(self.last_press, self._filtertext,
self._keystring)) self._keystring))
if self._last_press == LastPress.filtertext and self._filtertext: if self.last_press == LastPress.filtertext and self._filtertext:
self._filtertext = self._filtertext[:-1] self._filtertext = self._filtertext[:-1]
self.filter_hints.emit(self._filtertext) self.filter_hints.emit(self._filtertext)
return True return True
elif self._last_press == LastPress.keystring and self._keystring: elif self.last_press == LastPress.keystring and self._keystring:
self._keystring = self._keystring[:-1] self._keystring = self._keystring[:-1]
self.keystring_updated.emit(self._keystring) self.keystring_updated.emit(self._keystring)
return True return True
@ -139,7 +152,7 @@ class HintKeyParser(CommandKeyParser):
else: else:
self._filtertext += e.text() self._filtertext += e.text()
self.filter_hints.emit(self._filtertext) self.filter_hints.emit(self._filtertext)
self._last_press = LastPress.filtertext self.last_press = LastPress.filtertext
return True return True
def handle(self, e): def handle(self, e):
@ -155,12 +168,12 @@ class HintKeyParser(CommandKeyParser):
if handled and self._keystring: if handled and self._keystring:
# A key has been added to the keystring (Match.partial) # A key has been added to the keystring (Match.partial)
self.keystring_updated.emit(self._keystring) self.keystring_updated.emit(self._keystring)
self._last_press = LastPress.keystring self.last_press = LastPress.keystring
return handled return handled
elif handled: elif handled:
# We handled the key but the keystring is empty. This happens when # We handled the key but the keystring is empty. This happens when
# match is Match.definitive, so a keychain has been completed. # match is Match.definitive, so a keychain has been completed.
self._last_press = LastPress.none self.last_press = LastPress.none
return handled return handled
else: else:
# We couldn't find a keychain so we check if it's a special key. # We couldn't find a keychain so we check if it's a special key.
@ -172,6 +185,8 @@ class HintKeyParser(CommandKeyParser):
Emit: Emit:
fire_hint: Emitted if keytype is chain fire_hint: Emitted if keytype is chain
""" """
if not isinstance(keytype, self.Type):
raise TypeError("Type {} is no Type member!".format(keytype))
if keytype == self.Type.chain: if keytype == self.Type.chain:
self.fire_hint.emit(cmdstr) self.fire_hint.emit(cmdstr)
else: else:

View File

@ -91,6 +91,8 @@ def ask_async(message, mode, handler, default=None):
handler: The function to get called with the answer as argument. handler: The function to get called with the answer as argument.
default: The default value to display. default: The default value to display.
""" """
if not isinstance(mode, PromptMode):
raise TypeError("Mode {} is no PromptMode member!".format(mode))
bridge = instance() bridge = instance()
q = Question(bridge) q = Question(bridge)
q.text = message q.text = message

View File

@ -90,6 +90,8 @@ class NeighborList(collections.abc.Sequence):
Modes.wrap: Wrap around to the other end Modes.wrap: Wrap around to the other end
Modes.exception: Raise an IndexError. Modes.exception: Raise an IndexError.
""" """
if not isinstance(mode, self.Modes):
raise TypeError("Mode {} is not a Modes member!".format(mode))
if items is None: if items is None:
self._items = [] self._items = []
else: else:
@ -289,7 +291,7 @@ class Question(QObject):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.mode = None self._mode = None
self.default = None self.default = None
self.text = None self.text = None
self.user = None self.user = None
@ -299,6 +301,18 @@ class Question(QObject):
def __repr__(self): def __repr__(self):
return '<{} "{}">'.format(self.__class__.__name__, self.text) return '<{} "{}">'.format(self.__class__.__name__, self.text)
@property
def mode(self):
"""Getter for mode so we can define a setter."""
return self._mode
@mode.setter
def mode(self, val):
"""Setter for mode to do basic type checking."""
if not isinstance(val, PromptMode):
raise TypeError("Mode {} is no PromptMode member!".format(val))
self._mode = val
def done(self): def done(self):
"""Must be called when the queston was answered completely.""" """Must be called when the queston was answered completely."""
self.answered.emit(self.answer) self.answered.emit(self.answer)

View File

@ -101,6 +101,8 @@ class UrlText(TextBase):
@urltype.setter @urltype.setter
def urltype(self, val): def urltype(self, val):
"""Setter for self.urltype to update stylesheets after it is set.""" """Setter for self.urltype to update stylesheets after it is set."""
if not isinstance(val, UrlType):
raise TypeError("Type {} is no UrlType member!".format(val))
self._urltype = val self._urltype = val
self.setStyleSheet(get_stylesheet(self.STYLESHEET)) self.setStyleSheet(get_stylesheet(self.STYLESHEET))
@ -138,6 +140,8 @@ class UrlText(TextBase):
Args: Args:
val: The value as an UrlType instance. val: The value as an UrlType instance.
""" """
if not isinstance(val, UrlType):
raise TypeError("Type {} is no UrlType member!".format(val))
self._normal_url_type = val self._normal_url_type = val
self._update_url() self._update_url()

View File

@ -90,7 +90,8 @@ class WebView(QWebView):
def __init__(self, parent): def __init__(self, parent):
super().__init__(parent) super().__init__(parent)
self._load_status = LoadStatus.none self._load_status = None
self.load_status = LoadStatus.none
self._check_insertmode = False self._check_insertmode = False
self.tabbedbrowser = parent self.tabbedbrowser = parent
self.inspector = None self.inspector = None
@ -98,6 +99,7 @@ class WebView(QWebView):
self.statusbar_message = '' self.statusbar_message = ''
self._old_scroll_pos = (-1, -1) self._old_scroll_pos = (-1, -1)
self._shutdown_callback = None self._shutdown_callback = None
self._open_target = None
self.open_target = ClickTarget.normal self.open_target = ClickTarget.normal
self._force_open_target = None self._force_open_target = None
self._destroyed = {} self._destroyed = {}
@ -127,6 +129,18 @@ class WebView(QWebView):
url = self.url().toDisplayString() url = self.url().toDisplayString()
return "WebView(url='{}')".format(elide(url, 50)) return "WebView(url='{}')".format(elide(url, 50))
@property
def open_target(self):
"""Getter for open_target so we can define a setter."""
return self._open_target
@open_target.setter
def open_target(self, val):
"""Setter for open_target to do type checking."""
if not isinstance(val, ClickTarget):
raise TypeError("Target {} is no ClickTarget member!".format(val))
self._open_target = val
@property @property
def load_status(self): def load_status(self):
"""Getter for load_status.""" """Getter for load_status."""
@ -139,6 +153,8 @@ class WebView(QWebView):
Emit: Emit:
load_status_changed load_status_changed
""" """
if not isinstance(val, LoadStatus):
raise TypeError("Type {} is no LoadStatus member!".format(val))
log.webview.debug("load status for {}: {}".format(repr(self), val)) log.webview.debug("load status for {}: {}".format(repr(self), val))
self._load_status = val self._load_status = val
self.load_status_changed.emit(val.name) self.load_status_changed.emit(val.name)