From c8fd0937b0f4b695d8c3b6838884f21f14339ffd Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 5 May 2014 20:12:20 +0200 Subject: [PATCH] Revert "Use global object dict for global objects" This reverts commit bf2c7831c816c0271712910c740c3011905c740c. This was a bad idea as we need to access some of the main attributes from commands via instance=... --- qutebrowser/app.py | 118 ++++++++++++++----------- qutebrowser/browser/webpage.py | 3 +- qutebrowser/commands/_command.py | 2 +- qutebrowser/config/config.py | 2 +- qutebrowser/keyinput/modeman.py | 2 +- qutebrowser/models/cmdhistory.py | 2 +- qutebrowser/test/test_immutabledict.py | 44 --------- qutebrowser/utils/message.py | 2 +- qutebrowser/utils/usertypes.py | 10 --- qutebrowser/widgets/mainwindow.py | 6 +- qutebrowser/widgets/webview.py | 2 +- 11 files changed, 74 insertions(+), 119 deletions(-) delete mode 100644 qutebrowser/test/test_immutabledict.py diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 348d3fb57..563785a2c 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -64,7 +64,6 @@ from qutebrowser.browser.cookies import CookieJar from qutebrowser.utils.message import MessageBridge from qutebrowser.utils.appdirs import AppDirs from qutebrowser.utils.misc import dotted_getattr -from qutebrowser.utils.usertypes import ImmutableDict from qutebrowser.utils.debug import set_trace # pylint: disable=unused-import @@ -79,7 +78,15 @@ class QuteBrowser(QApplication): Attributes: mainwindow: The MainWindow QWidget. - obj: Dictionary containing global singleton objects. + commandmanager: The main CommandManager instance. + searchmanager: The main SearchManager instance. + config: The main ConfigManager + stateconfig: The "state" ReadWriteConfigParser instance. + cmd_history: The "cmd_history" LineConfigParser instance. + messagebridge: The global MessageBridge instance. + modeman: The global ModeManager instance. + networkmanager: The global NetworkManager instance. + cookiejar: The global CookieJar instance. _keyparsers: A mapping from modes to keyparsers. _dirs: AppDirs instance for config/cache directories. _args: ArgumentParser instance. @@ -89,6 +96,9 @@ class QuteBrowser(QApplication): _opened_urls: List of opened URLs. """ + # This also holds all our globals, so we're a bit over the top here. + # pylint: disable=too-many-instance-attributes + def __init__(self): super().__init__(sys.argv) self._quit_status = {} @@ -97,7 +107,11 @@ class QuteBrowser(QApplication): self._shutting_down = False self._keyparsers = None self._dirs = None - self.obj = ImmutableDict() + self.messagebridge = None + self.stateconfig = None + self.modeman = None + self.cmd_history = None + self.config = None sys.excepthook = self._exception_hook @@ -107,18 +121,18 @@ class QuteBrowser(QApplication): self._init_config() self._init_modes() websettings.init(self._dirs.user_cache_dir) - self.obj['cookiejar'] = CookieJar(self._dirs.user_data_dir) - self.obj['networkmanager'] = NetworkManager(self.obj['cookiejar']) - self.obj['commandmanager'] = CommandManager() - self.obj['searchmanager'] = SearchManager() + self.cookiejar = CookieJar(self._dirs.user_data_dir) + self.networkmanager = NetworkManager(self.cookiejar) + self.commandmanager = CommandManager() + self.searchmanager = SearchManager() self._init_cmds() self.mainwindow = MainWindow() - self.installEventFilter(self.obj['modeman']) + self.installEventFilter(self.modeman) self.setQuitOnLastWindowClosed(False) self._connect_signals() - self.obj['modeman'].enter('normal') + self.modeman.enter('normal') self.mainwindow.show() self._python_hacks() @@ -154,7 +168,7 @@ class QuteBrowser(QApplication): else: confdir = self._args.confdir try: - self.obj['config'] = ConfigManager(confdir, 'qutebrowser.conf') + self.config = ConfigManager(confdir, 'qutebrowser.conf') except (config.ValidationError, config.NoOptionError, configparser.InterpolationError, @@ -171,9 +185,9 @@ class QuteBrowser(QApplication): msgbox.exec_() # We didn't really initialize much so far, so we just quit hard. sys.exit(1) - self.obj['stateconfig'] = ReadWriteConfigParser(confdir, 'state') - self.obj['cmd_history'] = LineConfigParser( - confdir, 'cmd_history', ('completion', 'history-length')) + self.stateconfig = ReadWriteConfigParser(confdir, 'state') + self.cmd_history = LineConfigParser(confdir, 'cmd_history', + ('completion', 'history-length')) def _init_modes(self): """Inizialize the mode manager and the keyparsers.""" @@ -184,16 +198,16 @@ class QuteBrowser(QApplication): 'passthrough': PassthroughKeyParser('keybind.passthrough', self), 'command': PassthroughKeyParser('keybind.command', self), } - modeman = ModeManager() - modeman.register('normal', self._keyparsers['normal'].handle) - modeman.register('hint', self._keyparsers['hint'].handle) - modeman.register('insert', self._keyparsers['insert'].handle, - passthrough=True) - modeman.register('passthrough', self._keyparsers['passthrough'].handle, - passthrough=True) - modeman.register('command', self._keyparsers['command'].handle, - passthrough=True) - self.obj['modeman'] = modeman + self.modeman = ModeManager() + self.modeman.register('normal', self._keyparsers['normal'].handle) + self.modeman.register('hint', self._keyparsers['hint'].handle) + self.modeman.register('insert', self._keyparsers['insert'].handle, + passthrough=True) + self.modeman.register('passthrough', + self._keyparsers['passthrough'].handle, + passthrough=True) + self.modeman.register('command', self._keyparsers['command'].handle, + passthrough=True) def _init_log(self): """Initialisation of the logging output. @@ -217,7 +231,7 @@ class QuteBrowser(QApplication): os.environ['QT_FATAL_WARNINGS'] = '1' self.setApplicationName("qutebrowser") self.setApplicationVersion(qutebrowser.__version__) - self.obj['messagebridge'] = MessageBridge() + self.messagebridge = MessageBridge() def _init_cmds(self): """Initialisation of the qutebrowser commands. @@ -246,7 +260,7 @@ class QuteBrowser(QApplication): for e in self._args.command: if e.startswith(':'): logging.debug("Startup cmd {}".format(e)) - self.obj['commandmanager'].run_safely(e.lstrip(':')) + self.commandmanager.run_safely(e.lstrip(':')) else: logging.debug("Startup url {}".format(e)) self._opened_urls.append(e) @@ -254,7 +268,7 @@ class QuteBrowser(QApplication): if self.mainwindow.tabs.count() == 0: logging.debug("Opening startpage") - for url in self.obj['config'].get('general', 'startpage'): + for url in self.config.get('general', 'startpage'): self.mainwindow.tabs.tabopen(url) def _python_hacks(self): @@ -278,10 +292,6 @@ class QuteBrowser(QApplication): completion = self.mainwindow.completion tabs = self.mainwindow.tabs cmd = self.mainwindow.status.cmd - searchmanager = self.obj['searchmanager'] - conf = self.obj['config'] - messagebridge = self.obj['messagebridge'] - modeman = self.obj['modeman'] # misc self.lastWindowClosed.connect(self.shutdown) @@ -289,17 +299,17 @@ class QuteBrowser(QApplication): tabs.currentChanged.connect(self.mainwindow.update_inspector) # status bar - modeman.entered.connect(status.on_mode_entered) - modeman.left.connect(status.on_mode_left) - modeman.left.connect(status.cmd.on_mode_left) - modeman.key_pressed.connect(status.on_key_pressed) + self.modeman.entered.connect(status.on_mode_entered) + self.modeman.left.connect(status.on_mode_left) + self.modeman.left.connect(status.cmd.on_mode_left) + self.modeman.key_pressed.connect(status.on_key_pressed) # commands - cmd.got_cmd.connect(self.obj['commandmanager'].run_safely) - cmd.got_search.connect(searchmanager.search) - cmd.got_search_rev.connect(searchmanager.search_rev) + cmd.got_cmd.connect(self.commandmanager.run_safely) + cmd.got_search.connect(self.searchmanager.search) + cmd.got_search_rev.connect(self.searchmanager.search_rev) cmd.returnPressed.connect(tabs.setFocus) - searchmanager.do_search.connect(tabs.cur.search) + self.searchmanager.do_search.connect(tabs.cur.search) kp['normal'].keystring_updated.connect(status.keystring.setText) # hints @@ -309,16 +319,16 @@ class QuteBrowser(QApplication): tabs.hint_strings_updated.connect(kp['hint'].on_hint_strings_updated) # messages - messagebridge.error.connect(status.disp_error) - messagebridge.info.connect(status.txt.set_temptext) - messagebridge.text.connect(status.txt.set_normaltext) - messagebridge.set_cmd_text.connect(cmd.set_cmd_text) + self.messagebridge.error.connect(status.disp_error) + self.messagebridge.info.connect(status.txt.set_temptext) + self.messagebridge.text.connect(status.txt.set_normaltext) + self.messagebridge.set_cmd_text.connect(cmd.set_cmd_text) # config - conf.style_changed.connect(style.invalidate_caches) - for obj in [tabs, completion, self.mainwindow, self.obj['cmd_history'], - websettings, kp['normal'], modeman]: - conf.changed.connect(obj.on_config_changed) + self.config.style_changed.connect(style.invalidate_caches) + for obj in [tabs, completion, self.mainwindow, self.cmd_history, + websettings, kp['normal'], self.modeman]: + self.config.changed.connect(obj.on_config_changed) # statusbar tabs.cur_progress.connect(status.prog.setValue) @@ -331,7 +341,7 @@ class QuteBrowser(QApplication): tabs.cur_link_hovered.connect(status.url.set_hover_url) # command input / completion - modeman.left.connect(tabs.on_mode_left) + self.modeman.left.connect(tabs.on_mode_left) cmd.clear_completion_selection.connect( completion.on_clear_completion_selection) cmd.hide_completion.connect(completion.hide) @@ -364,10 +374,10 @@ class QuteBrowser(QApplication): """Save the window geometry to the state config.""" geom = b64encode(bytes(self.mainwindow.saveGeometry())).decode('ASCII') try: - self.obj['stateconfig'].add_section('geometry') + self.stateconfig.add_section('geometry') except configparser.DuplicateSectionError: pass - self.obj['stateconfig']['geometry']['mainwindow'] = geom + self.stateconfig['geometry']['mainwindow'] = geom def _exception_hook(self, exctype, excvalue, tb): """Handle uncaught python exceptions. @@ -484,22 +494,22 @@ class QuteBrowser(QApplication): return self._shutting_down = True logging.debug("Shutting down... (do_quit={})".format(do_quit)) - if self.obj['config'].get('general', 'auto-save-config'): + if self.config.get('general', 'auto-save-config'): try: - self.obj['config'].save() + self.config.save() except AttributeError: logging.exception("Could not save config.") try: - self.obj['cmd_history'].save() + self.cmd_history.save() except AttributeError: logging.exception("Could not save command history.") try: self._save_geometry() - self.obj['stateconfig'].save() + self.stateconfig.save() except AttributeError: logging.exception("Could not save window geometry.") try: - self.obj['cookiejar'].save() + self.cookiejar.save() except AttributeError: logging.exception("Could not save cookies.") try: diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index cf485f308..03b65d5a6 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -41,8 +41,7 @@ class BrowserPage(QWebPage): self._extension_handlers = { QWebPage.ErrorPageExtension: self._handle_errorpage, } - netman = QApplication.instance().obj['networkmanager'] - self.setNetworkAccessManager(netman) + self.setNetworkAccessManager(QApplication.instance().networkmanager) def _handle_errorpage(self, opt, out): """Display an error page if needed. diff --git a/qutebrowser/commands/_command.py b/qutebrowser/commands/_command.py index bb47a1e1d..57a83d087 100644 --- a/qutebrowser/commands/_command.py +++ b/qutebrowser/commands/_command.py @@ -85,7 +85,7 @@ class Command(QObject): """ # We don't use modeman.instance() here to avoid a circular import # of qutebrowser.keyinput.modeman. - curmode = QApplication.instance().obj['modeman'].mode + curmode = QApplication.instance().modeman.mode if self.modes is not None and curmode not in self.modes: raise PrerequisitesError("{}: This command is only allowed in {} " "mode.".format(self.name, diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 6d913d68d..ae11aa84e 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -42,7 +42,7 @@ from qutebrowser.config._conftypes import ValidationError def instance(): """Get the global config instance.""" - return QApplication.instance().obj['config'] + return QApplication.instance().config def get(*args, **kwargs): diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py index 2e9b18fce..db62ccb18 100644 --- a/qutebrowser/keyinput/modeman.py +++ b/qutebrowser/keyinput/modeman.py @@ -34,7 +34,7 @@ import qutebrowser.utils.debug as debug def instance(): """Get the global modeman instance.""" - return QApplication.instance().obj['modeman'] + return QApplication.instance().modeman def enter(mode): diff --git a/qutebrowser/models/cmdhistory.py b/qutebrowser/models/cmdhistory.py index 6f6f6ea4c..a410a0299 100644 --- a/qutebrowser/models/cmdhistory.py +++ b/qutebrowser/models/cmdhistory.py @@ -51,7 +51,7 @@ class History: def __init__(self): self._tmphist = None - history = QApplication.instance().obj['cmd_history'].data + history = QApplication.instance().cmd_history.data if history is None: self._history = [] else: diff --git a/qutebrowser/test/test_immutabledict.py b/qutebrowser/test/test_immutabledict.py deleted file mode 100644 index 6aca6d9dd..000000000 --- a/qutebrowser/test/test_immutabledict.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2014 Florian Bruhin (The Compiler) -# -# This file is part of qutebrowser. -# -# qutebrowser is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# qutebrowser is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with qutebrowser. If not, see . - -# pylint: disable=missing-docstring - -"""Tests for the FakeDict class.""" - -import unittest -from unittest import TestCase - -from qutebrowser.utils.usertypes import ImmutableDict - - -class ImmutableDictTests(TestCase): - - """Test the ImmutableDict usertype.""" - - def setUp(self): - self.d = ImmutableDict() - - def test_setitem(self): - self.d['foo'] = 'bar' - self.assertEqual(self.d['foo'], 'bar') - with self.assertRaises(ValueError): - self.d['foo'] = 'baz' - self.assertEqual(self.d['foo'], 'bar') - - -if __name__ == '__main__': - unittest.main() diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py index 1486e6c03..22292a373 100644 --- a/qutebrowser/utils/message.py +++ b/qutebrowser/utils/message.py @@ -23,7 +23,7 @@ from PyQt5.QtWidgets import QApplication def instance(): """Get the global messagebridge instance.""" - return QApplication.instance().obj['messagebridge'] + return QApplication.instance().messagebridge def error(message): diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 94d0113ce..a67a24e49 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -182,13 +182,3 @@ class FakeDict: def __getitem__(self, _key): return self._val - - -class ImmutableDict(dict): - - """Dict where items only can be set once.""" - - def __setitem__(self, key, value): - if key in self: - raise ValueError("Key {} already has been set.".format(key)) - super().__setitem__(key, value) diff --git a/qutebrowser/widgets/mainwindow.py b/qutebrowser/widgets/mainwindow.py index 6f45daedd..c5a75bb84 100644 --- a/qutebrowser/widgets/mainwindow.py +++ b/qutebrowser/widgets/mainwindow.py @@ -49,10 +49,10 @@ class MainWindow(QWidget): super().__init__() self.setWindowTitle('qutebrowser') - stateconfig = QApplication.instance().obj['stateconfig'] try: - geom = b64decode(stateconfig['geometry']['mainwindow'], - validate=True) + geom = b64decode( + QApplication.instance().stateconfig['geometry']['mainwindow'], + validate=True) except (KeyError, binascii.Error): self._set_default_geometry() else: diff --git a/qutebrowser/widgets/webview.py b/qutebrowser/widgets/webview.py index f3be69f78..8d4b7d830 100644 --- a/qutebrowser/widgets/webview.py +++ b/qutebrowser/widgets/webview.py @@ -209,7 +209,7 @@ class WebView(QWebView): self.destroyed.connect(functools.partial(self._on_destroyed, self)) self.deleteLater() - netman = QApplication.instance().obj['networkmanager'] + netman = QApplication.instance().networkmanager self._destroyed[netman] = False netman.abort_requests() netman.destroyed.connect(functools.partial(self._on_destroyed, netman))