From 62dd08f6d6c2ce97272286b6af3e1bc42abd29af Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 9 Oct 2019 23:28:33 +0200 Subject: Add type annotations for keyinput.modeman --- qutebrowser/keyinput/modeman.py | 82 +++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 39 deletions(-) (limited to 'qutebrowser/keyinput/modeman.py') diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py index 22f5500a4..df61cd369 100644 --- a/qutebrowser/keyinput/modeman.py +++ b/qutebrowser/keyinput/modeman.py @@ -20,13 +20,15 @@ """Mode manager singleton which handles the current keyboard mode.""" import functools +import typing import attr from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QObject, QEvent +from PyQt5.QtGui import QKeyEvent from PyQt5.QtWidgets import QApplication from qutebrowser.commands import runners -from qutebrowser.keyinput import modeparsers +from qutebrowser.keyinput import modeparsers, basekeyparser from qutebrowser.config import config from qutebrowser.api import cmdutils from qutebrowser.utils import usertypes, log, objreg, utils @@ -35,6 +37,9 @@ from qutebrowser.browser import hints INPUT_MODES = [usertypes.KeyMode.insert, usertypes.KeyMode.passthrough] PROMPT_MODES = [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno] +_ParserDictType = typing.MutableMapping[ + usertypes.KeyMode, basekeyparser.BaseKeyParser] + @attr.s(frozen=True) class KeyEvent: @@ -50,13 +55,13 @@ class KeyEvent: text: A string (QKeyEvent::text). """ - key = attr.ib() - text = attr.ib() + key = attr.ib() # type: Qt.Key + text = attr.ib() # type: str @classmethod - def from_event(cls, event): + def from_event(cls, event: QKeyEvent) -> 'KeyEvent': """Initialize a KeyEvent from a QKeyEvent.""" - return cls(event.key(), event.text()) + return cls(Qt.Key(event.key()), event.text()) class NotInModeError(Exception): @@ -64,7 +69,7 @@ class NotInModeError(Exception): """Exception raised when we want to leave a mode we're not in.""" -def init(win_id, parent): +def init(win_id: int, parent: QObject) -> 'ModeManager': """Initialize the mode manager and the keyparsers for the given win_id.""" modeman = ModeManager(win_id, parent) objreg.register('mode-manager', modeman, scope='window', window=win_id) @@ -121,9 +126,9 @@ def init(win_id, parent): modeparsers.RegisterKeyParser( win_id=win_id, mode=usertypes.KeyMode.run_macro, commandrunner=commandrunner, parent=modeman), - } + } # type: _ParserDictType objreg.register('keyparsers', keyparsers, scope='window', window=win_id) - modeman.destroyed.connect( + modeman.destroyed.connect( # type: ignore functools.partial(objreg.delete, 'keyparsers', scope='window', window=win_id)) for mode, parser in keyparsers.items(): @@ -131,17 +136,23 @@ def init(win_id, parent): return modeman -def instance(win_id): +def instance(win_id: int) -> 'ModeManager': """Get a modemanager object.""" return objreg.get('mode-manager', scope='window', window=win_id) -def enter(win_id, mode, reason=None, only_if_normal=False): +def enter(win_id: int, + mode: usertypes.KeyMode, + reason: str = None, + only_if_normal: bool = False) -> None: """Enter the mode 'mode'.""" instance(win_id).enter(mode, reason, only_if_normal) -def leave(win_id, mode, reason=None, *, maybe=False): +def leave(win_id: int, + mode: usertypes.KeyMode, + reason: str = None, *, + maybe: bool = False) -> None: """Leave the mode 'mode'.""" instance(win_id).leave(mode, reason, maybe=maybe) @@ -173,18 +184,19 @@ class ModeManager(QObject): entered = pyqtSignal(usertypes.KeyMode, int) left = pyqtSignal(usertypes.KeyMode, usertypes.KeyMode, int) - def __init__(self, win_id, parent=None): + def __init__(self, win_id: int, parent: QObject = None) -> None: super().__init__(parent) self._win_id = win_id - self._parsers = {} + self._parsers = {} # type: _ParserDictType self._prev_mode = usertypes.KeyMode.normal self.mode = usertypes.KeyMode.normal - self._releaseevents_to_pass = set() + self._releaseevents_to_pass = set() # type: typing.Set[KeyEvent] - def __repr__(self): + def __repr__(self) -> str: return utils.get_repr(self, mode=self.mode) - def _handle_keypress(self, event, *, dry_run=False): + def _handle_keypress(self, event: QKeyEvent, *, + dry_run: bool = False) -> bool: """Handle filtering of KeyPress events. Args: @@ -228,7 +240,7 @@ class ModeManager(QObject): filter_this, focus_widget)) return filter_this - def _handle_keyrelease(self, event): + def _handle_keyrelease(self, event: QKeyEvent) -> bool: """Handle filtering of KeyRelease events. Args: @@ -248,19 +260,16 @@ class ModeManager(QObject): log.modes.debug("filter: {}".format(filter_this)) return filter_this - def register(self, mode, parser): - """Register a new mode. - - Args: - mode: The name of the mode. - parser: The KeyParser which should be used. - """ - assert isinstance(mode, usertypes.KeyMode) + def register(self, mode: usertypes.KeyMode, + parser: basekeyparser.BaseKeyParser) -> None: + """Register a new mode.""" assert parser is not None self._parsers[mode] = parser parser.request_leave.connect(self.leave) - def enter(self, mode, reason=None, only_if_normal=False): + def enter(self, mode: usertypes.KeyMode, + reason: str = None, + only_if_normal: bool = False) -> None: """Enter a new mode. Args: @@ -268,9 +277,6 @@ class ModeManager(QObject): reason: Why the mode was entered. only_if_normal: Only enter the new mode if we're in normal mode. """ - if not isinstance(mode, usertypes.KeyMode): - raise TypeError("Mode {} is no KeyMode member!".format(mode)) - if mode == usertypes.KeyMode.normal: self.leave(self.mode, reason='enter normal: {}'.format(reason)) return @@ -302,7 +308,7 @@ class ModeManager(QObject): self.entered.emit(mode, self._win_id) @cmdutils.register(instance='mode-manager', scope='window') - def enter_mode(self, mode): + def enter_mode(self, mode: str) -> None: """Enter a key mode. Args: @@ -323,7 +329,9 @@ class ModeManager(QObject): self.enter(m, 'command') @pyqtSlot(usertypes.KeyMode, str, bool) - def leave(self, mode, reason=None, maybe=False): + def leave(self, mode: usertypes.KeyMode, + reason: str = None, + maybe: bool = False) -> None: """Leave a key mode. Args: @@ -353,13 +361,13 @@ class ModeManager(QObject): @cmdutils.register(instance='mode-manager', name='leave-mode', not_modes=[usertypes.KeyMode.normal], scope='window') - def leave_current_mode(self): + def leave_current_mode(self) -> None: """Leave the mode we're currently in.""" if self.mode == usertypes.KeyMode.normal: raise ValueError("Can't leave normal mode!") self.leave(self.mode, 'leave current') - def handle_event(self, event): + def handle_event(self, event: QEvent) -> bool: """Filter all events based on the currently set mode. Also calls the real keypress handler. @@ -370,20 +378,16 @@ class ModeManager(QObject): Return: True if event should be filtered, False otherwise. """ - if self.mode is None: - # We got events before mode is set, so just pass them through. - return False - handlers = { QEvent.KeyPress: self._handle_keypress, QEvent.KeyRelease: self._handle_keyrelease, QEvent.ShortcutOverride: functools.partial(self._handle_keypress, dry_run=True), - } + } # type: typing.Mapping[QEvent.Type, typing.Callable[[QEvent], bool]] handler = handlers[event.type()] return handler(event) @cmdutils.register(instance='mode-manager', scope='window') - def clear_keychain(self): + def clear_keychain(self) -> None: """Clear the currently entered key chain.""" self._parsers[self.mode].clear_keystring() -- cgit v1.2.3-54-g00ecf