diff --git a/doc/HACKING.asciidoc b/doc/HACKING.asciidoc index 76e7f0fe7..06845720d 100644 --- a/doc/HACKING.asciidoc +++ b/doc/HACKING.asciidoc @@ -289,7 +289,7 @@ or [source,python] ---- -import qutebrowser.utils.log as log +from qutebrowser.utils import log ... log.foo.debug("Hello World") ---- diff --git a/qutebrowser/__main__.py b/qutebrowser/__main__.py index 064a64281..fb8436df5 100644 --- a/qutebrowser/__main__.py +++ b/qutebrowser/__main__.py @@ -20,9 +20,10 @@ """Entry point for qutebrowser. Simply execute qutebrowser.""" -import qutebrowser.qutebrowser import sys +import qutebrowser.qutebrowser + if __name__ == '__main__': sys.exit(qutebrowser.qutebrowser.main()) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index d9f880d8f..d4a1d094f 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -26,46 +26,28 @@ import faulthandler import configparser import signal import warnings -from bdb import BdbQuit -from base64 import b64encode -from functools import partial +import bdb +import base64 +import functools from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox from PyQt5.QtCore import (pyqtSlot, QTimer, QEventLoop, Qt, QStandardPaths, qInstallMessageHandler, QObject, QUrl) import qutebrowser -import qutebrowser.commands.utils as cmdutils -import qutebrowser.config.style as style -import qutebrowser.config.config as config -import qutebrowser.network.qutescheme as qutescheme -import qutebrowser.config.websettings as websettings -import qutebrowser.network.proxy as proxy -import qutebrowser.browser.quickmarks as quickmarks -import qutebrowser.utils.log as log -import qutebrowser.utils.version as version -import qutebrowser.utils.url as urlutils -import qutebrowser.utils.message as message -import qutebrowser.commands.userscripts as userscripts -import qutebrowser.utils.utilcmds as utilcmds -from qutebrowser.config.config import ConfigManager -from qutebrowser.keyinput.modeman import ModeManager -from qutebrowser.widgets.mainwindow import MainWindow -from qutebrowser.widgets.console import ConsoleWidget -from qutebrowser.widgets.crash import (ExceptionCrashDialog, FatalCrashDialog, - ReportDialog) -from qutebrowser.keyinput.modeparsers import (NormalKeyParser, HintKeyParser, - PromptKeyParser) -from qutebrowser.keyinput.keyparser import PassthroughKeyParser -from qutebrowser.commands.runners import CommandRunner, SearchRunner -from qutebrowser.config.iniparsers import ReadWriteConfigParser -from qutebrowser.config.lineparser import LineConfigParser -from qutebrowser.browser.cookies import CookieJar -from qutebrowser.browser.downloads import DownloadManager -from qutebrowser.utils.misc import get_standard_dir, actute_warning -from qutebrowser.utils.qt import get_qt_args -from qutebrowser.utils.readline import ReadlineBridge -from qutebrowser.utils.usertypes import Timer, KeyMode +from qutebrowser.commands import userscripts, runners +from qutebrowser.commands import utils as cmdutils +from qutebrowser.config import (style, config, websettings, iniparsers, + lineparser, conftypes) +from qutebrowser.network import qutescheme, proxy +from qutebrowser.browser import quickmarks, cookies, downloads +from qutebrowser.widgets import mainwindow, console, crash +from qutebrowser.keyinput import modeparsers, keyparser, modeman +from qutebrowser.utils import log, version, message, utilcmds, readline +from qutebrowser.utils import url as urlutils +from qutebrowser.utils import misc as utils +from qutebrowser.utils import qt as qtutils +from qutebrowser.utils import usertypes as utypes class Application(QApplication): @@ -104,9 +86,9 @@ class Application(QApplication): # We don't enable this earlier because some imports trigger # warnings (which are not our fault). warnings.simplefilter('default') - qt_args = get_qt_args(args) + qt_args = qtutils.get_qt_args(args) log.init.debug("Qt arguments: {}, based on {}".format(qt_args, args)) - super().__init__(get_qt_args(args)) + super().__init__(qt_args) self._quit_status = { 'crash': True, 'tabs': False, @@ -129,7 +111,7 @@ class Application(QApplication): self.args = args log.init.debug("Starting init...") self._init_misc() - actute_warning() + utils.actute_warning() log.init.debug("Initializing config...") self._init_config() log.init.debug("Initializing crashlog...") @@ -147,25 +129,25 @@ class Application(QApplication): log.init.debug("Initializing utility commands...") utilcmds.init() log.init.debug("Initializing cookies...") - self.cookiejar = CookieJar(self) + self.cookiejar = cookies.CookieJar(self) log.init.debug("Initializing commands...") - self.commandrunner = CommandRunner() + self.commandrunner = runners.CommandRunner() log.init.debug("Initializing search...") - self.searchrunner = SearchRunner(self) + self.searchrunner = runners.SearchRunner(self) log.init.debug("Initializing downloads...") - self.downloadmanager = DownloadManager(self) + self.downloadmanager = downloads.DownloadManager(self) log.init.debug("Initializing main window...") - self.mainwindow = MainWindow() + self.mainwindow = mainwindow.MainWindow() self.modeman.mainwindow = self.mainwindow log.init.debug("Initializing debug console...") - self.debugconsole = ConsoleWidget() + self.debugconsole = console.ConsoleWidget() log.init.debug("Initializing eventfilter...") self.installEventFilter(self.modeman) self.setQuitOnLastWindowClosed(False) log.init.debug("Connecting signals...") self._connect_signals() - self.modeman.enter(KeyMode.normal, 'init') + self.modeman.enter(utypes.KeyMode.normal, 'init') log.init.debug("Showing mainwindow...") if not args.nowindow: @@ -183,14 +165,15 @@ class Application(QApplication): def _init_config(self): """Inizialize and read the config.""" if self.args.confdir is None: - confdir = get_standard_dir(QStandardPaths.ConfigLocation) + confdir = utils.get_standard_dir(QStandardPaths.ConfigLocation) elif self.args.confdir == '': confdir = None else: confdir = self.args.confdir try: - self.config = ConfigManager(confdir, 'qutebrowser.conf', self) - except (config.ValidationError, + self.config = config.ConfigManager(confdir, 'qutebrowser.conf', + self) + except (conftypes.ValidationError, config.NoOptionError, config.InterpolationSyntaxError, configparser.InterpolationError, @@ -207,47 +190,49 @@ class Application(QApplication): msgbox.exec_() # We didn't really initialize much so far, so we just quit hard. sys.exit(1) - self.stateconfig = ReadWriteConfigParser(confdir, 'state') - self.cmd_history = LineConfigParser(confdir, 'cmd_history', - ('completion', 'history-length')) + self.stateconfig = iniparsers.ReadWriteConfigParser(confdir, 'state') + self.cmd_history = lineparser.LineConfigParser( + confdir, 'cmd_history', ('completion', 'history-length')) def _init_modes(self): """Inizialize the mode manager and the keyparsers.""" self._keyparsers = { - KeyMode.normal: - NormalKeyParser(self), - KeyMode.hint: - HintKeyParser(self), - KeyMode.insert: - PassthroughKeyParser('keybind.insert', self), - KeyMode.passthrough: - PassthroughKeyParser('keybind.passthrough', self), - KeyMode.command: - PassthroughKeyParser('keybind.command', self), - KeyMode.prompt: - PassthroughKeyParser('keybind.prompt', self, warn=False), - KeyMode.yesno: - PromptKeyParser(self), + utypes.KeyMode.normal: + modeparsers.NormalKeyParser(self), + utypes.KeyMode.hint: + modeparsers.HintKeyParser(self), + utypes.KeyMode.insert: + keyparser.PassthroughKeyParser('keybind.insert', self), + utypes.KeyMode.passthrough: + keyparser.PassthroughKeyParser('keybind.passthrough', self), + utypes.KeyMode.command: + keyparser.PassthroughKeyParser('keybind.command', self), + utypes.KeyMode.prompt: + keyparser.PassthroughKeyParser('keybind.prompt', self, + warn=False), + utypes.KeyMode.yesno: + modeparsers.PromptKeyParser(self), } - self.modeman = ModeManager(self) - self.modeman.register(KeyMode.normal, - self._keyparsers[KeyMode.normal].handle) - self.modeman.register(KeyMode.hint, - self._keyparsers[KeyMode.hint].handle) - self.modeman.register(KeyMode.insert, - self._keyparsers[KeyMode.insert].handle, + self.modeman = modeman.ModeManager(self) + self.modeman.register(utypes.KeyMode.normal, + self._keyparsers[utypes.KeyMode.normal].handle) + self.modeman.register(utypes.KeyMode.hint, + self._keyparsers[utypes.KeyMode.hint].handle) + self.modeman.register(utypes.KeyMode.insert, + self._keyparsers[utypes.KeyMode.insert].handle, passthrough=True) - self.modeman.register(KeyMode.passthrough, - self._keyparsers[KeyMode.passthrough].handle, + self.modeman.register( + utypes.KeyMode.passthrough, + self._keyparsers[utypes.KeyMode.passthrough].handle, + passthrough=True) + self.modeman.register(utypes.KeyMode.command, + self._keyparsers[utypes.KeyMode.command].handle, passthrough=True) - self.modeman.register(KeyMode.command, - self._keyparsers[KeyMode.command].handle, + self.modeman.register(utypes.KeyMode.prompt, + self._keyparsers[utypes.KeyMode.prompt].handle, passthrough=True) - self.modeman.register(KeyMode.prompt, - self._keyparsers[KeyMode.prompt].handle, - passthrough=True) - self.modeman.register(KeyMode.yesno, - self._keyparsers[KeyMode.yesno].handle) + self.modeman.register(utypes.KeyMode.yesno, + self._keyparsers[utypes.KeyMode.yesno].handle) def _init_misc(self): """Initialize misc things.""" @@ -263,7 +248,7 @@ class Application(QApplication): self.setApplicationName("qutebrowser") self.setApplicationVersion(qutebrowser.__version__) self.messagebridge = message.MessageBridge(self) - self.rl_bridge = ReadlineBridge() + self.rl_bridge = readline.ReadlineBridge() def _handle_segfault(self): """Handle a segfault from a previous run.""" @@ -272,8 +257,8 @@ class Application(QApplication): # However this also means if the logfile is there for some weird # reason, we'll *always* log to stderr, but that's still better than no # dialogs at all. - logname = os.path.join(get_standard_dir(QStandardPaths.DataLocation), - 'crash.log') + path = utils.get_standard_dir(QStandardPaths.DataLocation) + logname = os.path.join(path, 'crash.log') # First check if an old logfile exists. if os.path.exists(logname): with open(logname, 'r', encoding='ascii') as f: @@ -287,7 +272,7 @@ class Application(QApplication): log.init.warning("Could not remove crash log!") else: self._init_crashlogfile() - self._crashdlg = FatalCrashDialog(data) + self._crashdlg = crash.FatalCrashDialog(data) self._crashdlg.show() else: # Crashlog exists but without data. @@ -307,8 +292,8 @@ class Application(QApplication): def _init_crashlogfile(self): """Start a new logfile and redirect faulthandler to it.""" - logname = os.path.join(get_standard_dir(QStandardPaths.DataLocation), - 'crash.log') + path = utils.get_standard_dir(QStandardPaths.DataLocation) + logname = os.path.join(path, 'crash.log') self._crashlogfile = open(logname, 'w', encoding='ascii') faulthandler.enable(self._crashlogfile) if (hasattr(faulthandler, 'register') and @@ -360,7 +345,7 @@ class Application(QApplication): """ signal.signal(signal.SIGINT, self.interrupt) signal.signal(signal.SIGTERM, self.interrupt) - timer = Timer(self, 'python_hacks') + timer = utypes.Timer(self, 'python_hacks') timer.start(500) timer.timeout.connect(lambda: None) self._timers.append(timer) @@ -392,15 +377,16 @@ class Application(QApplication): cmd.got_search_rev.connect(self.searchrunner.search_rev) cmd.returnPressed.connect(tabs.setFocus) self.searchrunner.do_search.connect(tabs.search) - kp[KeyMode.normal].keystring_updated.connect(status.keystring.setText) + kp[utypes.KeyMode.normal].keystring_updated.connect( + status.keystring.setText) tabs.got_cmd.connect(self.commandrunner.run_safely) # hints - kp[KeyMode.hint].fire_hint.connect(tabs.fire_hint) - kp[KeyMode.hint].filter_hints.connect(tabs.filter_hints) - kp[KeyMode.hint].keystring_updated.connect(tabs.handle_hint_key) + kp[utypes.KeyMode.hint].fire_hint.connect(tabs.fire_hint) + kp[utypes.KeyMode.hint].filter_hints.connect(tabs.filter_hints) + kp[utypes.KeyMode.hint].keystring_updated.connect(tabs.handle_hint_key) tabs.hint_strings_updated.connect( - kp[KeyMode.hint].on_hint_strings_updated) + kp[utypes.KeyMode.hint].on_hint_strings_updated) # messages self.messagebridge.s_error.connect(status.disp_error) @@ -413,8 +399,8 @@ class Application(QApplication): # config self.config.style_changed.connect(style.invalidate_caches) for obj in (tabs, completion, self.mainwindow, self.cmd_history, - websettings, kp[KeyMode.normal], self.modeman, status, - status.txt): + websettings, kp[utypes.KeyMode.normal], self.modeman, + status, status.txt): self.config.changed.connect(obj.on_config_changed) # statusbar @@ -498,7 +484,8 @@ class Application(QApplication): def _save_geometry(self): """Save the window geometry to the state config.""" - geom = b64encode(bytes(self.mainwindow.saveGeometry())).decode('ASCII') + data = bytes(self.mainwindow.saveGeometry()) + geom = base64.b64encode(data).decode('ASCII') try: self.stateconfig.add_section('geometry') except configparser.DuplicateSectionError: @@ -530,7 +517,7 @@ class Application(QApplication): """ # pylint: disable=broad-except - if exctype is BdbQuit or not issubclass(exctype, Exception): + if exctype is bdb.BdbQuit or not issubclass(exctype, Exception): # pdb exit, KeyboardInterrupt, ... try: self.shutdown() @@ -580,8 +567,8 @@ class Application(QApplication): log.destroy.debug("Error while preventing shutdown: {}: {}".format( e.__class__.__name__, e)) QApplication.closeAllWindows() - self._crashdlg = ExceptionCrashDialog(pages, history, exc, widgets, - objects) + self._crashdlg = crash.ExceptionCrashDialog(pages, history, exc, + widgets, objects) ret = self._crashdlg.exec_() if ret == QDialog.Accepted: # restore self.restart(shutdown=False, pages=pages) @@ -655,7 +642,7 @@ class Application(QApplication): history = self.mainwindow.status.cmd.history[-5:] widgets = self.get_all_widgets() objects = self.get_all_objects() - self._crashdlg = ReportDialog(pages, history, widgets, objects) + self._crashdlg = crash.ReportDialog(pages, history, widgets, objects) self._crashdlg.show() @cmdutils.register(instance='', debug=True, name='debug-console') @@ -674,7 +661,7 @@ class Application(QApplication): signal.signal(signal.SIGINT, self.interrupt_forcefully) signal.signal(signal.SIGTERM, self.interrupt_forcefully) # If we call shutdown directly here, we get a segfault. - QTimer.singleShot(0, partial(self.shutdown, 128 + signum)) + QTimer.singleShot(0, functools.partial(self.shutdown, 128 + signum)) def interrupt_forcefully(self, signum, _frame): """Interrupt forcefully on the second SIGINT/SIGTERM request. @@ -689,7 +676,7 @@ class Application(QApplication): signal.signal(signal.SIGTERM, self.interrupt_really_forcefully) # This *should* work without a QTimer, but because of the trouble in # self.interrupt we're better safe than sorry. - QTimer.singleShot(0, partial(self.exit, 128 + signum)) + QTimer.singleShot(0, functools.partial(self.exit, 128 + signum)) def interrupt_really_forcefully(self, signum, _frame): """Interrupt with even more force on the third SIGINT/SIGTERM request. @@ -722,7 +709,7 @@ class Application(QApplication): # in the real main event loop, or we'll get a segfault. log.destroy.debug("Deferring real shutdown because question was " "active.") - QTimer.singleShot(0, partial(self._shutdown, status)) + QTimer.singleShot(0, functools.partial(self._shutdown, status)) else: # If we have no questions to shut down, we are already in the real # event loop, so we can shut down immediately. @@ -773,7 +760,7 @@ class Application(QApplication): log.destroy.debug("Deferring QApplication::exit...") # We use a singleshot timer to exit here to minimize the likelyhood of # segfaults. - QTimer.singleShot(0, partial(self.exit, status)) + QTimer.singleShot(0, functools.partial(self.exit, status)) def exit(self, status): """Extend QApplication::exit to log the event.""" diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 75e4e34b1..c02290a12 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -29,19 +29,14 @@ from PyQt5.QtGui import QClipboard from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog from PyQt5.QtWebKitWidgets import QWebInspector -import qutebrowser.commands.utils as cmdutils -import qutebrowser.config.config as config -import qutebrowser.browser.hints as hints -import qutebrowser.utils.message as message -import qutebrowser.utils.webelem as webelem -import qutebrowser.browser.quickmarks as quickmarks -import qutebrowser.utils.log as log -import qutebrowser.utils.url as urlutils -import qutebrowser.commands.userscripts as userscripts -from qutebrowser.utils.qt import check_overflow, check_print_compat -from qutebrowser.utils.editor import ExternalEditor -from qutebrowser.commands.exceptions import CommandError -from qutebrowser.utils.usertypes import KeyMode +from qutebrowser.commands import userscripts +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.config import config +from qutebrowser.browser import hints, quickmarks +from qutebrowser.utils import message, webelem, editor, usertypes, log +from qutebrowser.utils import qt as qtutils +from qutebrowser.utils import url as urlutils class CommandDispatcher: @@ -82,7 +77,7 @@ class CommandDispatcher: perc = int(count) else: perc = float(perc) - perc = check_overflow(perc, 'int', fatal=False) + perc = qtutils.check_overflow(perc, 'int', fatal=False) frame = self._tabs.currentWidget().page().currentFrame() m = frame.scrollBarMaximum(orientation) if m == 0: @@ -94,7 +89,7 @@ class CommandDispatcher: widget = self._tabs.currentWidget() frame = widget.page().currentFrame() if frame is None: - raise CommandError("No frame focused!") + raise cmdexc.CommandError("No frame focused!") widget.hintmanager.follow_prevnext(frame, self._tabs.current_url(), prev, newtab) @@ -130,10 +125,10 @@ class CommandDispatcher: def _tab_focus_last(self): """Select the tab which was last focused.""" if self._tabs.last_focused is None: - raise CommandError("No last focused tab!") + raise cmdexc.CommandError("No last focused tab!") idx = self._tabs.indexOf(self._tabs.last_focused) if idx == -1: - raise CommandError("Last focused tab vanished!") + raise cmdexc.CommandError("Last focused tab vanished!") self._tabs.setCurrentIndex(idx) def _editor_cleanup(self, oshandle, filename): @@ -142,7 +137,7 @@ class CommandDispatcher: try: os.remove(filename) except PermissionError: - raise CommandError("Failed to delete tempfile...") + raise cmdexc.CommandError("Failed to delete tempfile...") @cmdutils.register(instance='mainwindow.tabs.cmd') def tab_close(self, count=None): @@ -173,7 +168,7 @@ class CommandDispatcher: try: url = urlutils.fuzzy_url(urlstr) except urlutils.FuzzyUrlError as e: - raise CommandError(e) + raise cmdexc.CommandError(e) if tab is None: if count is None: # We want to open a URL in the current tab, but none exists @@ -214,9 +209,9 @@ class CommandDispatcher: Args: count: The tab index to print, or None. """ - if not check_print_compat(): - raise CommandError("Printing on Qt < 5.3.0 on Windows is broken, " - "please upgrade!") + if not qtutils.check_print_compat(): + raise cmdexc.CommandError( + "Printing on Qt < 5.3.0 on Windows is broken, please upgrade!") tab = self._tabs.cntwidget(count) if tab is not None: preview = QPrintPreviewDialog() @@ -231,9 +226,9 @@ class CommandDispatcher: Args: count: The tab index to print, or None. """ - if not check_print_compat(): - raise CommandError("Printing on Qt < 5.3.0 on Windows is broken, " - "please upgrade!") + if not qtutils.check_print_compat(): + raise cmdexc.CommandError( + "Printing on Qt < 5.3.0 on Windows is broken, please upgrade!") tab = self._tabs.cntwidget(count) if tab is not None: printdiag = QPrintDialog() @@ -303,15 +298,17 @@ class CommandDispatcher: widget = self._tabs.currentWidget() frame = widget.page().mainFrame() if frame is None: - raise CommandError("No frame focused!") + raise cmdexc.CommandError("No frame focused!") try: group_enum = webelem.Group[group.replace('-', '_')] except KeyError: - raise CommandError("Unknown hinting group {}!".format(group)) + raise cmdexc.CommandError("Unknown hinting group {}!".format( + group)) try: target_enum = hints.Target[target.replace('-', '_')] except KeyError: - raise CommandError("Unknown hinting target {}!".format(target)) + raise cmdexc.CommandError("Unknown hinting target {}!".format( + target)) widget.hintmanager.start(frame, self._tabs.current_url(), group_enum, target_enum, *args) @@ -488,7 +485,7 @@ class CommandDispatcher: try: level = cmdutils.arg_or_count(zoom, count, default=100) except ValueError as e: - raise CommandError(e) + raise cmdexc.CommandError(e) tab = self._tabs.currentWidget() tab.zoom_perc(level) @@ -506,7 +503,7 @@ class CommandDispatcher: try: url = urlutils.fuzzy_url(urlstr) except urlutils.FuzzyUrlError as e: - raise CommandError(e) + raise cmdexc.CommandError(e) self._tabs.tabopen(url, background=False, explicit=True) @cmdutils.register(instance='mainwindow.tabs.cmd', split=False) @@ -515,7 +512,7 @@ class CommandDispatcher: try: url = urlutils.fuzzy_url(urlstr) except urlutils.FuzzyUrlError as e: - raise CommandError(e) + raise cmdexc.CommandError(e) self._tabs.tabopen(url, background=True, explicit=True) @cmdutils.register(instance='mainwindow.tabs.cmd') @@ -524,7 +521,7 @@ class CommandDispatcher: if self._tabs.url_stack: self._tabs.tabopen(self._tabs.url_stack.pop()) else: - raise CommandError("Nothing to undo!") + raise cmdexc.CommandError("Nothing to undo!") @cmdutils.register(instance='mainwindow.tabs.cmd') def tab_prev(self, count=1): @@ -539,7 +536,7 @@ class CommandDispatcher: elif config.get('tabs', 'wrap'): self._tabs.setCurrentIndex(newidx % self._tabs.count()) else: - raise CommandError("First tab") + raise cmdexc.CommandError("First tab") @cmdutils.register(instance='mainwindow.tabs.cmd') def tab_next(self, count=1): @@ -554,7 +551,7 @@ class CommandDispatcher: elif config.get('tabs', 'wrap'): self._tabs.setCurrentIndex(newidx % self._tabs.count()) else: - raise CommandError("Last tab") + raise cmdexc.CommandError("Last tab") @cmdutils.register(instance='mainwindow.tabs.cmd', nargs=(0, 1)) def paste(self, sel=False, tab=False): @@ -573,12 +570,12 @@ class CommandDispatcher: target = "Clipboard" text = clipboard.text(mode) if not text: - raise CommandError("{} is empty.".format(target)) + raise cmdexc.CommandError("{} is empty.".format(target)) log.misc.debug("{} contained: '{}'".format(target, text)) try: url = urlutils.fuzzy_url(text) except urlutils.FuzzyUrlError as e: - raise CommandError(e) + raise cmdexc.CommandError(e) if tab: self._tabs.tabopen(url, explicit=True) else: @@ -610,12 +607,13 @@ class CommandDispatcher: idx = cmdutils.arg_or_count(index, count, default=1, countzero=self._tabs.count()) except ValueError as e: - raise CommandError(e) + raise cmdexc.CommandError(e) cmdutils.check_overflow(idx + 1, 'int') if 1 <= idx <= self._tabs.count(): self._tabs.setCurrentIndex(idx - 1) else: - raise CommandError("There's no tab with index {}!".format(idx)) + raise cmdexc.CommandError("There's no tab with index {}!".format( + idx)) @cmdutils.register(instance='mainwindow.tabs.cmd') def tab_move(self, direction=None, count=None): @@ -632,11 +630,13 @@ class CommandDispatcher: try: new_idx = self._tab_move_relative(direction, count) except ValueError: - raise CommandError("Count must be given for relative moving!") + raise cmdexc.CommandError("Count must be given for relative " + "moving!") else: - raise CommandError("Invalid direction '{}'!".format(direction)) + raise cmdexc.CommandError("Invalid direction '{}'!".format( + direction)) if not 0 <= new_idx < self._tabs.count(): - raise CommandError("Can't move tab to position {}!".format( + raise cmdexc.CommandError("Can't move tab to position {}!".format( new_idx)) tab = self._tabs.currentWidget() cur_idx = self._tabs.currentIndex() @@ -697,7 +697,7 @@ class CommandDispatcher: urlstr = quickmarks.get(name) url = QUrl(urlstr) if not url.isValid(): - raise CommandError("Invalid URL {} ({})".format( + raise cmdexc.CommandError("Invalid URL {} ({})".format( urlstr, url.errorString())) self._tabs.currentWidget().openurl(url) @@ -719,8 +719,9 @@ class CommandDispatcher: cur = self._tabs.currentWidget() if cur.inspector is None: if not config.get('general', 'developer-extras'): - raise CommandError("Please enable developer-extras before " - "using the webinspector!") + raise cmdexc.CommandError( + "Please enable developer-extras before using the " + "webinspector!") cur.inspector = QWebInspector() cur.inspector.setPage(cur.page()) cur.inspector.show() @@ -728,8 +729,9 @@ class CommandDispatcher: cur.inspector.hide() else: if not config.get('general', 'developer-extras'): - raise CommandError("Please enable developer-extras before " - "using the webinspector!") + raise cmdexc.CommandError( + "Please enable developer-extras before using the " + "webinspector!") else: cur.inspector.show() @@ -739,7 +741,8 @@ class CommandDispatcher: page = self._tabs.currentWidget().page() self._tabs.download_get.emit(self._tabs.current_url(), page) - @cmdutils.register(instance='mainwindow.tabs.cmd', modes=[KeyMode.insert], + @cmdutils.register(instance='mainwindow.tabs.cmd', + modes=[usertypes.KeyMode.insert], hide=True) def open_editor(self): """Open an external editor with the currently selected form field. @@ -756,14 +759,14 @@ class CommandDispatcher: frame = self._tabs.currentWidget().page().currentFrame() elem = webelem.focus_elem(frame) if elem.isNull(): - raise CommandError("No element focused!") + raise cmdexc.CommandError("No element focused!") if not webelem.is_editable(elem, strict=True): - raise CommandError("Focused element is not editable!") + raise cmdexc.CommandError("Focused element is not editable!") if webelem.is_content_editable(elem): text = elem.toPlainText() else: text = elem.evaluateJavaScript('this.value') - self._editor = ExternalEditor(self._tabs) + self._editor = editor.ExternalEditor(self._tabs) self._editor.editing_finished.connect( partial(self.on_editing_finished, elem)) self._editor.edit(text) @@ -778,7 +781,7 @@ class CommandDispatcher: text: The new text to insert. """ if elem.isNull(): - raise CommandError("Element vanished while editing!") + raise cmdexc.CommandError("Element vanished while editing!") if webelem.is_content_editable(elem): log.misc.debug("Filling element {} via setPlainText.".format( webelem.debug_text(elem))) diff --git a/qutebrowser/browser/cookies.py b/qutebrowser/browser/cookies.py index b7da8d949..b7359fdf1 100644 --- a/qutebrowser/browser/cookies.py +++ b/qutebrowser/browser/cookies.py @@ -22,9 +22,8 @@ from PyQt5.QtNetwork import QNetworkCookie, QNetworkCookieJar from PyQt5.QtCore import QStandardPaths, QDateTime -import qutebrowser.config.config as config -from qutebrowser.config.lineparser import LineConfigParser -from qutebrowser.utils.misc import get_standard_dir +from qutebrowser.config import config, lineparser +from qutebrowser.utils import misc as utils class CookieJar(QNetworkCookieJar): @@ -33,8 +32,8 @@ class CookieJar(QNetworkCookieJar): def __init__(self, parent=None): super().__init__(parent) - datadir = get_standard_dir(QStandardPaths.DataLocation) - self._linecp = LineConfigParser(datadir, 'cookies') + datadir = utils.get_standard_dir(QStandardPaths.DataLocation) + self._linecp = lineparser.LineConfigParser(datadir, 'cookies') cookies = [] for line in self._linecp: cookies += QNetworkCookie.parseCookies(line.encode('utf-8')) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index aa129ce54..4d539eb38 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -21,21 +21,19 @@ import os import os.path -from functools import partial -from collections import deque +import functools +import collections from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QTimer, QStandardPaths from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply -import qutebrowser.config.config as config -import qutebrowser.utils.message as message -import qutebrowser.commands.utils as cmdutils -import qutebrowser.utils.misc as utils -from qutebrowser.utils.http import parse_content_disposition +from qutebrowser.config import config +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.utils import message, http, usertypes +from qutebrowser.utils import misc as utils +from qutebrowser.utils import qt as qtutils from qutebrowser.utils.log import downloads as logger -from qutebrowser.utils.usertypes import PromptMode, Question, Timer -from qutebrowser.utils.qt import qt_ensure_valid -from qutebrowser.commands.exceptions import CommandError class DownloadItem(QObject): @@ -92,7 +90,7 @@ class DownloadItem(QObject): self.basename = '???' samples = int(self.SPEED_AVG_WINDOW * (1000 / self.SPEED_REFRESH_INTERVAL)) - self.speed_avg = deque(maxlen=samples) + self.speed_avg = collections.deque(maxlen=samples) self.fileobj = None self.filename = None self.is_cancelled = False @@ -111,7 +109,7 @@ class DownloadItem(QObject): QTimer.singleShot(0, lambda: self.error.emit(reply.errorString())) if reply.isFinished(): QTimer.singleShot(0, self.finished.emit) - self.timer = Timer(self, 'speed_refresh') + self.timer = usertypes.Timer(self, 'speed_refresh') self.timer.timeout.connect(self.update_speed) self.timer.setInterval(self.SPEED_REFRESH_INTERVAL) self.timer.start() @@ -349,7 +347,7 @@ class DownloadManager(QObject): url: The URL to get, as QUrl page: The QWebPage to get the download from. """ - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) req = QNetworkRequest(url) reply = page.networkAccessManager().get(req) self.fetch(reply) @@ -362,7 +360,7 @@ class DownloadManager(QObject): try: download = self.downloads[count - 1] except IndexError: - raise CommandError("There's no download {}!".format(count)) + raise cmdexc.CommandError("There's no download {}!".format(count)) download.cancel() @pyqtSlot('QNetworkReply') @@ -372,25 +370,27 @@ class DownloadManager(QObject): Args: reply: The QNetworkReply to download. """ - _inline, suggested_filename = parse_content_disposition(reply) + _inline, suggested_filename = http.parse_content_disposition(reply) logger.debug("fetch: {} -> {}".format(reply.url(), suggested_filename)) download = DownloadItem(reply, self) - download.finished.connect(partial(self.on_finished, download)) - download.data_changed.connect(partial(self.on_data_changed, download)) + download.finished.connect( + functools.partial(self.on_finished, download)) + download.data_changed.connect( + functools.partial(self.on_data_changed, download)) download.error.connect(self.on_error) download.basename = suggested_filename self.download_about_to_be_added.emit(len(self.downloads) + 1) self.downloads.append(download) self.download_added.emit() - q = Question(self) + q = usertypes.Question(self) q.text = "Save file to:" - q.mode = PromptMode.text + q.mode = usertypes.PromptMode.text q.default = suggested_filename q.answered.connect(download.set_filename) q.cancelled.connect(download.cancel) q.completed.connect(q.deleteLater) - q.destroyed.connect(partial(self.questions.remove, q)) + q.destroyed.connect(functools.partial(self.questions.remove, q)) self.questions.append(q) download.cancelled.connect(q.abort) message.instance().ask(q, blocking=False) diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 7fa29ccdf..361947090 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -21,28 +21,28 @@ import math import subprocess -from collections import namedtuple +import collections from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent, Qt, QUrl from PyQt5.QtGui import QMouseEvent, QClipboard from PyQt5.QtWidgets import QApplication -import qutebrowser.config.config as config -import qutebrowser.keyinput.modeman as modeman -import qutebrowser.utils.message as message -import qutebrowser.utils.webelem as webelem -import qutebrowser.commands.userscripts as userscripts -from qutebrowser.commands.exceptions import CommandError -from qutebrowser.utils.usertypes import enum, KeyMode +from qutebrowser.config import config +from qutebrowser.keyinput import modeman +from qutebrowser.utils import message, webelem +from qutebrowser.commands import userscripts +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.utils import usertypes +from qutebrowser.utils import qt as qtutils from qutebrowser.utils.log import hints as logger -from qutebrowser.utils.qt import qt_ensure_valid -ElemTuple = namedtuple('ElemTuple', 'elem, label') +ElemTuple = collections.namedtuple('ElemTuple', 'elem, label') -Target = enum('Target', 'normal', 'tab', 'tab_bg', 'yank', 'yank_primary', - 'fill', 'rapid', 'download', 'userscript', 'spawn') +Target = usertypes.enum('Target', 'normal', 'tab', 'tab_bg', 'yank', + 'yank_primary', 'fill', 'rapid', 'download', + 'userscript', 'spawn') class HintContext: @@ -340,7 +340,7 @@ class HintManager(QObject): Args: url: The URL to open as a QURL. """ - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) sel = self._context.target == Target.yank_primary mode = QClipboard.Selection if sel else QClipboard.Clipboard urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword) @@ -354,7 +354,7 @@ class HintManager(QObject): Args: url: The URL to open as a QUrl. """ - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) urlstr = url.toDisplayString(QUrl.FullyEncoded) args = self._context.get_args(urlstr) message.set_cmd_text(' '.join(args)) @@ -370,19 +370,19 @@ class HintManager(QObject): message.error("No suitable link found for this element.", immediately=True) return - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) self.download_get.emit(url, elem.webFrame().page()) def _call_userscript(self, url): """Call an userscript from a hint.""" - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) cmd = self._context.args[0] args = self._context.args[1:] userscripts.run(cmd, *args, url=url) def _spawn(self, url): """Spawn a simple command from a hint.""" - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword) args = self._context.get_args(urlstr) subprocess.Popen(args) @@ -406,7 +406,7 @@ class HintManager(QObject): url = QUrl(text) if url.isRelative(): url = baseurl.resolved(url) - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) return url def _find_prevnext(self, frame, prev=False): @@ -457,11 +457,11 @@ class HintManager(QObject): """ elem = self._find_prevnext(frame, prev) if elem is None: - raise CommandError("No {} links found!".format( + raise cmdexc.CommandError("No {} links found!".format( "prev" if prev else "forward")) url = self._resolve_url(elem, baseurl) if url is None or not url.isValid(): - raise CommandError("No {} links found!".format( + raise cmdexc.CommandError("No {} links found!".format( "prev" if prev else "forward")) self.openurl.emit(url, newtab) @@ -488,12 +488,13 @@ class HintManager(QObject): raise ValueError("start() was called with frame=None") if target in (Target.userscript, Target.spawn, Target.fill): if not args: - raise CommandError("Additional arguments are required with " - "target userscript/spawn/fill.") + raise cmdexc.CommandError( + "Additional arguments are required with target " + "userscript/spawn/fill.") else: if args: - raise CommandError("Arguments are only allowed with target " - "userscript/spawn.") + raise cmdexc.CommandError( + "Arguments are only allowed with target userscript/spawn.") elems = [] ctx = HintContext() ctx.frames = webelem.get_child_frames(mainframe) @@ -503,7 +504,7 @@ class HintManager(QObject): visible_elems = [e for e in elems if filterfunc(e) and webelem.is_visible(e, mainframe)] if not visible_elems: - raise CommandError("No elements found.") + raise cmdexc.CommandError("No elements found.") ctx.target = target ctx.baseurl = baseurl ctx.args = args @@ -516,7 +517,7 @@ class HintManager(QObject): self._connect_frame_signals() self.hint_strings_updated.emit(strings) try: - modeman.enter(KeyMode.hint, 'HintManager.start') + modeman.enter(usertypes.KeyMode.hint, 'HintManager.start') except modeman.ModeLockedError: self._cleanup() @@ -560,7 +561,7 @@ class HintManager(QObject): visible[k] = e if not visible: # Whoops, filtered all hints - modeman.leave(KeyMode.hint, 'all filtered') + modeman.leave(usertypes.KeyMode.hint, 'all filtered') elif len(visible) == 1 and config.get('hints', 'auto-follow'): # unpacking gets us the first (and only) key in the dict. self.fire(*visible) @@ -606,12 +607,12 @@ class HintManager(QObject): else: raise ValueError("No suitable handler found!") if self._context.target != Target.rapid: - modeman.maybe_leave(KeyMode.hint, 'followed') + modeman.maybe_leave(usertypes.KeyMode.hint, 'followed') def follow_hint(self): """Follow the currently selected hint.""" if not self._context.to_follow: - raise CommandError("No hint to follow") + raise cmdexc.CommandError("No hint to follow") self.fire(self._context.to_follow, force=True) @pyqtSlot('QSize') @@ -627,16 +628,16 @@ class HintManager(QObject): css = self._get_hint_css(elems.elem, elems.label) elems.label.setAttribute('style', css) - @pyqtSlot(KeyMode) + @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Stop hinting when insert mode was entered.""" - if mode == KeyMode.insert: - modeman.maybe_leave(KeyMode.hint, 'insert mode') + if mode == usertypes.KeyMode.insert: + modeman.maybe_leave(usertypes.KeyMode.hint, 'insert mode') - @pyqtSlot(KeyMode) + @pyqtSlot(usertypes.KeyMode) def on_mode_left(self, mode): """Stop hinting when hinting mode was left.""" - if mode != KeyMode.hint or self._context is None: + if mode != usertypes.KeyMode.hint or self._context is None: # We have one HintManager per tab, so when this gets called, # self._context might be None, because the current tab is not # hinting. diff --git a/qutebrowser/browser/quickmarks.py b/qutebrowser/browser/quickmarks.py index 5ce9368ac..e35705c0a 100644 --- a/qutebrowser/browser/quickmarks.py +++ b/qutebrowser/browser/quickmarks.py @@ -24,29 +24,28 @@ OrderedDict. This is because we read them from a file at start and write them to a file on shutdown, so it makes semse to keep them as strings her.e """ -from functools import partial -from collections import OrderedDict +import functools +import collections from PyQt5.QtCore import QStandardPaths, QUrl -import qutebrowser.utils.message as message -import qutebrowser.commands.utils as cmdutils -from qutebrowser.utils.usertypes import PromptMode -from qutebrowser.config.lineparser import LineConfigParser -from qutebrowser.utils.misc import get_standard_dir -from qutebrowser.utils.qt import qt_ensure_valid -from qutebrowser.commands.exceptions import CommandError +from qutebrowser.utils import message, usertypes +from qutebrowser.utils import misc as utils +from qutebrowser.utils import qt as qtutils +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.config import lineparser -marks = OrderedDict() +marks = collections.OrderedDict() linecp = None def init(): """Read quickmarks from the config file.""" global linecp - confdir = get_standard_dir(QStandardPaths.ConfigLocation) - linecp = LineConfigParser(confdir, 'quickmarks') + confdir = utils.get_standard_dir(QStandardPaths.ConfigLocation) + linecp = lineparser.LineConfigParser(confdir, 'quickmarks') for line in linecp: try: key, url = line.split(maxsplit=1) @@ -68,10 +67,10 @@ def prompt_save(url): Args: url: The quickmark url as a QUrl. """ - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded) - message.ask_async("Add quickmark:", PromptMode.text, - partial(quickmark_add, urlstr)) + message.ask_async("Add quickmark:", usertypes.PromptMode.text, + functools.partial(quickmark_add, urlstr)) @cmdutils.register() @@ -83,9 +82,9 @@ def quickmark_add(urlstr, name): name: The name for the new quickmark. """ if not name: - raise CommandError("Can't set mark with empty name!") + raise cmdexc.CommandError("Can't set mark with empty name!") if not urlstr: - raise CommandError("Can't set mark with empty URL!") + raise cmdexc.CommandError("Can't set mark with empty URL!") def set_mark(): """Really set the quickmark.""" @@ -101,10 +100,12 @@ def quickmark_add(urlstr, name): def get(name): """Get the URL of the quickmark named name as a QUrl.""" if name not in marks: - raise CommandError("Quickmark '{}' does not exist!".format(name)) + raise cmdexc.CommandError( + "Quickmark '{}' does not exist!".format(name)) urlstr = marks[name] url = QUrl(urlstr) if not url.isValid(): - raise CommandError("Invalid URL for quickmark {}: {} ({})".format( - name, urlstr, url.errorString())) + raise cmdexc.CommandError( + "Invalid URL for quickmark {}: {} ({})".format(name, urlstr, + url.errorString())) return url diff --git a/qutebrowser/browser/signalfilter.py b/qutebrowser/browser/signalfilter.py index 3a9ac0341..ce155d8fa 100644 --- a/qutebrowser/browser/signalfilter.py +++ b/qutebrowser/browser/signalfilter.py @@ -19,12 +19,12 @@ """A filter for signals which either filters or passes them.""" -from functools import partial +import functools from PyQt5.QtCore import QObject -from qutebrowser.utils.debug import dbg_signal, signal_name -from qutebrowser.widgets.webview import WebView +from qutebrowser.utils import debug +from qutebrowser.widgets import webview from qutebrowser.utils.log import signals as logger @@ -58,10 +58,10 @@ class SignalFilter(QObject): Return: A partial functon calling _filter_signals with a signal. """ - if not isinstance(tab, WebView): + if not isinstance(tab, webview.WebView): raise ValueError("Tried to create filter for {} which is no " "WebView!".format(tab)) - return partial(self._filter_signals, signal, tab) + return functools.partial(self._filter_signals, signal, tab) def _filter_signals(self, signal, tab, *args): """Filter signals and trigger TabbedBrowser signals if needed. @@ -80,7 +80,7 @@ class SignalFilter(QObject): Emit: The target signal if the sender was the current widget. """ - log_signal = signal_name(signal) not in self.BLACKLIST + log_signal = debug.signal_name(signal) not in self.BLACKLIST try: tabidx = self._tabs.indexOf(tab) except RuntimeError: @@ -89,9 +89,9 @@ class SignalFilter(QObject): if tabidx == self._tabs.currentIndex(): if log_signal: logger.debug("emitting: {} (tab {})".format( - dbg_signal(signal, args), tabidx)) + debug.dbg_signal(signal, args), tabidx)) signal.emit(*args) else: if log_signal: logger.debug("ignoring: {} (tab {})".format( - dbg_signal(signal, args), tabidx)) + debug.dbg_signal(signal, args), tabidx)) diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index 8727ba9d4..42ebf1064 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -28,14 +28,11 @@ from PyQt5.QtWidgets import QFileDialog from PyQt5.QtPrintSupport import QPrintDialog from PyQt5.QtWebKitWidgets import QWebPage -import qutebrowser.utils.message as message -import qutebrowser.config.config as config -import qutebrowser.utils.log as log -import qutebrowser.utils.http as http -from qutebrowser.network.networkmanager import NetworkManager -from qutebrowser.utils.misc import read_file -from qutebrowser.utils.qt import check_print_compat -from qutebrowser.utils.usertypes import PromptMode, ClickTarget +from qutebrowser.config import config +from qutebrowser.network import networkmanager +from qutebrowser.utils import message, usertypes, log, http +from qutebrowser.utils import misc as utils +from qutebrowser.utils import qt as qtutils class BrowserPage(QWebPage): @@ -61,7 +58,7 @@ class BrowserPage(QWebPage): QWebPage.ErrorPageExtension: self._handle_errorpage, QWebPage.ChooseMultipleFilesExtension: self._handle_multiple_files, } - self._networkmanager = NetworkManager(self) + self._networkmanager = networkmanager.NetworkManager(self) self.setNetworkAccessManager(self._networkmanager) self.setForwardUnsupportedContent(True) self.printRequested.connect(self.on_print_requested) @@ -83,7 +80,8 @@ class BrowserPage(QWebPage): http://www.riverbankcomputing.com/pipermail/pyqt/2014-June/034385.html """ - answer = message.ask("js: {}".format(msg), PromptMode.text, default) + answer = message.ask("js: {}".format(msg), usertypes.PromptMode.text, + default) if answer is None: return (False, "") else: @@ -122,7 +120,7 @@ class BrowserPage(QWebPage): log.webview.debug("Error domain: {}, error code: {}".format( info.domain, info.error)) title = "Error loading page: {}".format(urlstr) - errpage.content = read_file('html/error.html').format( + errpage.content = utils.read_file('html/error.html').format( title=title, url=urlstr, error=info.errorString, icon='') return True @@ -158,7 +156,7 @@ class BrowserPage(QWebPage): def on_print_requested(self, frame): """Handle printing when requested via javascript.""" - if not check_print_compat(): + if not qtutils.check_print_compat(): message.error("Printing on Qt < 5.3.0 on Windows is broken, " "please upgrade!", immediately=True) return @@ -246,11 +244,12 @@ class BrowserPage(QWebPage): def javaScriptAlert(self, _frame, msg): """Override javaScriptAlert to use the statusbar.""" - message.ask("[js alert] {}".format(msg), PromptMode.alert) + message.ask("[js alert] {}".format(msg), usertypes.PromptMode.alert) def javaScriptConfirm(self, _frame, msg): """Override javaScriptConfirm to use the statusbar.""" - ans = message.ask("[js confirm] {}".format(msg), PromptMode.yesno) + ans = message.ask("[js confirm] {}".format(msg), + usertypes.PromptMode.yesno) return bool(ans) def javaScriptConsoleMessage(self, msg, line, source): @@ -270,7 +269,7 @@ class BrowserPage(QWebPage): def shouldInterruptJavaScript(self): """Override shouldInterruptJavaScript to use the statusbar.""" answer = message.ask("Interrupt long-running javascript?", - PromptMode.yesno) + usertypes.PromptMode.yesno) if answer is None: answer = True return answer @@ -298,10 +297,10 @@ class BrowserPage(QWebPage): message.error("Invalid link {} clicked!".format(urlstr)) log.webview.debug(url.errorString()) return False - if self._view.open_target == ClickTarget.tab: + if self._view.open_target == usertypes.ClickTarget.tab: self._view.tabbedbrowser.tabopen(url, False) return False - elif self._view.open_target == ClickTarget.tab_bg: + elif self._view.open_target == usertypes.ClickTarget.tab_bg: self._view.tabbedbrowser.tabopen(url, True) return False else: diff --git a/qutebrowser/commands/command.py b/qutebrowser/commands/command.py index 983500d75..fce7cdec7 100644 --- a/qutebrowser/commands/command.py +++ b/qutebrowser/commands/command.py @@ -22,9 +22,8 @@ from PyQt5.QtCore import QCoreApplication, QUrl from PyQt5.QtWebKit import QWebSettings -from qutebrowser.commands.exceptions import (ArgumentCountError, - PrerequisitesError) -from qutebrowser.utils.misc import dotted_getattr +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.utils import misc as utils from qutebrowser.utils.log import commands as logger @@ -84,16 +83,18 @@ class Command: curmode = QCoreApplication.instance().modeman.mode if self.modes is not None and curmode not in self.modes: mode_names = '/'.join(mode.name for mode in self.modes) - raise PrerequisitesError("{}: This command is only allowed in {} " - "mode.".format(self.name, mode_names)) + raise cmdexc.PrerequisitesError( + "{}: This command is only allowed in {} mode.".format( + self.name, mode_names)) elif self.not_modes is not None and curmode in self.not_modes: mode_names = '/'.join(mode.name for mode in self.not_modes) - raise PrerequisitesError("{}: This command is not allowed in {} " - "mode.".format(self.name, mode_names)) + raise cmdexc.PrerequisitesError( + "{}: This command is not allowed in {} mode.".format( + self.name, mode_names)) if self.needs_js and not QWebSettings.globalSettings().testAttribute( QWebSettings.JavascriptEnabled): - raise PrerequisitesError("{}: This command needs javascript " - "enabled.".format(self.name)) + raise cmdexc.PrerequisitesError( + "{}: This command needs javascript enabled.".format(self.name)) if self.nargs[1] is None and self.nargs[0] <= len(args): pass elif self.nargs[0] <= len(args) <= self.nargs[1]: @@ -105,8 +106,9 @@ class Command: argcnt = '{}-inf'.format(self.nargs[0]) else: argcnt = '{}-{}'.format(self.nargs[0], self.nargs[1]) - raise ArgumentCountError("{}: {} args expected, but got {}".format( - self.name, argcnt, len(args))) + raise cmdexc.ArgumentCountError( + "{}: {} args expected, but got {}".format(self.name, argcnt, + len(args))) def run(self, args=None, count=None): """Run the command. @@ -142,7 +144,7 @@ class Command: if self.instance == '': obj = app else: - obj = dotted_getattr(app, self.instance) + obj = utils.dotted_getattr(app, self.instance) new_args.insert(0, obj) if count is not None and self.count: diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 12e19dd14..6c3a409e5 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -22,12 +22,11 @@ from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject from PyQt5.QtWebKitWidgets import QWebPage -import qutebrowser.config.config as config -import qutebrowser.commands.utils as cmdutils -import qutebrowser.utils.message as message -from qutebrowser.commands.exceptions import (NoSuchCommandError, - CommandMetaError, CommandError) -from qutebrowser.utils.misc import safe_shlex_split +from qutebrowser.config import config +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.utils import message +from qutebrowser.utils import misc as utils from qutebrowser.utils.log import commands as logger @@ -201,7 +200,7 @@ class CommandRunner: """ parts = text.strip().split(maxsplit=1) if not parts: - raise NoSuchCommandError("No command given") + raise cmdexc.NoSuchCommandError("No command given") cmdstr = parts[0] if aliases: new_cmd = self._get_alias(text, alias_no_args) @@ -217,11 +216,12 @@ class CommandRunner: parts.append('') return parts else: - raise NoSuchCommandError('{}: no such command'.format(cmdstr)) + raise cmdexc.NoSuchCommandError( + '{}: no such command'.format(cmdstr)) if len(parts) == 1: args = [] elif cmd.split: - args = safe_shlex_split(parts[1]) + args = utils.safe_shlex_split(parts[1]) else: args = parts[1].split(maxsplit=cmd.nargs[0] - 1) self._cmd = cmd @@ -266,7 +266,7 @@ class CommandRunner: """Run a command and display exceptions in the statusbar.""" try: self.run(text, count) - except (CommandMetaError, CommandError) as e: + except (cmdexc.CommandMetaError, cmdexc.CommandError) as e: message.error(e, immediately=True) @pyqtSlot(str, int) @@ -277,5 +277,5 @@ class CommandRunner: suitable to use while initializing.""" try: self.run(text, count) - except (CommandMetaError, CommandError) as e: + except (cmdexc.CommandMetaError, cmdexc.CommandError) as e: message.error(e) diff --git a/qutebrowser/commands/userscripts.py b/qutebrowser/commands/userscripts.py index a37df530c..589a3ca11 100644 --- a/qutebrowser/commands/userscripts.py +++ b/qutebrowser/commands/userscripts.py @@ -26,17 +26,17 @@ Module attributes: import os import os.path import tempfile -from select import select -from functools import partial +import select +import functools from PyQt5.QtCore import (pyqtSignal, QObject, QThread, QStandardPaths, QProcessEnvironment, QProcess, QUrl) -import qutebrowser.utils.message as message -from qutebrowser.utils.misc import get_standard_dir +from qutebrowser.utils import message +from qutebrowser.utils import misc as utils from qutebrowser.utils.log import procs as logger -from qutebrowser.commands.exceptions import CommandError -from qutebrowser.commands.runners import CommandRunner +from qutebrowser.commands import runners +from qutebrowser.commands import exceptions as cmdexc _runners = [] @@ -83,7 +83,7 @@ class _BlockingFIFOReader(QObject): self.fifo = os.fdopen(fd, 'r') while True: logger.debug("thread loop") - ready_r, _ready_w, _ready_e = select([self.fifo], [], [], 1) + ready_r, _ready_w, _ready_e = select.select([self.fifo], [], [], 1) if ready_r: logger.debug("reading data") for line in self.fifo: @@ -205,7 +205,7 @@ class _POSIXUserscriptRunner(_BaseUserscriptRunner): self.thread = None def run(self, cmd, *args, env=None): - rundir = get_standard_dir(QStandardPaths.RuntimeLocation) + rundir = utils.get_standard_dir(QStandardPaths.RuntimeLocation) # tempfile.mktemp is deprecated and discouraged, but we use it here to # create a FIFO since the only other alternative would be to create a # directory and place the FIFO there, which sucks. Since os.kfifo will @@ -313,7 +313,8 @@ class _DummyUserscriptRunner: def run(self, _cmd, *_args, _env=None): """Print an error as userscripts are not supported.""" self.finished.emit() - raise CommandError("Userscripts are not supported on this platform!") + raise cmdexc.CommandError( + "Userscripts are not supported on this platform!") # Here we basically just assign a generic UserscriptRunner class which does the @@ -329,7 +330,7 @@ else: def init(): """Initialize the global _commandrunner.""" global _commandrunner - _commandrunner = CommandRunner() + _commandrunner = runners.CommandRunner() def run(cmd, *args, url): @@ -341,4 +342,4 @@ def run(cmd, *args, url): runner.got_cmd.connect(_commandrunner.run_safely) runner.run(cmd, *args, env={'QUTE_URL': urlstr}) _runners.append(runner) - runner.finished.connect(partial(_runners.remove, runner)) + runner.finished.connect(functools.partial(_runners.remove, runner)) diff --git a/qutebrowser/commands/utils.py b/qutebrowser/commands/utils.py index ac59f2bad..5deb35ae3 100644 --- a/qutebrowser/commands/utils.py +++ b/qutebrowser/commands/utils.py @@ -24,12 +24,12 @@ Module attributes: """ import inspect -from collections import Iterable +import collections -import qutebrowser.utils.qt as qtutils -from qutebrowser.commands.command import Command -from qutebrowser.commands.exceptions import CommandError -from qutebrowser.utils.usertypes import KeyMode +from qutebrowser.utils import usertypes +from qutebrowser.utils import qt as qtutils +from qutebrowser.commands import command +from qutebrowser.commands import exceptions as cmdexc cmd_dict = {} @@ -49,8 +49,9 @@ def check_overflow(arg, ctype): try: qtutils.check_overflow(arg, ctype) except OverflowError: - raise CommandError("Numeric argument is too large for internal {} " - "representation.".format(ctype)) + raise cmdexc.CommandError( + "Numeric argument is too large for internal {} " + "representation.".format(ctype)) def arg_or_count(arg, count, default=None, countzero=None): @@ -135,11 +136,11 @@ class register: # pylint: disable=invalid-name self.debug = debug if modes is not None: for m in modes: - if not isinstance(m, KeyMode): + if not isinstance(m, usertypes.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): + if not isinstance(m, usertypes.KeyMode): raise TypeError("Mode {} is no KeyMode member!".format(m)) def __call__(self, func): @@ -178,12 +179,11 @@ class register: # pylint: disable=invalid-name desc = func.__doc__.splitlines()[0].strip() else: desc = "" - cmd = Command(name=mainname, split=self.split, - hide=self.hide, nargs=nargs, count=count, desc=desc, - instance=self.instance, handler=func, - completion=self.completion, modes=self.modes, - not_modes=self.not_modes, needs_js=self.needs_js, - debug=self.debug) + cmd = command.Command( + name=mainname, split=self.split, hide=self.hide, nargs=nargs, + count=count, desc=desc, instance=self.instance, handler=func, + completion=self.completion, modes=self.modes, + not_modes=self.not_modes, needs_js=self.needs_js, debug=self.debug) for name in names: cmd_dict[name] = cmd return func @@ -209,7 +209,7 @@ class register: # pylint: disable=invalid-name # we assume count always has a default (and it should!) if self.nargs is not None: # If nargs is overriden, use that. - if isinstance(self.nargs, Iterable): + if isinstance(self.nargs, collections.Iterable): # Iterable (min, max) # pylint: disable=unpacking-non-sequence minargs, maxargs = self.nargs diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 8ef3f1b56..aa9db0200 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -28,18 +28,15 @@ import os import os.path import textwrap import configparser -from configparser import ExtendedInterpolation -from collections.abc import MutableMapping +import collections.abc from PyQt5.QtCore import pyqtSignal, QObject, QCoreApplication -import qutebrowser.config.configdata as configdata -import qutebrowser.commands.utils as cmdutils -import qutebrowser.utils.message as message -import qutebrowser.utils.log as log -from qutebrowser.config.iniparsers import ReadConfigParser -from qutebrowser.config.conftypes import ValidationError -from qutebrowser.commands.exceptions import CommandError +from qutebrowser.utils import log +from qutebrowser.config import configdata, iniparsers, conftypes +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.utils import message from qutebrowser.utils.usertypes import Completion @@ -114,7 +111,7 @@ class ConfigManager(QObject): def __init__(self, configdir, fname, parent=None): super().__init__(parent) self.sections = configdata.DATA - self._configparser = ReadConfigParser(configdir, fname) + self._configparser = iniparsers.ReadConfigParser(configdir, fname) self._configfile = os.path.join(configdir, fname) self._wrapper_args = { 'width': 72, @@ -124,7 +121,7 @@ class ConfigManager(QObject): } self._configdir = configdir self._fname = fname - self._interpolation = ExtendedInterpolation() + self._interpolation = configparser.ExtendedInterpolation() self._proxies = {} for sectname in self.sections.keys(): self._proxies[sectname] = SectionProxy(self, sectname) @@ -227,7 +224,7 @@ class ConfigManager(QObject): k = k.replace('', '=') try: self.set('conf', sectname, k, v) - except ValidationError as e: + except conftypes.ValidationError as e: e.section = sectname e.option = k raise @@ -299,7 +296,8 @@ class ConfigManager(QObject): try: val = self.get(sectname, optname, transformed=False) except (NoOptionError, NoSectionError) as e: - raise CommandError("get: {} - {}".format(e.__class__.__name__, e)) + raise cmdexc.CommandError("get: {} - {}".format( + e.__class__.__name__, e)) else: message.info("{} {} = {}".format(sectname, optname, val), immediately=True) @@ -350,9 +348,10 @@ class ConfigManager(QObject): """ try: self.set('conf', sectname, optname, value) - except (NoOptionError, NoSectionError, ValidationError, + except (NoOptionError, NoSectionError, conftypes.ValidationError, ValueError) as e: - raise CommandError("set: {} - {}".format(e.__class__.__name__, e)) + raise cmdexc.CommandError("set: {} - {}".format( + e.__class__.__name__, e)) @cmdutils.register(name='set-temp', instance='config', completion=[Completion.section, Completion.option, @@ -371,8 +370,9 @@ class ConfigManager(QObject): """ try: self.set('temp', sectname, optname, value) - except (NoOptionError, NoSectionError, ValidationError) as e: - raise CommandError("set: {} - {}".format(e.__class__.__name__, e)) + except (NoOptionError, NoSectionError, conftypes.ValidationError) as e: + raise cmdexc.CommandError("set: {} - {}".format( + e.__class__.__name__, e)) def set(self, layer, sectname, optname, value): """Set an option. @@ -442,7 +442,7 @@ class ConfigManager(QObject): return val -class SectionProxy(MutableMapping): +class SectionProxy(collections.abc.MutableMapping): """A proxy for a single section from a config. diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 7d6a1308d..80e03b12a 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -27,11 +27,11 @@ DATA: The config defaults, an OrderedDict of sections. """ import re -from collections import OrderedDict +import collections +from qutebrowser.config import conftypes as typ +from qutebrowser.config import sections as sect from qutebrowser.config.value import SettingValue -import qutebrowser.config.conftypes as types -import qutebrowser.config.sections as sect from qutebrowser.utils.qt import MAXVALS @@ -165,57 +165,57 @@ SECTION_DESC = { } -DATA = OrderedDict([ +DATA = collections.OrderedDict([ ('general', sect.KeyValue( ('ignore-case', - SettingValue(types.IgnoreCase(), 'smart'), + SettingValue(typ.IgnoreCase(), 'smart'), "Whether to find text on a page case-insensitively."), ('wrap-search', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to wrap finding text to the top when arriving at the end."), ('startpage', - SettingValue(types.List(), 'http://www.duckduckgo.com'), + SettingValue(typ.List(), 'http://www.duckduckgo.com'), "The default page(s) to open at the start, separated by commas."), ('auto-search', - SettingValue(types.AutoSearch(), 'naive'), + SettingValue(typ.AutoSearch(), 'naive'), "Whether to start a search when something else than a URL is " "entered."), ('auto-save-config', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to save the config automatically on quit."), ('editor', - SettingValue(types.ShellCommand(placeholder=True), 'gvim -f "{}"'), + SettingValue(typ.ShellCommand(placeholder=True), 'gvim -f "{}"'), "The editor (and arguments) to use for the `open-editor` command.\n\n" "Use `{}` for the filename. The value gets split like in a shell, so " "you can use `\"` or `'` to quote arguments."), ('editor-encoding', - SettingValue(types.Encoding(), 'utf-8'), + SettingValue(typ.Encoding(), 'utf-8'), "Encoding to use for editor."), ('private-browsing', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Do not record visited pages in the history or store web page " "icons."), ('developer-extras', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Enable extra tools for Web developers.\n\n" "This needs to be enabled for `:inspector` to work and also adds an " "_Inspect_ entry to the context menu."), ('print-element-backgrounds', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether the background color and images are also drawn when the " "page is printed."), ('xss-auditing', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether load requests should be monitored for cross-site scripting " "attempts.\n\n" "Suspicious scripts will be blocked and reported in the inspector's " @@ -223,11 +223,11 @@ DATA = OrderedDict([ "performance."), ('site-specific-quirks', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Enable workarounds for broken sites."), ('default-encoding', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "Default encoding to use for websites.\n\n" "The encoding must be a string describing an encoding such as " '_utf-8_, _iso-8859-1_, etc. If left empty a default value will be ' @@ -236,126 +236,125 @@ DATA = OrderedDict([ ('ui', sect.KeyValue( ('zoom-levels', - SettingValue(types.PercList(minval=0), + SettingValue(typ.PercList(minval=0), '25%,33%,50%,67%,75%,90%,100%,110%,125%,150%,175%,200%,' '250%,300%,400%,500%'), "The available zoom levels, separated by commas."), ('default-zoom', - SettingValue(types.ZoomPerc(), '100%'), + SettingValue(typ.ZoomPerc(), '100%'), "The default zoom level."), ('message-timeout', - SettingValue(types.Int(), '2000'), + SettingValue(typ.Int(), '2000'), "Time (in ms) to show messages in the statusbar for."), ('confirm-quit', - SettingValue(types.ConfirmQuit(), 'never'), + SettingValue(typ.ConfirmQuit(), 'never'), "Whether to confirm quitting the application."), ('display-statusbar-messages', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether to display javascript statusbar messages."), ('zoom-text-only', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether the zoom factor on a frame applies only to the text or to " "all content."), ('frame-flattening', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether to expand each subframe to its contents.\n\n" "This will flatten all the frames to become one scrollable page."), ('user-stylesheet', - SettingValue(types.WebSettingsFile(), ''), + SettingValue(typ.WebSettingsFile(), ''), "User stylesheet to use."), ('css-media-type', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "Set the CSS media type."), )), ('network', sect.KeyValue( ('do-not-track', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Value to send in the `DNT` header."), ('accept-language', - SettingValue(types.String(none_ok=True), 'en-US,en'), + SettingValue(typ.String(none_ok=True), 'en-US,en'), "Value to send in the `accept-language` header."), ('user-agent', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "User agent to send. Empty to send the default."), ('proxy', - SettingValue(types.Proxy(), 'system'), + SettingValue(typ.Proxy(), 'system'), "The proxy to use.\n\n" "In addition to the listed values, you can use a `socks://...` or " "`http://...` URL."), ('ssl-strict', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to validate SSL handshakes."), ('dns-prefetch', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to try to pre-fetch DNS entries to speed up browsing."), )), ('completion', sect.KeyValue( ('show', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to show the autocompletion window."), ('height', - SettingValue(types.PercOrInt(minperc=0, maxperc=100, minint=1), - '50%'), + SettingValue(typ.PercOrInt(minperc=0, maxperc=100, minint=1), '50%'), "The height of the completion, in px or as percentage of the " "window."), ('history-length', - SettingValue(types.Int(minval=-1), '100'), + SettingValue(typ.Int(minval=-1), '100'), "How many commands to save in the history.\n\n" "0: no history / -1: unlimited"), ('quick-complete', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to move on to the next part when there's only one possible " "completion left."), ('shrink', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether to shrink the completion to be smaller than the configured " "size if there are no scrollbars."), )), ('input', sect.KeyValue( ('timeout', - SettingValue(types.Int(minval=0, maxval=MAXVALS['int']), '500'), + SettingValue(typ.Int(minval=0, maxval=MAXVALS['int']), '500'), "Timeout for ambiguous keybindings."), ('insert-mode-on-plugins', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether to switch to insert mode when clicking flash and other " "plugins."), ('auto-leave-insert-mode', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to leave insert mode if a non-editable element is clicked."), ('auto-insert-mode', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether to automatically enter insert mode if an editable element " "is focused after page load."), ('forward-unbound-keys', - SettingValue(types.ForwardUnboundKeys(), 'auto'), + SettingValue(typ.ForwardUnboundKeys(), 'auto'), "Whether to forward unbound keys to the webview in normal mode."), ('spatial-navigation', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Enables or disables the Spatial Navigation feature\n\n" "Spatial navigation consists in the ability to navigate between " "focusable elements in a Web page, such as hyperlinks and form " @@ -365,76 +364,74 @@ DATA = OrderedDict([ "right and which element he probably wants."), ('links-included-in-focus-chain', - SettingValue(types.Bool(), 'true'), - "Whether hyperlinks should be included in the keyboard focus " - "chain."), + SettingValue(typ.Bool(), 'true'), + "Whether hyperlinks should be included in the keyboard focus chain."), )), ('tabs', sect.KeyValue( ('background-tabs', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether to open new tabs (middleclick/ctrl+click) in background."), ('select-on-remove', - SettingValue(types.SelectOnRemove(), 'right'), + SettingValue(typ.SelectOnRemove(), 'right'), "Which tab to select when the focused tab is removed."), ('new-tab-position', - SettingValue(types.NewTabPosition(), 'right'), + SettingValue(typ.NewTabPosition(), 'right'), "How new tabs are positioned."), ('new-tab-position-explicit', - SettingValue(types.NewTabPosition(), 'last'), + SettingValue(typ.NewTabPosition(), 'last'), "How new tabs opened explicitely are positioned."), ('last-close', - SettingValue(types.LastClose(), 'ignore'), + SettingValue(typ.LastClose(), 'ignore'), "Behaviour when the last tab is closed."), ('wrap', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to wrap when changing tabs."), ('movable', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether tabs should be movable."), ('close-mouse-button', - SettingValue(types.CloseButton(), 'middle'), + SettingValue(typ.CloseButton(), 'middle'), "On which mouse button to close tabs."), ('position', - SettingValue(types.Position(), 'north'), + SettingValue(typ.Position(), 'north'), "The position of the tab bar."), ('show-favicons', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to show favicons in the tab bar."), ('width', - SettingValue(types.PercOrInt(minperc=0, maxperc=100, minint=1), - '20%'), + SettingValue(typ.PercOrInt(minperc=0, maxperc=100, minint=1), '20%'), "The width of the tab bar if it's vertical, in px or as percentage " "of the window."), ('indicator-width', - SettingValue(types.Int(minval=0), '3'), + SettingValue(typ.Int(minval=0), '3'), "Width of the progress indicator (0 to disable)."), ('indicator-space', - SettingValue(types.Int(minval=0), '3'), + SettingValue(typ.Int(minval=0), '3'), "Spacing between tab edge and indicator."), )), ('storage', sect.KeyValue( ('download-directory', - SettingValue(types.Directory(none_ok=True), ''), + SettingValue(typ.Directory(none_ok=True), ''), "The directory to save downloads to. An empty value selects a " "sensible os-specific default."), ('maximum-pages-in-cache', - SettingValue(types.Int(none_ok=True, minval=0, maxval=MAXVALS['int']), - ''), + SettingValue( + typ.Int(none_ok=True, minval=0, maxval=MAXVALS['int']), ''), "The maximum number of pages to hold in the memory page cache.\n\n" "The Page Cache allows for a nicer user experience when navigating " "forth or back to pages in the forward/back history, by pausing and " @@ -443,8 +440,8 @@ DATA = OrderedDict([ "http://webkit.org/blog/427/webkit-page-cache-i-the-basics/"), ('object-cache-capacities', - SettingValue(types.WebKitBytesList(length=3, maxsize=MAXVALS['int']), - ''), + SettingValue( + typ.WebKitBytesList(length=3, maxsize=MAXVALS['int']), ''), "The capacities for the memory cache for dead objects such as " "stylesheets or scripts. Syntax: cacheMinDeadCapacity, cacheMaxDead, " "totalCapacity.\n\n" @@ -457,19 +454,19 @@ DATA = OrderedDict([ "that the cache should consume *overall*."), ('offline-storage-default-quota', - SettingValue(types.WebKitBytes(maxsize=MAXVALS['int64']), ''), + SettingValue(typ.WebKitBytes(maxsize=MAXVALS['int64']), ''), "Default quota for new offline storage databases."), ('offline-web-application-cache-quota', - SettingValue(types.WebKitBytes(maxsize=MAXVALS['int64']), ''), + SettingValue(typ.WebKitBytes(maxsize=MAXVALS['int64']), ''), "Quota for the offline web application cache."), ('offline-storage-database', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether support for the HTML 5 offline storage feature is enabled."), ('offline-web-application-storage', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether support for the HTML 5 web application cache feature is " "enabled.\n\n" "An application cache acts like an HTTP cache in some sense. For " @@ -480,96 +477,96 @@ DATA = OrderedDict([ "http://dev.w3.org/html5/spec/Overview.html#appcache"), ('local-storage', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether support for the HTML 5 local storage feature is enabled."), )), ('permissions', sect.KeyValue( ('allow-images', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether images are automatically loaded in web pages."), ('allow-javascript', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Enables or disables the running of JavaScript programs."), ('allow-plugins', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Enables or disables plugins in Web pages.\n\n" 'Qt plugins with a mimetype such as "application/x-qt-plugin" are ' "not affected by this setting."), #('allow-java', - # SettingValue(types.Bool(), 'true'), + # SettingValue(typ.Bool(), 'true'), # "Enables or disables Java applets. Currently Java applets are " # "not supported"), ('javascript-can-open-windows', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether JavaScript programs can open new windows."), ('javascript-can-close-windows', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether JavaScript programs can close windows."), ('javascript-can-access-clipboard', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether JavaScript programs can read or write to the clipboard."), ('local-content-can-access-remote-urls', - SettingValue(types.Bool(), 'false'), + SettingValue(typ.Bool(), 'false'), "Whether locally loaded documents are allowed to access remote " "urls."), ('local-content-can-access-file-urls', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether locally loaded documents are allowed to access other local " "urls."), ('cookies-accept', - SettingValue(types.AcceptCookies(), 'default'), + SettingValue(typ.AcceptCookies(), 'default'), "Whether to accept cookies."), ('cookies-store', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to store cookies."), )), ('hints', sect.KeyValue( ('border', - SettingValue(types.String(), '1px solid #E3BE23'), + SettingValue(typ.String(), '1px solid #E3BE23'), "CSS border value for hints."), ('opacity', - SettingValue(types.Float(minval=0.0, maxval=1.0), '0.7'), + SettingValue(typ.Float(minval=0.0, maxval=1.0), '0.7'), "Opacity for hints."), ('mode', - SettingValue(types.HintMode(), 'letter'), + SettingValue(typ.HintMode(), 'letter'), "Mode to use for hints."), ('chars', - SettingValue(types.String(minlen=2), 'asdfghjkl'), + SettingValue(typ.String(minlen=2), 'asdfghjkl'), "Chars used for hint strings."), ('auto-follow', - SettingValue(types.Bool(), 'true'), + SettingValue(typ.Bool(), 'true'), "Whether to auto-follow a hint if there's only one left."), ('next-regexes', - SettingValue(types.RegexList(flags=re.IGNORECASE), + SettingValue(typ.RegexList(flags=re.IGNORECASE), r'\bnext\b,\bmore\b,\bnewer\b,\b[>→≫]\b,\b(>>|»)\b'), "A comma-separated list of regexes to use for 'next' links."), ('prev-regexes', - SettingValue(types.RegexList(flags=re.IGNORECASE), + SettingValue(typ.RegexList(flags=re.IGNORECASE), r'\bprev(ious)?\b,\bback\b,\bolder\b,\b[<←≪]\b,' r'\b(<<|«)\b'), "A comma-separated list of regexes to use for 'prev' links."), )), ('searchengines', sect.ValueList( - types.SearchEngineName(), types.SearchEngineUrl(), + typ.SearchEngineName(), typ.SearchEngineUrl(), ('DEFAULT', '${duckduckgo}'), ('duckduckgo', 'https://duckduckgo.com/?q={}'), ('ddg', '${duckduckgo}'), @@ -581,7 +578,7 @@ DATA = OrderedDict([ )), ('keybind', sect.ValueList( - types.KeyBindingName(), types.KeyBinding(), + typ.KeyBindingName(), typ.KeyBinding(), ('o', 'set-cmd-text ":open "'), ('go', 'set-cmd-text :open {url}'), ('O', 'set-cmd-text ":open-tab "'), @@ -674,7 +671,7 @@ DATA = OrderedDict([ )), ('keybind.insert', sect.ValueList( - types.KeyBindingName(), types.KeyBinding(), + typ.KeyBindingName(), typ.KeyBinding(), ('', 'leave-mode'), ('', 'leave-mode'), ('', 'open-editor'), @@ -682,7 +679,7 @@ DATA = OrderedDict([ )), ('keybind.hint', sect.ValueList( - types.KeyBindingName(), types.KeyBinding(), + typ.KeyBindingName(), typ.KeyBinding(), ('', 'follow-hint'), ('', 'leave-mode'), ('', 'leave-mode'), @@ -690,7 +687,7 @@ DATA = OrderedDict([ )), ('keybind.passthrough', sect.ValueList( - types.KeyBindingName(), types.KeyBinding(), + typ.KeyBindingName(), typ.KeyBinding(), ('', 'leave-mode'), ('', '${}'), )), @@ -699,7 +696,7 @@ DATA = OrderedDict([ # text field. ('keybind.command', sect.ValueList( - types.KeyBindingName(), types.KeyBinding(), + typ.KeyBindingName(), typ.KeyBinding(), ('', 'leave-mode'), ('', 'command-history-prev'), ('', 'command-history-next'), @@ -726,7 +723,7 @@ DATA = OrderedDict([ )), ('keybind.prompt', sect.ValueList( - types.KeyBindingName(), types.KeyBinding(), + typ.KeyBindingName(), typ.KeyBinding(), ('', 'leave-mode'), ('', 'prompt-accept'), ('y', 'prompt-yes'), @@ -749,255 +746,255 @@ DATA = OrderedDict([ )), ('aliases', sect.ValueList( - types.String(forbidden=' '), types.Command(), + typ.String(forbidden=' '), typ.Command(), )), ('colors', sect.KeyValue( ('completion.fg', - SettingValue(types.QtColor(), 'white'), + SettingValue(typ.QtColor(), 'white'), "Text color of the completion widget."), ('completion.bg', - SettingValue(types.QssColor(), '#333333'), + SettingValue(typ.QssColor(), '#333333'), "Background color of the completion widget."), ('completion.item.bg', - SettingValue(types.QssColor(), '${completion.bg}'), + SettingValue(typ.QssColor(), '${completion.bg}'), "Background color of completion widget items."), ('completion.category.fg', - SettingValue(types.QtColor(), 'white'), + SettingValue(typ.QtColor(), 'white'), "Foreground color of completion widget category headers."), ('completion.category.bg', - SettingValue(types.QssColor(), 'qlineargradient(x1:0, y1:0, x2:0, ' + SettingValue(typ.QssColor(), 'qlineargradient(x1:0, y1:0, x2:0, ' 'y2:1, stop:0 #888888, stop:1 #505050)'), "Background color of the completion widget category headers."), ('completion.category.border.top', - SettingValue(types.QssColor(), 'black'), + SettingValue(typ.QssColor(), 'black'), "Top border color of the completion widget category headers."), ('completion.category.border.bottom', - SettingValue(types.QssColor(), '${completion.category.border.top}'), + SettingValue(typ.QssColor(), '${completion.category.border.top}'), "Bottom border color of the completion widget category headers."), ('completion.item.selected.fg', - SettingValue(types.QtColor(), 'black'), + SettingValue(typ.QtColor(), 'black'), "Foreground color of the selected completion item."), ('completion.item.selected.bg', - SettingValue(types.QssColor(), '#e8c000'), + SettingValue(typ.QssColor(), '#e8c000'), "Background color of the selected completion item."), ('completion.item.selected.border.top', - SettingValue(types.QssColor(), '#bbbb00'), + SettingValue(typ.QssColor(), '#bbbb00'), "Top border color of the completion widget category headers."), ('completion.item.selected.border.bottom', - SettingValue(types.QssColor(), '${completion.item.selected.border.' + SettingValue(typ.QssColor(), '${completion.item.selected.border.' 'top}'), "Bottom border color of the selected completion item."), ('completion.match.fg', - SettingValue(types.QssColor(), '#ff4444'), + SettingValue(typ.QssColor(), '#ff4444'), "Foreground color of the matched text in the completion."), ('statusbar.bg', - SettingValue(types.QssColor(), 'black'), + SettingValue(typ.QssColor(), 'black'), "Foreground color of the statusbar."), ('statusbar.fg', - SettingValue(types.QssColor(), 'white'), + SettingValue(typ.QssColor(), 'white'), "Foreground color of the statusbar."), ('statusbar.bg.error', - SettingValue(types.QssColor(), 'red'), + SettingValue(typ.QssColor(), 'red'), "Background color of the statusbar if there was an error."), ('statusbar.bg.prompt', - SettingValue(types.QssColor(), 'darkblue'), + SettingValue(typ.QssColor(), 'darkblue'), "Background color of the statusbar if there is a prompt."), ('statusbar.bg.insert', - SettingValue(types.QssColor(), 'darkgreen'), + SettingValue(typ.QssColor(), 'darkgreen'), "Background color of the statusbar in insert mode."), ('statusbar.progress.bg', - SettingValue(types.QssColor(), 'white'), + SettingValue(typ.QssColor(), 'white'), "Background color of the progress bar."), ('statusbar.url.fg', - SettingValue(types.QssColor(), '${statusbar.fg}'), + SettingValue(typ.QssColor(), '${statusbar.fg}'), "Default foreground color of the URL in the statusbar."), ('statusbar.url.fg.success', - SettingValue(types.QssColor(), 'lime'), + SettingValue(typ.QssColor(), 'lime'), "Foreground color of the URL in the statusbar on successful " "load."), ('statusbar.url.fg.error', - SettingValue(types.QssColor(), 'orange'), + SettingValue(typ.QssColor(), 'orange'), "Foreground color of the URL in the statusbar on error."), ('statusbar.url.fg.warn', - SettingValue(types.QssColor(), 'yellow'), + SettingValue(typ.QssColor(), 'yellow'), "Foreground color of the URL in the statusbar when there's a " "warning."), ('statusbar.url.fg.hover', - SettingValue(types.QssColor(), 'aqua'), - "Foreground color of the URL in the statusbar for hovered " - "links."), + SettingValue(typ.QssColor(), 'aqua'), + "Foreground color of the URL in the statusbar for hovered links."), ('tab.fg', - SettingValue(types.QtColor(), 'white'), + SettingValue(typ.QtColor(), 'white'), "Foreground color of tabs."), ('tab.bg.odd', - SettingValue(types.QtColor(), 'grey'), + SettingValue(typ.QtColor(), 'grey'), "Background color of unselected odd tabs."), ('tab.bg.even', - SettingValue(types.QtColor(), 'darkgrey'), + SettingValue(typ.QtColor(), 'darkgrey'), "Background color of unselected even tabs."), ('tab.bg.selected', - SettingValue(types.QtColor(), 'black'), + SettingValue(typ.QtColor(), 'black'), "Background color of selected tabs."), ('tab.bg.bar', - SettingValue(types.QtColor(), '#555555'), + SettingValue(typ.QtColor(), '#555555'), "Background color of the tabbar."), ('tab.indicator.start', - SettingValue(types.QtColor(), '#0000aa'), + SettingValue(typ.QtColor(), '#0000aa'), "Color gradient start for the tab indicator."), ('tab.indicator.stop', - SettingValue(types.QtColor(), '#00aa00'), + SettingValue(typ.QtColor(), '#00aa00'), "Color gradient end for the tab indicator."), ('tab.indicator.error', - SettingValue(types.QtColor(), '#ff0000'), + SettingValue(typ.QtColor(), '#ff0000'), "Color for the tab indicator on errors.."), ('tab.indicator.system', - SettingValue(types.ColorSystem(), 'rgb'), + SettingValue(typ.ColorSystem(), 'rgb'), "Color gradient interpolation system for the tab indicator."), ('tab.seperator', - SettingValue(types.QssColor(), '#555555'), + SettingValue(typ.QssColor(), '#555555'), "Color for the tab seperator."), ('hints.fg', - SettingValue(types.CssColor(), 'black'), + SettingValue(typ.CssColor(), 'black'), "Font color for hints."), ('hints.fg.match', - SettingValue(types.CssColor(), 'green'), + SettingValue(typ.CssColor(), 'green'), "Font color for the matched part of hints."), ('hints.bg', - SettingValue(types.CssColor(), '-webkit-gradient(linear, left top, ' - 'left bottom, color-stop(0%,#FFF785), ' - 'color-stop(100%,#FFC542))'), + SettingValue(typ.CssColor(), '-webkit-gradient(linear, left top, ' + 'left bottom, color-stop(0%,#FFF785), ' + 'color-stop(100%,#FFC542))'), "Background color for hints."), ('downloads.fg', - SettingValue(types.QtColor(), '#ffffff'), + SettingValue(typ.QtColor(), '#ffffff'), "Foreground color for downloads."), ('downloads.bg.bar', - SettingValue(types.QssColor(), 'black'), + SettingValue(typ.QssColor(), 'black'), "Background color for the download bar."), ('downloads.bg.start', - SettingValue(types.QtColor(), '#0000aa'), + SettingValue(typ.QtColor(), '#0000aa'), "Color gradient start for downloads."), ('downloads.bg.stop', - SettingValue(types.QtColor(), '#00aa00'), + SettingValue(typ.QtColor(), '#00aa00'), "Color gradient end for downloads."), ('downloads.bg.system', - SettingValue(types.ColorSystem(), 'rgb'), + SettingValue(typ.ColorSystem(), 'rgb'), "Color gradient interpolation system for downloads."), )), ('fonts', sect.KeyValue( ('_monospace', - SettingValue(types.Font(), 'Terminus, Monospace, "DejaVu Sans Mono", ' + SettingValue(typ.Font(), 'Terminus, Monospace, "DejaVu Sans Mono", ' 'Consolas, Monaco, "Bitstream Vera Sans Mono", ' '"Andale Mono", "Liberation Mono", "Courier New", ' 'Courier, monospace, Fixed, Terminal'), "Default monospace fonts."), ('completion', - SettingValue(types.Font(), '8pt ${_monospace}'), + SettingValue(typ.Font(), '8pt ${_monospace}'), "Font used in the completion widget."), ('tabbar', - SettingValue(types.QtFont(), '8pt ${_monospace}'), + SettingValue(typ.QtFont(), '8pt ${_monospace}'), "Font used in the tabbar."), ('statusbar', - SettingValue(types.Font(), '8pt ${_monospace}'), + SettingValue(typ.Font(), '8pt ${_monospace}'), "Font used in the statusbar."), ('downloads', - SettingValue(types.Font(), '8pt ${_monospace}'), + SettingValue(typ.Font(), '8pt ${_monospace}'), "Font used for the downloadbar."), ('hints', - SettingValue(types.Font(), 'bold 12px Monospace'), + SettingValue(typ.Font(), 'bold 12px Monospace'), "Font used for the hints."), ('debug-console', - SettingValue(types.QtFont(), '8pt ${_monospace}'), + SettingValue(typ.QtFont(), '8pt ${_monospace}'), "Font used for the debugging console."), ('web-family-standard', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "Font family for standard fonts."), ('web-family-fixed', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "Font family for fixed fonts."), ('web-family-serif', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "Font family for serif fonts."), ('web-family-sans-serif', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "Font family for sans-serif fonts."), ('web-family-cursive', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "Font family for cursive fonts."), ('web-family-fantasy', - SettingValue(types.String(none_ok=True), ''), + SettingValue(typ.String(none_ok=True), ''), "Font family for fantasy fonts."), ('web-size-minimum', - SettingValue(types.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), - ''), + SettingValue( + typ.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), ''), "The hard minimum font size."), ('web-size-minimum-logical', - SettingValue(types.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), - ''), + SettingValue( + typ.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), ''), "The minimum logical font size that is applied when zooming out."), ('web-size-default', - SettingValue(types.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), - ''), "The default font size for regular text."), + SettingValue( + typ.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), ''), + "The default font size for regular text."), ('web-size-default-fixed', - SettingValue(types.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), - ''), + SettingValue( + typ.Int(none_ok=True, minval=1, maxval=MAXVALS['int']), ''), "The default font size for fixed-pitch text."), )), ]) diff --git a/qutebrowser/config/conftypes.py b/qutebrowser/config/conftypes.py index d1509324f..05d6c69e2 100644 --- a/qutebrowser/config/conftypes.py +++ b/qutebrowser/config/conftypes.py @@ -23,13 +23,13 @@ import re import shlex import codecs import os.path -from sre_constants import error as RegexError +import sre_constants from PyQt5.QtCore import QUrl from PyQt5.QtGui import QColor, QFont from PyQt5.QtNetwork import QNetworkProxy -import qutebrowser.commands.utils as cmdutils +from qutebrowser.commands import utils as cmdutils SYSTEM_PROXY = object() # Return value for Proxy type @@ -734,7 +734,7 @@ class Regex(BaseType): raise ValidationError(value, "may not be empty!") try: re.compile(value, self.flags) - except RegexError as e: + except sre_constants.error as e: raise ValidationError(value, "must be a valid regex - " + str(e)) def transform(self, value): @@ -762,7 +762,7 @@ class RegexList(List): def validate(self, value): try: vals = self.transform(value) - except RegexError as e: + except sre_constants.error as e: raise ValidationError(value, "must be a list valid regexes - " + str(e)) if not self.none_ok and None in vals: diff --git a/qutebrowser/config/iniparsers.py b/qutebrowser/config/iniparsers.py index 3386a6360..7e238320e 100644 --- a/qutebrowser/config/iniparsers.py +++ b/qutebrowser/config/iniparsers.py @@ -21,12 +21,12 @@ import os import os.path -from configparser import ConfigParser +import configparser -import qutebrowser.utils.log as log +from qutebrowser.utils import log -class ReadConfigParser(ConfigParser): +class ReadConfigParser(configparser.ConfigParser): """Our own ConfigParser subclass to read the main config. diff --git a/qutebrowser/config/lineparser.py b/qutebrowser/config/lineparser.py index d37d98aee..78bca1383 100644 --- a/qutebrowser/config/lineparser.py +++ b/qutebrowser/config/lineparser.py @@ -24,7 +24,7 @@ import os.path from PyQt5.QtCore import pyqtSlot -import qutebrowser.utils.log as log +from qutebrowser.utils import log class LineConfigParser: @@ -82,7 +82,7 @@ class LineConfigParser: log.destroy.debug("No data to save.") return # We need to import this here because config needs LineConfigParser. - import qutebrowser.config.config as config + from qutebrowser.config import config limit = -1 if self._limit is None else config.get(*self._limit) if limit == 0: return @@ -98,7 +98,7 @@ class LineConfigParser: if self._limit is None: return # We need to import this here because config needs LineConfigParser. - import qutebrowser.config.config as config + from qutebrowser.config import config value = config.get(section, option) if (section, option) == self._limit and value == 0: if os.path.exists(self._configfile): diff --git a/qutebrowser/config/sections.py b/qutebrowser/config/sections.py index d6b7049b4..9d84bec01 100644 --- a/qutebrowser/config/sections.py +++ b/qutebrowser/config/sections.py @@ -19,9 +19,9 @@ """Setting sections used for qutebrowser.""" -from collections import OrderedDict, ChainMap +import collections -from qutebrowser.config.value import SettingValue +from qutebrowser.config import value as confvalue class Section: @@ -108,7 +108,7 @@ class KeyValue(Section): super().__init__() if not defaults: return - self.values = OrderedDict() + self.values = collections.OrderedDict() for (k, v, desc) in defaults: assert k not in self.values, k self.values[k] = v @@ -160,17 +160,17 @@ class ValueList(Section): self._ordered_value_cache = None self.keytype = keytype self.valtype = valtype - self.layers = OrderedDict([ - ('default', OrderedDict()), - ('conf', OrderedDict()), - ('temp', OrderedDict()), + self.layers = collections.OrderedDict([ + ('default', collections.OrderedDict()), + ('conf', collections.OrderedDict()), + ('temp', collections.OrderedDict()), ]) defaultlayer = self.layers['default'] for key, value in defaults: assert key not in defaultlayer, key - defaultlayer[key] = SettingValue(valtype, value) - self.values = ChainMap(self.layers['temp'], self.layers['conf'], - self.layers['default']) + defaultlayer[key] = confvalue.SettingValue(valtype, value) + self.values = collections.ChainMap( + self.layers['temp'], self.layers['conf'], self.layers['default']) @property def ordered_values(self): @@ -180,7 +180,7 @@ class ValueList(Section): iterating/items/etc. when order matters. """ if self._ordered_value_cache is None: - self._ordered_value_cache = OrderedDict() + self._ordered_value_cache = collections.OrderedDict() for layer in self.layers.values(): self._ordered_value_cache.update(layer) return self._ordered_value_cache @@ -190,14 +190,15 @@ class ValueList(Section): if key in self.layers[layer]: self.layers[layer][key].setv(layer, value, interpolated) else: - val = SettingValue(self.valtype) + val = confvalue.SettingValue(self.valtype) val.setv(layer, value, interpolated) self.layers[layer][key] = val self._ordered_value_cache = None def dump_userconfig(self): changed = [] - mapping = ChainMap(self.layers['temp'], self.layers['conf']) + mapping = collections.ChainMap( + self.layers['temp'], self.layers['conf']) for k, v in mapping.items(): try: if v.value != self.layers['default'][k].value: diff --git a/qutebrowser/config/style.py b/qutebrowser/config/style.py index 7c6827529..77aeb1956 100644 --- a/qutebrowser/config/style.py +++ b/qutebrowser/config/style.py @@ -24,13 +24,13 @@ Module attributes: _fontdict: The global cached FontDict. """ -from functools import partial +import functools from PyQt5.QtGui import QColor -import qutebrowser.config.config as config +from qutebrowser.config import config +from qutebrowser.utils import misc as utils from qutebrowser.utils.log import style as logger -from qutebrowser.utils.misc import compact_text _colordict = None @@ -68,9 +68,10 @@ def set_register_stylesheet(obj): """ qss = get_stylesheet(obj.STYLESHEET) logger.debug("stylesheet for {}: {}".format(obj.__class__.__name__, - compact_text(qss))) + utils.compact_text(qss))) obj.setStyleSheet(qss) - config.instance().changed.connect(partial(_update_stylesheet, obj)) + config.instance().changed.connect( + functools.partial(_update_stylesheet, obj)) def _update_stylesheet(obj, _section, _option): diff --git a/qutebrowser/config/value.py b/qutebrowser/config/value.py index 0ff0ace68..f12703b88 100644 --- a/qutebrowser/config/value.py +++ b/qutebrowser/config/value.py @@ -19,7 +19,7 @@ """A single value (with multiple layers possibly) in the config.""" -from collections import OrderedDict +import collections class SettingValue: @@ -43,7 +43,8 @@ class SettingValue: default: Raw value to set. """ self.typ = typ - self._values = OrderedDict.fromkeys(['temp', 'conf', 'default']) + self._values = collections.OrderedDict.fromkeys( + ['temp', 'conf', 'default']) self._values['default'] = default def __str__(self): @@ -72,7 +73,7 @@ class SettingValue: startlayer: The first layer to include. """ idx = list(self._values.keys()).index(startlayer) - d = OrderedDict(list(self._values.items())[idx:]) + d = collections.OrderedDict(list(self._values.items())[idx:]) return d def get_first_value(self, startlayer=None): diff --git a/qutebrowser/config/websettings.py b/qutebrowser/config/websettings.py index f25102824..7c94a858c 100644 --- a/qutebrowser/config/websettings.py +++ b/qutebrowser/config/websettings.py @@ -30,11 +30,11 @@ from PyQt5.QtCore import pyqtSlot from PyQt5.QtWebKit import QWebSettings from PyQt5.QtCore import QStandardPaths -import qutebrowser.config.config as config -from qutebrowser.utils.usertypes import enum -from qutebrowser.utils.misc import get_standard_dir +from qutebrowser.config import config +from qutebrowser.utils import usertypes +from qutebrowser.utils import misc as utils -MapType = enum('MapType', 'attribute', 'setter', 'static_setter') +MapType = usertypes.enum('MapType', 'attribute', 'setter', 'static_setter') MAPPINGS = { @@ -177,7 +177,7 @@ def _set_setting(typ, arg, value): def init(): """Initialize the global QWebSettings.""" global settings - cachedir = get_standard_dir(QStandardPaths.CacheLocation) + cachedir = utils.get_standard_dir(QStandardPaths.CacheLocation) QWebSettings.enablePersistentStorage(cachedir) settings = QWebSettings.globalSettings() for sectname, section in MAPPINGS.items(): diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py index 2af815971..34f74e896 100644 --- a/qutebrowser/keyinput/basekeyparser.py +++ b/qutebrowser/keyinput/basekeyparser.py @@ -21,14 +21,14 @@ import re import string -from functools import partial +import functools from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QObject -import qutebrowser.config.config as config -from qutebrowser.utils.usertypes import enum, Timer +from qutebrowser.config import config +from qutebrowser.utils import usertypes +from qutebrowser.utils import misc as utils from qutebrowser.utils.log import keyboard as logger -from qutebrowser.utils.misc import keyevent_to_string, normalize_keystr class BaseKeyParser(QObject): @@ -71,8 +71,9 @@ class BaseKeyParser(QObject): keystring_updated = pyqtSignal(str) do_log = True - Match = enum('Match', 'partial', 'definitive', 'ambiguous', 'none') - Type = enum('Type', 'chain', 'special') + Match = usertypes.enum('Match', 'partial', 'definitive', 'ambiguous', + 'none') + Type = usertypes.enum('Type', 'chain', 'special') def __init__(self, parent=None, supports_count=None, supports_chains=False): @@ -113,7 +114,7 @@ class BaseKeyParser(QObject): Return: True if event has been handled, False otherwise. """ - binding = keyevent_to_string(e) + binding = utils.keyevent_to_string(e) if binding is None: self._debug_log("Ignoring only-modifier keyeevent.") return False @@ -266,11 +267,11 @@ class BaseKeyParser(QObject): # execute in `time' ms self._debug_log("Scheduling execution of {} in {}ms".format( binding, time)) - self._timer = Timer(self, 'ambigious_match') + self._timer = usertypes.Timer(self, 'ambigious_match') self._timer.setSingleShot(True) self._timer.setInterval(time) - self._timer.timeout.connect(partial(self.delayed_exec, binding, - count)) + self._timer.timeout.connect( + functools.partial(self.delayed_exec, binding, count)) self._timer.start() def delayed_exec(self, command, count): @@ -329,7 +330,7 @@ class BaseKeyParser(QObject): if not cmd: continue elif key.startswith('<') and key.endswith('>'): - keystr = normalize_keystr(key[1:-1]) + keystr = utils.normalize_keystr(key[1:-1]) self.special_bindings[keystr] = cmd elif self._supports_chains: self.bindings[key] = cmd diff --git a/qutebrowser/keyinput/keyparser.py b/qutebrowser/keyinput/keyparser.py index b2a5e7a7d..65010a0b6 100644 --- a/qutebrowser/keyinput/keyparser.py +++ b/qutebrowser/keyinput/keyparser.py @@ -20,10 +20,9 @@ """Advanced keyparsers.""" from qutebrowser.keyinput.basekeyparser import BaseKeyParser -import qutebrowser.utils.message as message - -from qutebrowser.commands.runners import CommandRunner -from qutebrowser.commands.exceptions import CommandMetaError, CommandError +from qutebrowser.utils import message +from qutebrowser.commands import runners +from qutebrowser.commands import exceptions as cmdexc class CommandKeyParser(BaseKeyParser): @@ -37,12 +36,12 @@ class CommandKeyParser(BaseKeyParser): def __init__(self, parent=None, supports_count=None, supports_chains=False): super().__init__(parent, supports_count, supports_chains) - self.commandrunner = CommandRunner() + self.commandrunner = runners.CommandRunner() def execute(self, cmdstr, _keytype, count=None): try: self.commandrunner.run(cmdstr, count) - except (CommandMetaError, CommandError) as e: + except (cmdexc.CommandMetaError, cmdexc.CommandError) as e: message.error(e, immediately=True) diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py index 135fce987..f5b34a808 100644 --- a/qutebrowser/keyinput/modeman.py +++ b/qutebrowser/keyinput/modeman.py @@ -27,11 +27,11 @@ from PyQt5.QtGui import QWindow from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent from PyQt5.QtWidgets import QApplication -import qutebrowser.config.config as config -import qutebrowser.commands.utils as cmdutils +from qutebrowser.config import config +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.utils import usertypes from qutebrowser.utils.log import modes as logger -from qutebrowser.utils.usertypes import KeyMode -from qutebrowser.commands.exceptions import CommandError class ModeLockedError(Exception): @@ -96,8 +96,8 @@ class ModeManager(QObject): arg: The mode which has been left. """ - entered = pyqtSignal(KeyMode) - left = pyqtSignal(KeyMode) + entered = pyqtSignal(usertypes.KeyMode) + left = pyqtSignal(usertypes.KeyMode) def __init__(self, parent=None): super().__init__(parent) @@ -142,7 +142,7 @@ class ModeManager(QObject): True if event should be filtered, False otherwise. """ handler = self._handlers[self.mode] - if self.mode != KeyMode.insert: + if self.mode != usertypes.KeyMode.insert: logger.debug("got keypress in mode {} - calling handler {}".format( self.mode, handler.__qualname__)) handled = handler(event) if handler is not None else False @@ -161,7 +161,7 @@ class ModeManager(QObject): if not filter_this: self._releaseevents_to_pass.append(event) - if self.mode != KeyMode.insert: + if self.mode != usertypes.KeyMode.insert: logger.debug("handled: {}, forward-unbound-keys: {}, passthrough: " "{}, is_non_alnum: {} --> filter: {}".format( handled, self._forward_unbound_keys, @@ -186,7 +186,7 @@ class ModeManager(QObject): filter_this = False else: filter_this = True - if self.mode != KeyMode.insert: + if self.mode != usertypes.KeyMode.insert: logger.debug("filter: {}".format(filter_this)) return filter_this @@ -199,7 +199,7 @@ class ModeManager(QObject): passthrough: Whether to pass keybindings in this mode through to the widgets. """ - if not isinstance(mode, KeyMode): + if not isinstance(mode, usertypes.KeyMode): raise TypeError("Mode {} is no KeyMode member!".format(mode)) self._handlers[mode] = handler if passthrough: @@ -215,7 +215,7 @@ class ModeManager(QObject): Emit: entered: With the new mode name. """ - if not isinstance(mode, KeyMode): + if not isinstance(mode, usertypes.KeyMode): raise TypeError("Mode {} is no KeyMode member!".format(mode)) if self.locked: logger.debug("Not entering mode {} because mode is locked to " @@ -241,9 +241,9 @@ class ModeManager(QObject): mode: The mode to enter. """ try: - m = KeyMode[mode] + m = usertypes.KeyMode[mode] except KeyError: - raise CommandError("Mode {} does not exist!".format(mode)) + raise cmdexc.CommandError("Mode {} does not exist!".format(mode)) self.enter(m, 'command') def leave(self, mode, reason=None): @@ -267,10 +267,10 @@ class ModeManager(QObject): self.left.emit(mode) @cmdutils.register(instance='modeman', name='leave-mode', - not_modes=[KeyMode.normal], hide=True) + not_modes=[usertypes.KeyMode.normal], hide=True) def leave_current_mode(self): """Leave the mode we're currently in.""" - if self.mode == KeyMode.normal: + if self.mode == usertypes.KeyMode.normal: raise ValueError("Can't leave normal mode!") self.leave(self.mode, 'leave current') diff --git a/qutebrowser/keyinput/modeparsers.py b/qutebrowser/keyinput/modeparsers.py index 46dfd9265..d6b411b23 100644 --- a/qutebrowser/keyinput/modeparsers.py +++ b/qutebrowser/keyinput/modeparsers.py @@ -25,18 +25,18 @@ Module attributes: from PyQt5.QtCore import pyqtSignal, Qt -import qutebrowser.utils.message as message -import qutebrowser.config.config as config -from qutebrowser.keyinput.keyparser import CommandKeyParser -from qutebrowser.utils.usertypes import enum +from qutebrowser.utils import message +from qutebrowser.config import config +from qutebrowser.keyinput import keyparser +from qutebrowser.utils import usertypes from qutebrowser.utils.log import keyboard as logger STARTCHARS = ":/?" -LastPress = enum('LastPress', 'none', 'filtertext', 'keystring') +LastPress = usertypes.enum('LastPress', 'none', 'filtertext', 'keystring') -class NormalKeyParser(CommandKeyParser): +class NormalKeyParser(keyparser.CommandKeyParser): """KeyParser for normalmode with added STARTCHARS detection.""" @@ -63,7 +63,7 @@ class NormalKeyParser(CommandKeyParser): return super()._handle_single_key(e) -class PromptKeyParser(CommandKeyParser): +class PromptKeyParser(keyparser.CommandKeyParser): """KeyParser for yes/no prompts.""" @@ -77,7 +77,7 @@ class PromptKeyParser(CommandKeyParser): return '<{}>'.format(self.__class__.__name__) -class HintKeyParser(CommandKeyParser): +class HintKeyParser(keyparser.CommandKeyParser): """KeyChainParser for hints. diff --git a/qutebrowser/models/basecompletion.py b/qutebrowser/models/basecompletion.py index c72f558bc..4e66b95a3 100644 --- a/qutebrowser/models/basecompletion.py +++ b/qutebrowser/models/basecompletion.py @@ -26,11 +26,11 @@ Module attributes: from PyQt5.QtCore import Qt from PyQt5.QtGui import QStandardItemModel, QStandardItem -from qutebrowser.utils.usertypes import enum -from qutebrowser.utils.qt import qt_ensure_valid +from qutebrowser.utils import usertypes +from qutebrowser.utils import qt as qtutils -Role = enum('Role', 'marks', 'sort', start=Qt.UserRole, is_int=True) +Role = usertypes.enum('Role', 'marks', 'sort', start=Qt.UserRole, is_int=True) class BaseCompletionModel(QStandardItemModel): @@ -74,7 +74,7 @@ class BaseCompletionModel(QStandardItemModel): index: A QModelIndex of the item to mark. needle: The string to mark. """ - qt_ensure_valid(index) + qtutils.qt_ensure_valid(index) haystack = self.data(index) marks = self._get_marks(needle, haystack) ok = self.setData(index, marks, Role.marks) @@ -132,7 +132,7 @@ class BaseCompletionModel(QStandardItemModel): Return: The item flags, or Qt.NoItemFlags on error. """ - qt_ensure_valid(index) + qtutils.qt_ensure_valid(index) if index.parent().isValid(): # item return Qt.ItemIsEnabled | Qt.ItemIsSelectable diff --git a/qutebrowser/models/cmdhistory.py b/qutebrowser/models/cmdhistory.py index f4d1cc523..9e00b7e99 100644 --- a/qutebrowser/models/cmdhistory.py +++ b/qutebrowser/models/cmdhistory.py @@ -21,7 +21,7 @@ from PyQt5.QtCore import pyqtSlot -from qutebrowser.utils.usertypes import NeighborList +from qutebrowser.utils import usertypes from qutebrowser.utils.log import misc as logger @@ -85,7 +85,7 @@ class History: items = self.history if not items: raise HistoryEmptyError - self._tmphist = NeighborList(items) + self._tmphist = usertypes.NeighborList(items) return self._tmphist.lastitem() @pyqtSlot() diff --git a/qutebrowser/models/completion.py b/qutebrowser/models/completion.py index 1f385ca07..c57ad1adc 100644 --- a/qutebrowser/models/completion.py +++ b/qutebrowser/models/completion.py @@ -21,15 +21,14 @@ from PyQt5.QtCore import pyqtSlot, Qt, QCoreApplication -import qutebrowser.config.config as config -import qutebrowser.config.configdata as configdata -from qutebrowser.models.basecompletion import BaseCompletionModel -from qutebrowser.commands.utils import cmd_dict +from qutebrowser.config import config, configdata +from qutebrowser.models import basecompletion +from qutebrowser.commands import utils as cmdutils +from qutebrowser.utils import qt as qtutils from qutebrowser.utils.log import completion as logger -from qutebrowser.utils.qt import qt_ensure_valid -class SettingSectionCompletionModel(BaseCompletionModel): +class SettingSectionCompletionModel(basecompletion.BaseCompletionModel): """A CompletionModel filled with settings sections.""" @@ -43,7 +42,7 @@ class SettingSectionCompletionModel(BaseCompletionModel): self.new_item(cat, name, desc) -class SettingOptionCompletionModel(BaseCompletionModel): +class SettingOptionCompletionModel(basecompletion.BaseCompletionModel): """A CompletionModel filled with settings and their descriptions. @@ -88,14 +87,14 @@ class SettingOptionCompletionModel(BaseCompletionModel): return val = config.get(section, option, raw=True) idx = item.index() - qt_ensure_valid(idx) + qtutils.qt_ensure_valid(idx) ok = self.setData(idx, val, Qt.DisplayRole) if not ok: raise ValueError("Setting data failed! (section: {}, option: {}, " "value: {})".format(section, option, val)) -class SettingValueCompletionModel(BaseCompletionModel): +class SettingValueCompletionModel(basecompletion.BaseCompletionModel): """A CompletionModel filled with setting values. @@ -139,14 +138,14 @@ class SettingValueCompletionModel(BaseCompletionModel): if not value: value = '""' idx = self.cur_item.index() - qt_ensure_valid(idx) + qtutils.qt_ensure_valid(idx) ok = self.setData(idx, value, Qt.DisplayRole) if not ok: raise ValueError("Setting data failed! (section: {}, option: {}, " "value: {})".format(section, option, value)) -class CommandCompletionModel(BaseCompletionModel): +class CommandCompletionModel(basecompletion.BaseCompletionModel): """A CompletionModel filled with all commands and descriptions.""" @@ -154,9 +153,9 @@ class CommandCompletionModel(BaseCompletionModel): def __init__(self, parent=None): super().__init__(parent) - assert cmd_dict + assert cmdutils.cmd_dict cmdlist = [] - for obj in set(cmd_dict.values()): + for obj in set(cmdutils.cmd_dict.values()): if obj.hide or (obj.debug and not QCoreApplication.instance().args.debug): pass diff --git a/qutebrowser/models/completionfilter.py b/qutebrowser/models/completionfilter.py index 1156500b8..bc33469c6 100644 --- a/qutebrowser/models/completionfilter.py +++ b/qutebrowser/models/completionfilter.py @@ -25,9 +25,9 @@ Contains: from PyQt5.QtCore import QSortFilterProxyModel, QModelIndex -from qutebrowser.models.basecompletion import Role +from qutebrowser.models import basecompletion as completion +from qutebrowser.utils import qt as qtutils from qutebrowser.utils.log import completion as logger -from qutebrowser.utils.qt import qt_ensure_valid class CompletionFilterModel(QSortFilterProxyModel): @@ -81,7 +81,7 @@ class CompletionFilterModel(QSortFilterProxyModel): count = 0 for i in range(self.rowCount()): cat = self.index(i, 0) - qt_ensure_valid(cat) + qtutils.qt_ensure_valid(cat) count += self.rowCount(cat) return count @@ -89,10 +89,10 @@ class CompletionFilterModel(QSortFilterProxyModel): """Return the first item in the model.""" for i in range(self.rowCount()): cat = self.index(i, 0) - qt_ensure_valid(cat) + qtutils.qt_ensure_valid(cat) if cat.model().hasChildren(cat): index = self.index(0, 0, cat) - qt_ensure_valid(index) + qtutils.qt_ensure_valid(index) return index return QModelIndex() @@ -100,10 +100,10 @@ class CompletionFilterModel(QSortFilterProxyModel): """Return the last item in the model.""" for i in range(self.rowCount() - 1, -1, -1): cat = self.index(i, 0) - qt_ensure_valid(cat) + qtutils.qt_ensure_valid(cat) if cat.model().hasChildren(cat): index = self.index(self.rowCount(cat) - 1, 0, cat) - qt_ensure_valid(index) + qtutils.qt_ensure_valid(index) return index return QModelIndex() @@ -111,12 +111,12 @@ class CompletionFilterModel(QSortFilterProxyModel): """Mark the given text in all visible items.""" for i in range(self.rowCount()): cat = self.index(i, 0) - qt_ensure_valid(cat) + qtutils.qt_ensure_valid(cat) for k in range(self.rowCount(cat)): index = self.index(k, 0, cat) - qt_ensure_valid(index) + qtutils.qt_ensure_valid(index) index = self.mapToSource(index) - qt_ensure_valid(index) + qtutils.qt_ensure_valid(index) self.srcmodel.mark_item(index, text) def setSourceModel(self, model): @@ -142,7 +142,7 @@ class CompletionFilterModel(QSortFilterProxyModel): if parent == QModelIndex(): return True idx = self.srcmodel.index(row, 0, parent) - qt_ensure_valid(idx) + qtutils.qt_ensure_valid(idx) data = self.srcmodel.data(idx) # TODO more sophisticated filtering if not self.pattern: @@ -162,11 +162,11 @@ class CompletionFilterModel(QSortFilterProxyModel): Return: True if left < right, else False """ - qt_ensure_valid(lindex) - qt_ensure_valid(rindex) + qtutils.qt_ensure_valid(lindex) + qtutils.qt_ensure_valid(rindex) - left_sort = self.srcmodel.data(lindex, role=Role.sort) - right_sort = self.srcmodel.data(rindex, role=Role.sort) + left_sort = self.srcmodel.data(lindex, role=completion.Role.sort) + right_sort = self.srcmodel.data(rindex, role=completion.Role.sort) if left_sort is not None and right_sort is not None: return left_sort < right_sort diff --git a/qutebrowser/models/downloadmodel.py b/qutebrowser/models/downloadmodel.py index 6cd5dc5c3..0c58985e7 100644 --- a/qutebrowser/models/downloadmodel.py +++ b/qutebrowser/models/downloadmodel.py @@ -23,12 +23,12 @@ from PyQt5.QtCore import (pyqtSlot, Qt, QVariant, QAbstractListModel, QModelIndex) from PyQt5.QtWidgets import QApplication -import qutebrowser.config.config as config -from qutebrowser.utils.usertypes import enum -from qutebrowser.utils.qt import qt_ensure_valid +from qutebrowser.config import config +from qutebrowser.utils import usertypes +from qutebrowser.utils import qt as qtutils -Role = enum('Role', 'item', start=Qt.UserRole, is_int=True) +Role = usertypes.enum('Role', 'item', start=Qt.UserRole, is_int=True) class DownloadModel(QAbstractListModel): @@ -57,7 +57,7 @@ class DownloadModel(QAbstractListModel): def on_data_changed(self, idx): """Update view when DownloadManager data changed.""" model_idx = self.index(idx, 0) - qt_ensure_valid(model_idx) + qtutils.qt_ensure_valid(model_idx) self.dataChanged.emit(model_idx, model_idx) def last_index(self): @@ -79,7 +79,7 @@ class DownloadModel(QAbstractListModel): def data(self, index, role): """Download data from DownloadManager.""" - qt_ensure_valid(index) + qtutils.qt_ensure_valid(index) if index.parent().isValid() or index.column() != 0: return QVariant() diff --git a/qutebrowser/network/networkmanager.py b/qutebrowser/network/networkmanager.py index c3df0014f..83f5563eb 100644 --- a/qutebrowser/network/networkmanager.py +++ b/qutebrowser/network/networkmanager.py @@ -29,12 +29,9 @@ except ImportError: else: SSL_AVAILABLE = QSslSocket.supportsSsl() -import qutebrowser.config.config as config -import qutebrowser.utils.message as message -import qutebrowser.utils.log as log -from qutebrowser.network.qutescheme import QuteSchemeHandler -from qutebrowser.network.schemehandler import ErrorNetworkReply -from qutebrowser.utils.usertypes import PromptMode +from qutebrowser.config import config +from qutebrowser.utils import message, log, usertypes +from qutebrowser.network import qutescheme, schemehandler class NetworkManager(QNetworkAccessManager): @@ -52,7 +49,7 @@ class NetworkManager(QNetworkAccessManager): super().__init__(parent) self._requests = [] self._scheme_handlers = { - 'qute': QuteSchemeHandler(), + 'qute': qutescheme.QuteSchemeHandler(), } cookiejar = QCoreApplication.instance().cookiejar parent = cookiejar.parent() @@ -105,14 +102,14 @@ class NetworkManager(QNetworkAccessManager): def on_authentication_required(self, _reply, authenticator): """Called when a website needs authentication.""" answer = message.ask("Username ({}):".format(authenticator.realm()), - mode=PromptMode.user_pwd) + mode=usertypes.PromptMode.user_pwd) self._fill_authenticator(authenticator, answer) @pyqtSlot('QNetworkProxy', 'QAuthenticator') def on_proxy_authentication_required(self, _proxy, authenticator): """Called when a proxy needs authentication.""" answer = message.ask("Proxy username ({}):".format( - authenticator.realm()), mode=PromptMode.user_pwd) + authenticator.realm()), mode=usertypes.PromptMode.user_pwd) self._fill_authenticator(authenticator, answer) def createRequest(self, op, req, outgoing_data): @@ -131,7 +128,7 @@ class NetworkManager(QNetworkAccessManager): """ scheme = req.url().scheme() if scheme == 'https' and not SSL_AVAILABLE: - return ErrorNetworkReply( + return schemehandler.ErrorNetworkReply( req, "SSL is not supported by the installed Qt library!", QNetworkReply.ProtocolUnknownError) elif scheme in self._scheme_handlers: diff --git a/qutebrowser/network/proxy.py b/qutebrowser/network/proxy.py index 75513ca0f..d1f97613f 100644 --- a/qutebrowser/network/proxy.py +++ b/qutebrowser/network/proxy.py @@ -19,11 +19,11 @@ """Handling of proxies.""" -import qutebrowser.config.config as config -from qutebrowser.config.conftypes import SYSTEM_PROXY from PyQt5.QtNetwork import QNetworkProxyFactory +from qutebrowser.config import config, conftypes + def init(): """Set the application wide proxy factory.""" @@ -44,7 +44,7 @@ class ProxyFactory(QNetworkProxyFactory): A list of QNetworkProxy objects in order of preference. """ proxy = config.get('network', 'proxy') - if proxy is SYSTEM_PROXY: + if proxy is conftypes.SYSTEM_PROXY: return QNetworkProxyFactory.systemProxyForQuery(query) else: return [proxy] diff --git a/qutebrowser/network/qutescheme.py b/qutebrowser/network/qutescheme.py index 34fa86a86..1025440ea 100644 --- a/qutebrowser/network/qutescheme.py +++ b/qutebrowser/network/qutescheme.py @@ -29,12 +29,10 @@ import html as pyhtml from PyQt5.QtNetwork import QNetworkReply import qutebrowser -import qutebrowser.utils.log as logutils -import qutebrowser.utils.version as version -from qutebrowser.network.schemehandler import (SchemeHandler, - SpecialNetworkReply, - ErrorNetworkReply) -from qutebrowser.utils.misc import read_file +from qutebrowser.network import schemehandler +from qutebrowser.utils import version +from qutebrowser.utils import log as logutils +from qutebrowser.utils import misc as utils _HTML_TEMPLATE = """ @@ -73,7 +71,7 @@ def _get_html(title, snippet, head=None): return html -class QuteSchemeHandler(SchemeHandler): +class QuteSchemeHandler(schemehandler.SchemeHandler): """Scheme handler for qute: URLs.""" @@ -97,12 +95,13 @@ class QuteSchemeHandler(SchemeHandler): except AttributeError: errorstr = "No handler found for {}!".format( request.url().toDisplayString()) - return ErrorNetworkReply(request, errorstr, - QNetworkReply.ContentNotFoundError, - self.parent()) + return schemehandler.ErrorNetworkReply( + request, errorstr, QNetworkReply.ContentNotFoundError, + self.parent()) else: data = handler() - return SpecialNetworkReply(request, data, 'text/html', self.parent()) + return schemehandler.SpecialNetworkReply( + request, data, 'text/html', self.parent()) class QuteHandlers: @@ -171,4 +170,4 @@ class QuteHandlers: @classmethod def gpl(cls): """Handler for qute:gpl. Return HTML content as bytes.""" - return read_file('html/COPYING.html').encode('ASCII') + return utils.read_file('html/COPYING.html').encode('ASCII') diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py index 24032cfd2..88b815277 100644 --- a/qutebrowser/qutebrowser.py +++ b/qutebrowser/qutebrowser.py @@ -37,14 +37,14 @@ except ImportError: sys.exit(100) check_python_version() -from argparse import ArgumentParser -import qutebrowser.utils.earlyinit as earlyinit +import argparse +from qutebrowser.utils import earlyinit def get_argparser(): """Get the argparse parser.""" - parser = ArgumentParser("usage: qutebrowser", - description=qutebrowser.__description__) + parser = argparse.ArgumentParser("usage: qutebrowser", + description=qutebrowser.__description__) parser.add_argument('-c', '--confdir', help="Set config directory (empty " "for no config storage)") parser.add_argument('-V', '--version', help="Show version and quit.", @@ -103,7 +103,7 @@ def main(): earlyinit.check_pyqt_core() # We do this import late as we need to do the version checking first. # Note we may not import webkit stuff yet as fix_harfbuzz didn't run. - import qutebrowser.utils.log as log + from qutebrowser.utils import log log.init_log(args) log.init.debug("Log initialized.") log.init.debug("Doing early init.") @@ -113,10 +113,10 @@ def main(): earlyinit.check_pkg_resources() earlyinit.check_pypeg2() # We do this import late as we need to fix harfbuzz first. - from qutebrowser.app import Application - from qutebrowser.utils.debug import trace_lines + from qutebrowser import app + from qutebrowser.utils import debug import PyQt5.QtWidgets as QtWidgets - app = Application(args) + app = app.Application(args) # We set qApp explicitely here to reduce the risk of segfaults while # quitting. # See https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/561303/comments/7 @@ -127,6 +127,6 @@ def main(): ret = app.exec_() if args.debug_exit: print("Now logging late shutdown.", file=sys.stderr) - trace_lines(True) + debug.trace_lines(True) QtWidgets.qApp = None return ret diff --git a/qutebrowser/test/config/test_conftypes.py b/qutebrowser/test/config/test_conftypes.py index 2d017b05d..3b39e6632 100644 --- a/qutebrowser/test/config/test_conftypes.py +++ b/qutebrowser/test/config/test_conftypes.py @@ -19,13 +19,13 @@ """Tests for qutebrowser.config.conftypes.""" import unittest -import unittest.mock as mock import re -from collections import namedtuple +import collections +from unittest import mock -import qutebrowser.config.conftypes as conftypes -from qutebrowser.test.stubs import FakeCmdUtils, FakeCommand -from qutebrowser.utils.debug import qenum_key +from qutebrowser.config import conftypes +from qutebrowser.test import stubs +from qutebrowser.utils import debug from PyQt5.QtCore import QUrl from PyQt5.QtGui import QColor, QFont @@ -37,9 +37,10 @@ class Font(QFont): """A QFont with a nicer repr().""" def __repr__(self): + weight = debug.qenum_key(QFont, self.weight(), add_base=True, + klass=QFont.Weight) return ''.format( - self.family(), self.pointSize(), self.pixelSize(), - qenum_key(QFont, self.weight(), add_base=True, klass=QFont.Weight), + self.family(), self.pointSize(), self.pixelSize(), weight, self.style()) @classmethod @@ -853,10 +854,10 @@ class CommandTests(unittest.TestCase): def setUp(self): self.old_cmdutils = conftypes.cmdutils commands = { - 'cmd1': FakeCommand("desc 1"), - 'cmd2': FakeCommand("desc 2"), + 'cmd1': stubs.FakeCommand("desc 1"), + 'cmd2': stubs.FakeCommand("desc 2"), } - conftypes.cmdutils = FakeCmdUtils(commands) + conftypes.cmdutils = stubs.FakeCmdUtils(commands) self.t = conftypes.Command() def tearDown(self): @@ -1057,7 +1058,8 @@ class QssColorTests(QtColorTests): self.assertEqual(self.t.transform(v), v, v) -FontDesc = namedtuple('FontDesc', ['style', 'weight', 'pt', 'px', 'family']) +FontDesc = collections.namedtuple('FontDesc', + ['style', 'weight', 'pt', 'px', 'family']) class FontTests(unittest.TestCase): diff --git a/qutebrowser/test/helpers.py b/qutebrowser/test/helpers.py index 03f166513..5434c9b58 100644 --- a/qutebrowser/test/helpers.py +++ b/qutebrowser/test/helpers.py @@ -20,13 +20,13 @@ """Helpers needed by tests.""" import os -from contextlib import contextmanager -from unittest.mock import create_autospec +import contextlib +from unittest import mock from PyQt5.QtGui import QKeyEvent -@contextmanager +@contextlib.contextmanager def environ_set_temp(name, value): """Set a temporary environment variable.""" try: @@ -43,8 +43,8 @@ def environ_set_temp(name, value): def fake_keyevent(key, modifiers=0, text=''): """Generate a new fake QKeyPressEvent.""" - mock = create_autospec(QKeyEvent, instance=True) - mock.key.return_value = key - mock.modifiers.return_value = modifiers - mock.text.return_value = text - return mock + evtmock = mock.create_autospec(QKeyEvent, instance=True) + evtmock.key.return_value = key + evtmock.modifiers.return_value = modifiers + evtmock.text.return_value = text + return evtmock diff --git a/qutebrowser/test/keyinput/test_basekeyparser.py b/qutebrowser/test/keyinput/test_basekeyparser.py index cc5f430dc..ebe806cc4 100644 --- a/qutebrowser/test/keyinput/test_basekeyparser.py +++ b/qutebrowser/test/keyinput/test_basekeyparser.py @@ -23,14 +23,14 @@ import logging import unittest -from unittest.mock import Mock, patch - -import qutebrowser.keyinput.basekeyparser as basekeyparser -from qutebrowser.test.stubs import ConfigStub -from qutebrowser.test.helpers import fake_keyevent +from unittest import mock from PyQt5.QtCore import Qt +from qutebrowser.keyinput import basekeyparser +from qutebrowser.test import stubs, helpers + + CONFIG = {'test': {'': 'ctrla', 'a': 'a', 'ba': 'ba', @@ -42,7 +42,7 @@ CONFIG = {'test': {'': 'ctrla', def setUpModule(): """Mock out some imports in basekeyparser.""" - basekeyparser.QObject = Mock() + basekeyparser.QObject = mock.Mock() logging.disable(logging.WARNING) @@ -99,8 +99,8 @@ class ReadConfigTests(unittest.TestCase): """Test reading the config.""" def setUp(self): - basekeyparser.config = ConfigStub(CONFIG) - basekeyparser.Timer = Mock() + basekeyparser.config = stubs.ConfigStub(CONFIG) + basekeyparser.usertypes.Timer = mock.Mock() def test_read_config_invalid(self): """Test reading config without setting it before.""" @@ -131,31 +131,32 @@ class SpecialKeysTests(unittest.TestCase): """ def setUp(self): - patcher = patch('qutebrowser.keyinput.basekeyparser.Timer', - autospec=True) + patcher = mock.patch( + 'qutebrowser.keyinput.basekeyparser.usertypes.Timer', + autospec=True) patcher.start() self.addCleanup(patcher.stop) - basekeyparser.config = ConfigStub(CONFIG) + basekeyparser.config = stubs.ConfigStub(CONFIG) self.kp = basekeyparser.BaseKeyParser() - self.kp.execute = Mock() + self.kp.execute = mock.Mock() self.kp.read_config('test') def test_valid_key(self): """Test a valid special keyevent.""" - self.kp.handle(fake_keyevent(Qt.Key_A, Qt.ControlModifier)) - self.kp.handle(fake_keyevent(Qt.Key_X, Qt.ControlModifier)) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, Qt.ControlModifier)) + self.kp.handle(helpers.fake_keyevent(Qt.Key_X, Qt.ControlModifier)) self.kp.execute.assert_called_once_with('ctrla', self.kp.Type.special) def test_invalid_key(self): """Test an invalid special keyevent.""" - self.kp.handle(fake_keyevent(Qt.Key_A, (Qt.ControlModifier | - Qt.AltModifier))) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, (Qt.ControlModifier | + Qt.AltModifier))) self.assertFalse(self.kp.execute.called) def test_keychain(self): """Test a keychain.""" - self.kp.handle(fake_keyevent(Qt.Key_B)) - self.kp.handle(fake_keyevent(Qt.Key_A)) + self.kp.handle(helpers.fake_keyevent(Qt.Key_B)) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A)) self.assertFalse(self.kp.execute.called) @@ -170,35 +171,35 @@ class KeyChainTests(unittest.TestCase): def setUp(self): """Set up mocks and read the test config.""" - basekeyparser.config = ConfigStub(CONFIG) - self.timermock = Mock() - basekeyparser.Timer = Mock(return_value=self.timermock) + basekeyparser.config = stubs.ConfigStub(CONFIG) + self.timermock = mock.Mock() + basekeyparser.usertypes.Timer = mock.Mock(return_value=self.timermock) self.kp = basekeyparser.BaseKeyParser(supports_chains=True, supports_count=False) - self.kp.execute = Mock() + self.kp.execute = mock.Mock() self.kp.read_config('test') def test_valid_special_key(self): """Test valid special key.""" - self.kp.handle(fake_keyevent(Qt.Key_A, Qt.ControlModifier)) - self.kp.handle(fake_keyevent(Qt.Key_X, Qt.ControlModifier)) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, Qt.ControlModifier)) + self.kp.handle(helpers.fake_keyevent(Qt.Key_X, Qt.ControlModifier)) self.kp.execute.assert_called_once_with('ctrla', self.kp.Type.special) self.assertEqual(self.kp._keystring, '') def test_invalid_special_key(self): """Test invalid special key.""" - self.kp.handle(fake_keyevent(Qt.Key_A, (Qt.ControlModifier | - Qt.AltModifier))) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, (Qt.ControlModifier | + Qt.AltModifier))) self.assertFalse(self.kp.execute.called) self.assertEqual(self.kp._keystring, '') def test_keychain(self): """Test valid keychain.""" # Press 'x' which is ignored because of no match - self.kp.handle(fake_keyevent(Qt.Key_X, text='x')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_X, text='x')) # Then start the real chain - self.kp.handle(fake_keyevent(Qt.Key_B, text='b')) - self.kp.handle(fake_keyevent(Qt.Key_A, text='a')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a')) self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, None) self.assertEqual(self.kp._keystring, '') @@ -206,9 +207,10 @@ class KeyChainTests(unittest.TestCase): """Test ambigious keychain.""" # We start with 'a' where the keychain gives us an ambigious result. # Then we check if the timer has been set up correctly - self.kp.handle(fake_keyevent(Qt.Key_A, text='a')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a')) self.assertFalse(self.kp.execute.called) - basekeyparser.Timer.assert_called_once_with(self.kp, 'ambigious_match') + basekeyparser.usertypes.Timer.assert_called_once_with( + self.kp, 'ambigious_match') self.timermock.setSingleShot.assert_called_once_with(True) self.timermock.setInterval.assert_called_once_with(100) self.assertTrue(self.timermock.timeout.connect.called) @@ -216,15 +218,15 @@ class KeyChainTests(unittest.TestCase): self.timermock.start.assert_called_once_with() # Now we type an 'x' and check 'ax' has been executed and the timer # stopped. - self.kp.handle(fake_keyevent(Qt.Key_X, text='x')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_X, text='x')) self.kp.execute.assert_called_once_with('ax', self.kp.Type.chain, None) self.timermock.stop.assert_called_once_with() self.assertEqual(self.kp._keystring, '') def test_invalid_keychain(self): """Test invalid keychain.""" - self.kp.handle(fake_keyevent(Qt.Key_B, text='b')) - self.kp.handle(fake_keyevent(Qt.Key_C, text='c')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_C, text='c')) self.assertEqual(self.kp._keystring, '') @@ -233,53 +235,53 @@ class CountTests(unittest.TestCase): """Test execute() with counts.""" def setUp(self): - basekeyparser.config = ConfigStub(CONFIG) - basekeyparser.Timer = Mock() + basekeyparser.config = stubs.ConfigStub(CONFIG) + basekeyparser.usertypes.Timer = mock.Mock() self.kp = basekeyparser.BaseKeyParser(supports_chains=True, supports_count=True) - self.kp.execute = Mock() + self.kp.execute = mock.Mock() self.kp.read_config('test') def test_no_count(self): """Test with no count added.""" - self.kp.handle(fake_keyevent(Qt.Key_B, text='b')) - self.kp.handle(fake_keyevent(Qt.Key_A, text='a')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a')) self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, None) self.assertEqual(self.kp._keystring, '') def test_count_0(self): """Test with count=0.""" - self.kp.handle(fake_keyevent(Qt.Key_0, text='0')) - self.kp.handle(fake_keyevent(Qt.Key_B, text='b')) - self.kp.handle(fake_keyevent(Qt.Key_A, text='a')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_0, text='0')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a')) self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, 0) self.assertEqual(self.kp._keystring, '') def test_count_42(self): """Test with count=42.""" - self.kp.handle(fake_keyevent(Qt.Key_4, text='4')) - self.kp.handle(fake_keyevent(Qt.Key_2, text='2')) - self.kp.handle(fake_keyevent(Qt.Key_B, text='b')) - self.kp.handle(fake_keyevent(Qt.Key_A, text='a')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_4, text='4')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_2, text='2')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='b')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a')) self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, 42) self.assertEqual(self.kp._keystring, '') def test_count_42_invalid(self): """Test with count=42 and invalid command.""" # Invalid call with ccx gets ignored - self.kp.handle(fake_keyevent(Qt.Key_4, text='4')) - self.kp.handle(fake_keyevent(Qt.Key_2, text='2')) - self.kp.handle(fake_keyevent(Qt.Key_B, text='c')) - self.kp.handle(fake_keyevent(Qt.Key_A, text='c')) - self.kp.handle(fake_keyevent(Qt.Key_A, text='x')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_4, text='4')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_2, text='2')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='c')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='c')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='x')) self.assertFalse(self.kp.execute.called) self.assertEqual(self.kp._keystring, '') # Valid call with ccc gets the correct count - self.kp.handle(fake_keyevent(Qt.Key_4, text='2')) - self.kp.handle(fake_keyevent(Qt.Key_2, text='3')) - self.kp.handle(fake_keyevent(Qt.Key_B, text='c')) - self.kp.handle(fake_keyevent(Qt.Key_A, text='c')) - self.kp.handle(fake_keyevent(Qt.Key_A, text='c')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_4, text='2')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_2, text='3')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_B, text='c')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='c')) + self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='c')) self.kp.execute.assert_called_once_with('ccc', self.kp.Type.chain, 23) self.assertEqual(self.kp._keystring, '') diff --git a/qutebrowser/test/stubs.py b/qutebrowser/test/stubs.py index d8cce8d92..2625ba909 100644 --- a/qutebrowser/test/stubs.py +++ b/qutebrowser/test/stubs.py @@ -21,7 +21,7 @@ """Fake objects/stubs.""" -from unittest.mock import Mock +from unittest import mock from PyQt5.QtCore import QPoint, QProcess from PyQt5.QtWebKit import QWebElement @@ -73,9 +73,9 @@ class FakeKeyEvent: """Fake QKeyPressEvent stub.""" def __init__(self, key, modifiers=0, text=''): - self.key = Mock(return_value=key) - self.text = Mock(return_value=text) - self.modifiers = Mock(return_value=modifiers) + self.key = mock.Mock(return_value=key) + self.text = mock.Mock(return_value=text) + self.modifiers = mock.Mock(return_value=modifiers) class FakeWebElement: @@ -99,10 +99,10 @@ class FakeWebElement: Raise: ValueError if element is not null and geometry/frame are not given. """ - self.geometry = Mock(return_value=geometry) - self.webFrame = Mock(return_value=frame) - self.isNull = Mock(return_value=null) - self.tagName = Mock(return_value=tagname) + self.geometry = mock.Mock(return_value=geometry) + self.webFrame = mock.Mock(return_value=frame) + self.isNull = mock.Mock(return_value=null) + self.tagName = mock.Mock(return_value=tagname) self._visibility = visibility self._display = display self._attributes = attributes @@ -170,9 +170,9 @@ class FakeWebFrame: """ if scroll is None: scroll = QPoint(0, 0) - self.geometry = Mock(return_value=geometry) - self.scrollPosition = Mock(return_value=scroll) - self.parentFrame = Mock(return_value=parent) + self.geometry = mock.Mock(return_value=geometry) + self.scrollPosition = mock.Mock(return_value=scroll) + self.parentFrame = mock.Mock(return_value=parent) class FakeChildrenFrame: @@ -182,7 +182,7 @@ class FakeChildrenFrame: def __init__(self, children=None): if children is None: children = [] - self.childFrames = Mock(return_value=children) + self.childFrames = mock.Mock(return_value=children) class FakeQApplication: @@ -190,8 +190,8 @@ class FakeQApplication: """Stub to insert as QApplication module.""" def __init__(self, focus): - self.focusWidget = Mock(return_value=focus) - self.instance = Mock(return_value=self) + self.focusWidget = mock.Mock(return_value=focus) + self.instance = mock.Mock(return_value=self) class FakeUrl: @@ -199,7 +199,7 @@ class FakeUrl: """QUrl stub which provides .path().""" def __init__(self, path=None): - self.path = Mock(return_value=path) + self.path = mock.Mock(return_value=path) class FakeNetworkReply: @@ -217,7 +217,7 @@ class FakeNetworkReply: self.headers = {} else: self.headers = headers - self.url = Mock(return_value=url) + self.url = mock.Mock(return_value=url) def hasRawHeader(self, name): """Check if the reply has a certain header. @@ -282,9 +282,9 @@ class FakeQProcess: UnknownError = QProcess.UnknownError def __init__(self, parent=None): # pylint: disable=unused-argument - self.finished = Mock() - self.error = Mock() - self.start = Mock() + self.finished = mock.Mock() + self.error = mock.Mock() + self.start = mock.Mock() class FakeSignal: diff --git a/qutebrowser/test/test_helpers.py b/qutebrowser/test/test_helpers.py index 4e95946ed..7ecfbf39d 100644 --- a/qutebrowser/test/test_helpers.py +++ b/qutebrowser/test/test_helpers.py @@ -23,7 +23,7 @@ import os import unittest -from qutebrowser.test.helpers import environ_set_temp +from qutebrowser.test import helpers class TestEnvironSetTemp(unittest.TestCase): @@ -33,13 +33,13 @@ class TestEnvironSetTemp(unittest.TestCase): def test_environ_set(self): """Test environ_set_temp with something which was set already.""" os.environ['QUTEBROWSER_ENVIRON_TEST'] = 'oldval' - with environ_set_temp('QUTEBROWSER_ENVIRON_TEST', 'newval'): + with helpers.environ_set_temp('QUTEBROWSER_ENVIRON_TEST', 'newval'): self.assertEqual(os.environ['QUTEBROWSER_ENVIRON_TEST'], 'newval') self.assertEqual(os.environ['QUTEBROWSER_ENVIRON_TEST'], 'oldval') def test_environ_unset(self): """Test environ_set_temp with something which wasn't set yet.""" - with environ_set_temp('QUTEBROWSER_ENVIRON_TEST', 'newval'): + with helpers.environ_set_temp('QUTEBROWSER_ENVIRON_TEST', 'newval'): self.assertEqual(os.environ['QUTEBROWSER_ENVIRON_TEST'], 'newval') self.assertNotIn('QUTEBROWSER_ENVIRON_TEST', os.environ) diff --git a/qutebrowser/test/utils/http/test_content_disposition.py b/qutebrowser/test/utils/http/test_content_disposition.py index 5063c0663..6e0ba38e4 100644 --- a/qutebrowser/test/utils/http/test_content_disposition.py +++ b/qutebrowser/test/utils/http/test_content_disposition.py @@ -23,8 +23,8 @@ import os import unittest import logging -import qutebrowser.utils.http as httputils -from qutebrowser.test.stubs import FakeNetworkReply +from qutebrowser.utils import http +from qutebrowser.test import stubs DEFAULT_NAME = 'qutebrowser-download' @@ -39,23 +39,23 @@ class AttachmentTestCase(unittest.TestCase): def _check_filename(self, header, filename): """Check if the passed header has the given filename.""" - reply = FakeNetworkReply(headers={'Content-Disposition': header}) - cd_inline, cd_filename = httputils.parse_content_disposition(reply) + reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header}) + cd_inline, cd_filename = http.parse_content_disposition(reply) self.assertIsNotNone(cd_filename) self.assertEqual(cd_filename, filename) self.assertFalse(cd_inline) def _check_ignored(self, header): """Check if the passed header is ignored.""" - reply = FakeNetworkReply(headers={'Content-Disposition': header}) - cd_inline, cd_filename = httputils.parse_content_disposition(reply) + reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header}) + cd_inline, cd_filename = http.parse_content_disposition(reply) self.assertEqual(cd_filename, DEFAULT_NAME) self.assertTrue(cd_inline) def _check_unnamed(self, header): """Check if the passed header results in an unnamed attachment.""" - reply = FakeNetworkReply(headers={'Content-Disposition': header}) - cd_inline, cd_filename = httputils.parse_content_disposition(reply) + reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header}) + cd_inline, cd_filename = http.parse_content_disposition(reply) self.assertEqual(cd_filename, DEFAULT_NAME) self.assertFalse(cd_inline) @@ -69,15 +69,15 @@ class InlineTests(unittest.TestCase): def _check_filename(self, header, filename): """Check if the passed header has the given filename.""" - reply = FakeNetworkReply(headers={'Content-Disposition': header}) - cd_inline, cd_filename = httputils.parse_content_disposition(reply) + reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header}) + cd_inline, cd_filename = http.parse_content_disposition(reply) self.assertEqual(cd_filename, filename) self.assertTrue(cd_inline) def _check_ignored(self, header): """Check if the passed header is ignored.""" - reply = FakeNetworkReply(headers={'Content-Disposition': header}) - cd_inline, cd_filename = httputils.parse_content_disposition(reply) + reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header}) + cd_inline, cd_filename = http.parse_content_disposition(reply) self.assertEqual(cd_filename, DEFAULT_NAME) self.assertTrue(cd_inline) @@ -134,8 +134,9 @@ class AttachmentTests(AttachmentTestCase): UA should offer to download the resource. """ - reply = FakeNetworkReply(headers={'Content-Disposition': 'attachment'}) - cd_inline, cd_filename = httputils.parse_content_disposition(reply) + reply = stubs.FakeNetworkReply( + headers={'Content-Disposition': 'attachment'}) + cd_inline, cd_filename = http.parse_content_disposition(reply) self.assertFalse(cd_inline) self.assertEqual(cd_filename, DEFAULT_NAME) diff --git a/qutebrowser/test/utils/http/test_http.py b/qutebrowser/test/utils/http/test_http.py index 7eb857b99..01b918360 100644 --- a/qutebrowser/test/utils/http/test_http.py +++ b/qutebrowser/test/utils/http/test_http.py @@ -25,8 +25,8 @@ test_content_disposition.py file. import unittest -import qutebrowser.utils.http as httputils -from qutebrowser.test.stubs import FakeNetworkReply +from qutebrowser.utils import http +from qutebrowser.test import stubs class ParseContentTypeTests(unittest.TestCase): @@ -35,30 +35,31 @@ class ParseContentTypeTests(unittest.TestCase): def test_not_existing(self): """Test without any Content-Type header.""" - reply = FakeNetworkReply() - mimetype, rest = httputils.parse_content_type(reply) + reply = stubs.FakeNetworkReply() + mimetype, rest = http.parse_content_type(reply) self.assertIsNone(mimetype) self.assertIsNone(rest) def test_mimetype(self): """Test with simple Content-Type header.""" - reply = FakeNetworkReply(headers={'Content-Type': 'image/example'}) - mimetype, rest = httputils.parse_content_type(reply) + reply = stubs.FakeNetworkReply( + headers={'Content-Type': 'image/example'}) + mimetype, rest = http.parse_content_type(reply) self.assertEqual(mimetype, 'image/example') self.assertIsNone(rest) def test_empty(self): """Test with empty Content-Type header.""" - reply = FakeNetworkReply(headers={'Content-Type': ''}) - mimetype, rest = httputils.parse_content_type(reply) + reply = stubs.FakeNetworkReply(headers={'Content-Type': ''}) + mimetype, rest = http.parse_content_type(reply) self.assertEqual(mimetype, '') self.assertIsNone(rest) def test_additional(self): """Test with Content-Type header with additional informations.""" - reply = FakeNetworkReply( + reply = stubs.FakeNetworkReply( headers={'Content-Type': 'image/example; encoding=UTF-8'}) - mimetype, rest = httputils.parse_content_type(reply) + mimetype, rest = http.parse_content_type(reply) self.assertEqual(mimetype, 'image/example') self.assertEqual(rest, ' encoding=UTF-8') diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 12313e5e1..6f9e70a05 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -24,8 +24,8 @@ import unittest from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QStyle, QFrame -import qutebrowser.utils.debug as debug -from qutebrowser.test.stubs import FakeSignal +from qutebrowser.utils import debug +from qutebrowser.test import stubs class QEnumKeyTests(unittest.TestCase): @@ -123,7 +123,7 @@ class TestDebug(unittest.TestCase): """Test signal debug output functions.""" def setUp(self): - self.signal = FakeSignal() + self.signal = stubs.FakeSignal() def test_signal_name(self): """Test signal_name().""" diff --git a/qutebrowser/test/utils/test_editor.py b/qutebrowser/test/utils/test_editor.py index 15c3ea54e..db63a5948 100644 --- a/qutebrowser/test/utils/test_editor.py +++ b/qutebrowser/test/utils/test_editor.py @@ -23,19 +23,19 @@ import os import os.path import unittest import logging -from unittest.mock import Mock +from unittest import mock from PyQt5.QtCore import QProcess -import qutebrowser.utils.editor as editorutils -from qutebrowser.test.stubs import ConfigStub, FakeQProcess +from qutebrowser.utils import editor +from qutebrowser.test import stubs def setUpModule(): """Disable logging and mock out some imports.""" logging.disable(logging.INFO) - editorutils.message = Mock() - editorutils.QProcess = FakeQProcess + editor.message = mock.Mock() + editor.QProcess = stubs.FakeQProcess def tearDownModule(): @@ -52,18 +52,18 @@ class ArgTests(unittest.TestCase): """ def setUp(self): - self.editor = editorutils.ExternalEditor() + self.editor = editor.ExternalEditor() def test_simple_start_args(self): """Test starting editor without arguments.""" - editorutils.config = ConfigStub( + editor.config = stubs.ConfigStub( {'general': {'editor': ['bin'], 'editor-encoding': 'utf-8'}}) self.editor.edit("") self.editor.proc.start.assert_called_with("bin", []) def test_start_args(self): """Test starting editor with static arguments.""" - editorutils.config = ConfigStub( + editor.config = stubs.ConfigStub( {'general': {'editor': ['bin', 'foo', 'bar'], 'editor-encoding': 'utf-8'}}) self.editor.edit("") @@ -71,7 +71,7 @@ class ArgTests(unittest.TestCase): def test_placeholder(self): """Test starting editor with placeholder argument.""" - editorutils.config = ConfigStub( + editor.config = stubs.ConfigStub( {'general': {'editor': ['bin', 'foo', '{}', 'bar'], 'editor-encoding': 'utf-8'}}) self.editor.edit("") @@ -81,7 +81,7 @@ class ArgTests(unittest.TestCase): def test_in_arg_placeholder(self): """Test starting editor with placeholder argument inside argument.""" - editorutils.config = ConfigStub( + editor.config = stubs.ConfigStub( {'general': {'editor': ['bin', 'foo{}bar'], 'editor-encoding': 'utf-8'}}) self.editor.edit("") @@ -100,8 +100,8 @@ class FileHandlingTests(unittest.TestCase): """ def setUp(self): - self.editor = editorutils.ExternalEditor() - editorutils.config = ConfigStub( + self.editor = editor.ExternalEditor() + editor.config = stubs.ConfigStub( {'general': {'editor': [''], 'editor-encoding': 'utf-8'}}) def test_file_handling_closed_ok(self): @@ -139,9 +139,9 @@ class TextModifyTests(unittest.TestCase): """ def setUp(self): - self.editor = editorutils.ExternalEditor() - self.editor.editing_finished = Mock() - editorutils.config = ConfigStub( + self.editor = editor.ExternalEditor() + self.editor.editing_finished = mock.Mock() + editor.config = stubs.ConfigStub( {'general': {'editor': [''], 'editor-encoding': 'utf-8'}}) def _write(self, text): @@ -209,21 +209,21 @@ class ErrorMessageTests(unittest.TestCase): # pylint: disable=maybe-no-member def setUp(self): - self.editor = editorutils.ExternalEditor() - editorutils.config = ConfigStub( + self.editor = editor.ExternalEditor() + editor.config = stubs.ConfigStub( {'general': {'editor': [''], 'editor-encoding': 'utf-8'}}) def test_proc_error(self): """Test on_proc_error.""" self.editor.edit("") self.editor.on_proc_error(QProcess.Crashed) - self.assertTrue(editorutils.message.error.called) + self.assertTrue(editor.message.error.called) def test_proc_return(self): """Test on_proc_finished with a bad exit status.""" self.editor.edit("") self.editor.on_proc_closed(1, QProcess.NormalExit) - self.assertTrue(editorutils.message.error.called) + self.assertTrue(editor.message.error.called) if __name__ == '__main__': diff --git a/qutebrowser/test/utils/test_log.py b/qutebrowser/test/utils/test_log.py index 0bcbcd868..a2736383b 100644 --- a/qutebrowser/test/utils/test_log.py +++ b/qutebrowser/test/utils/test_log.py @@ -26,7 +26,7 @@ import unittest import argparse import sys -import qutebrowser.utils.log as log +from qutebrowser.utils import log class BaseTest(unittest.TestCase): diff --git a/qutebrowser/test/utils/test_misc.py b/qutebrowser/test/utils/test_misc.py index 41483d9cb..71e9260c2 100644 --- a/qutebrowser/test/utils/test_misc.py +++ b/qutebrowser/test/utils/test_misc.py @@ -24,14 +24,14 @@ import sys import shutil import unittest import os.path -from tempfile import mkdtemp +import tempfile from PyQt5.QtCore import QStandardPaths, QCoreApplication, Qt from PyQt5.QtGui import QColor -import qutebrowser.utils.misc as utils -from qutebrowser.test.helpers import environ_set_temp, fake_keyevent -from qutebrowser.utils.qt import QtValueError +from qutebrowser.utils import misc as utils +from qutebrowser.utils import qt as qtutils +from qutebrowser.test import helpers class Color(QColor): @@ -157,14 +157,14 @@ class GetStandardDirLinuxTests(unittest.TestCase): """ def setUp(self): - self.temp_dir = mkdtemp() + self.temp_dir = tempfile.mkdtemp() self.app = QCoreApplication([]) self.app.setApplicationName('qutebrowser') @unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux") def test_data_explicit(self): """Test data dir with XDG_DATA_HOME explicitely set.""" - with environ_set_temp('XDG_DATA_HOME', self.temp_dir): + with helpers.environ_set_temp('XDG_DATA_HOME', self.temp_dir): cur_dir = utils.get_standard_dir(QStandardPaths.DataLocation) self.assertEqual(cur_dir, os.path.join(self.temp_dir, 'qutebrowser')) @@ -173,7 +173,7 @@ class GetStandardDirLinuxTests(unittest.TestCase): @unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux") def test_config_explicit(self): """Test config dir with XDG_CONFIG_HOME explicitely set.""" - with environ_set_temp('XDG_CONFIG_HOME', self.temp_dir): + with helpers.environ_set_temp('XDG_CONFIG_HOME', self.temp_dir): cur_dir = utils.get_standard_dir(QStandardPaths.ConfigLocation) self.assertEqual(cur_dir, os.path.join(self.temp_dir, 'qutebrowser')) @@ -182,7 +182,7 @@ class GetStandardDirLinuxTests(unittest.TestCase): @unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux") def test_cache_explicit(self): """Test cache dir with XDG_CACHE_HOME explicitely set.""" - with environ_set_temp('XDG_CACHE_HOME', self.temp_dir): + with helpers.environ_set_temp('XDG_CACHE_HOME', self.temp_dir): cur_dir = utils.get_standard_dir(QStandardPaths.CacheLocation) self.assertEqual(cur_dir, os.path.join(self.temp_dir, 'qutebrowser')) @@ -191,7 +191,7 @@ class GetStandardDirLinuxTests(unittest.TestCase): @unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux") def test_data(self): """Test data dir with XDG_DATA_HOME not set.""" - with environ_set_temp('HOME', self.temp_dir): + with helpers.environ_set_temp('HOME', self.temp_dir): cur_dir = utils.get_standard_dir(QStandardPaths.DataLocation) self.assertEqual(cur_dir, os.path.join(self.temp_dir, '.local', 'share', 'qutebrowser')) @@ -200,7 +200,7 @@ class GetStandardDirLinuxTests(unittest.TestCase): @unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux") def test_config(self): """Test config dir with XDG_CONFIG_HOME not set.""" - with environ_set_temp('HOME', self.temp_dir): + with helpers.environ_set_temp('HOME', self.temp_dir): cur_dir = utils.get_standard_dir( QStandardPaths.ConfigLocation) self.assertEqual(cur_dir, os.path.join(self.temp_dir, '.config', @@ -210,7 +210,7 @@ class GetStandardDirLinuxTests(unittest.TestCase): @unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux") def test_cache(self): """Test cache dir with XDG_CACHE_HOME not set.""" - with environ_set_temp('HOME', self.temp_dir): + with helpers.environ_set_temp('HOME', self.temp_dir): cur_dir = utils.get_standard_dir(QStandardPaths.CacheLocation) self.assertEqual(cur_dir, os.path.join(self.temp_dir, '.cache', 'qutebrowser')) @@ -286,12 +286,12 @@ class InterpolateColorTests(unittest.TestCase): def test_invalid_start(self): """Test an invalid start color.""" - with self.assertRaises(QtValueError): + with self.assertRaises(qtutils.QtValueError): utils.interpolate_color(Color(), self.white, 0) def test_invalid_end(self): """Test an invalid end color.""" - with self.assertRaises(QtValueError): + with self.assertRaises(qtutils.QtValueError): utils.interpolate_color(self.white, Color(), 0) def test_invalid_percentage(self): @@ -464,29 +464,31 @@ class KeyEventToStringTests(unittest.TestCase): def test_only_control(self): """Test keyeevent when only control is pressed.""" - evt = fake_keyevent(key=Qt.Key_Control, modifiers=Qt.ControlModifier) + evt = helpers.fake_keyevent(key=Qt.Key_Control, + modifiers=Qt.ControlModifier) self.assertIsNone(utils.keyevent_to_string(evt)) def test_only_hyper_l(self): """Test keyeevent when only Hyper_L is pressed.""" - evt = fake_keyevent(key=Qt.Key_Hyper_L, modifiers=Qt.MetaModifier) + evt = helpers.fake_keyevent(key=Qt.Key_Hyper_L, + modifiers=Qt.MetaModifier) self.assertIsNone(utils.keyevent_to_string(evt)) def test_only_key(self): """Test with a simple key pressed.""" - evt = fake_keyevent(key=Qt.Key_A) + evt = helpers.fake_keyevent(key=Qt.Key_A) self.assertEqual(utils.keyevent_to_string(evt), 'A') def test_key_and_modifier(self): """Test with key and modifier pressed.""" - evt = fake_keyevent(key=Qt.Key_A, modifiers=Qt.ControlModifier) + evt = helpers.fake_keyevent(key=Qt.Key_A, modifiers=Qt.ControlModifier) self.assertEqual(utils.keyevent_to_string(evt), 'Ctrl+A') def test_key_and_modifiers(self): """Test with key and multiple modifier pressed.""" - evt = fake_keyevent(key=Qt.Key_A, - modifiers=(Qt.ControlModifier | Qt.AltModifier | - Qt.MetaModifier | Qt.ShiftModifier)) + evt = helpers.fake_keyevent( + key=Qt.Key_A, modifiers=(Qt.ControlModifier | Qt.AltModifier | + Qt.MetaModifier | Qt.ShiftModifier)) self.assertEqual(utils.keyevent_to_string(evt), 'Ctrl+Alt+Meta+Shift+A') diff --git a/qutebrowser/test/utils/test_qt.py b/qutebrowser/test/utils/test_qt.py index 3c1b88ee8..e3d33d2f7 100644 --- a/qutebrowser/test/utils/test_qt.py +++ b/qutebrowser/test/utils/test_qt.py @@ -23,7 +23,7 @@ import sys import argparse import unittest -import qutebrowser.utils.qt as qt +from qutebrowser.utils import qt class CheckOverflowTests(unittest.TestCase): diff --git a/qutebrowser/test/utils/test_readline.py b/qutebrowser/test/utils/test_readline.py index 93a1c353d..adaa55c28 100644 --- a/qutebrowser/test/utils/test_readline.py +++ b/qutebrowser/test/utils/test_readline.py @@ -21,12 +21,12 @@ import inspect import unittest -from unittest.mock import Mock +from unittest import mock from PyQt5.QtWidgets import QLineEdit -import qutebrowser.utils.readline as readline -from qutebrowser.test.stubs import FakeQApplication +from qutebrowser.utils import readline +from qutebrowser.test import stubs class NoneWidgetTests(unittest.TestCase): @@ -34,7 +34,7 @@ class NoneWidgetTests(unittest.TestCase): """Tests when the focused widget is None.""" def setUp(self): - readline.QApplication = FakeQApplication(None) + readline.QApplication = stubs.FakeQApplication(None) self.bridge = readline.ReadlineBridge() def test_none(self): @@ -50,9 +50,9 @@ class ReadlineBridgeTest(unittest.TestCase): """Tests for readline bridge.""" def setUp(self): - self.qle = Mock() + self.qle = mock.Mock() self.qle.__class__ = QLineEdit - readline.QApplication = FakeQApplication(self.qle) + readline.QApplication = stubs.FakeQApplication(self.qle) self.bridge = readline.ReadlineBridge() def _set_selected_text(self, text): diff --git a/qutebrowser/test/utils/test_url.py b/qutebrowser/test/utils/test_url.py index 889829be6..8f366d8b7 100644 --- a/qutebrowser/test/utils/test_url.py +++ b/qutebrowser/test/utils/test_url.py @@ -25,8 +25,8 @@ import unittest from PyQt5.QtCore import QUrl -import qutebrowser.utils.url as urlutils -from qutebrowser.test.stubs import ConfigStub +from qutebrowser.utils import url as urlutils +from qutebrowser.test import stubs CONFIG = { @@ -83,7 +83,7 @@ class SearchUrlTests(unittest.TestCase): def setUp(self): self.config = urlutils.config - urlutils.config = ConfigStub(CONFIG) + urlutils.config = stubs.ConfigStub(CONFIG) def test_default_engine(self): """Test default search engine.""" diff --git a/qutebrowser/test/utils/test_webelem.py b/qutebrowser/test/utils/test_webelem.py index b98425bec..978076b6a 100644 --- a/qutebrowser/test/utils/test_webelem.py +++ b/qutebrowser/test/utils/test_webelem.py @@ -23,9 +23,8 @@ import unittest from PyQt5.QtCore import QRect, QPoint -import qutebrowser.utils.webelem as webelem -from qutebrowser.test.stubs import (FakeWebElement, FakeWebFrame, - FakeChildrenFrame, ConfigStub) +from qutebrowser.utils import webelem +from qutebrowser.test import stubs class IsVisibleInvalidTests(unittest.TestCase): @@ -37,7 +36,7 @@ class IsVisibleInvalidTests(unittest.TestCase): """ def setUp(self): - self.frame = FakeWebFrame(QRect(0, 0, 100, 100)) + self.frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100)) def test_nullelem(self): """Passing an element with isNull() == True. @@ -45,7 +44,7 @@ class IsVisibleInvalidTests(unittest.TestCase): geometry() and webFrame() should not be called, and ValueError should be raised. """ - elem = FakeWebElement(null=True) + elem = stubs.FakeWebElement(null=True) with self.assertRaises(ValueError): webelem.is_visible(elem, self.frame) elem.isNull.assert_called_once_with() @@ -54,7 +53,7 @@ class IsVisibleInvalidTests(unittest.TestCase): def test_invalid_invisible(self): """Test elements with an invalid geometry which are invisible.""" - elem = FakeWebElement(QRect(0, 0, 0, 0), self.frame) + elem = stubs.FakeWebElement(QRect(0, 0, 0, 0), self.frame) self.assertFalse(elem.geometry().isValid()) self.assertEqual(elem.geometry().x(), 0) self.assertFalse(webelem.is_visible(elem, self.frame)) @@ -65,7 +64,7 @@ class IsVisibleInvalidTests(unittest.TestCase): This seems to happen sometimes in the real world, with real elements which *are* visible, but don't have a valid geometry. """ - elem = FakeWebElement(QRect(10, 10, 0, 0), self.frame) + elem = stubs.FakeWebElement(QRect(10, 10, 0, 0), self.frame) self.assertFalse(elem.geometry().isValid()) self.assertTrue(webelem.is_visible(elem, self.frame)) @@ -79,16 +78,17 @@ class IsVisibleScrollTests(unittest.TestCase): """ def setUp(self): - self.frame = FakeWebFrame(QRect(0, 0, 100, 100), scroll=QPoint(10, 10)) + self.frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100), + scroll=QPoint(10, 10)) def test_invisible(self): """Test elements which should be invisible due to scrolling.""" - elem = FakeWebElement(QRect(5, 5, 4, 4), self.frame) + elem = stubs.FakeWebElement(QRect(5, 5, 4, 4), self.frame) self.assertFalse(webelem.is_visible(elem, self.frame)) def test_visible(self): """Test elements which still should be visible after scrolling.""" - elem = FakeWebElement(QRect(10, 10, 1, 1), self.frame) + elem = stubs.FakeWebElement(QRect(10, 10, 1, 1), self.frame) self.assertTrue(webelem.is_visible(elem, self.frame)) @@ -101,29 +101,30 @@ class IsVisibleCssTests(unittest.TestCase): """ def setUp(self): - self.frame = FakeWebFrame(QRect(0, 0, 100, 100)) + self.frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100)) def test_visibility_visible(self): """Check that elements with "visibility = visible" are visible.""" - elem = FakeWebElement(QRect(0, 0, 10, 10), self.frame, - visibility='visible') + elem = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.frame, + visibility='visible') self.assertTrue(webelem.is_visible(elem, self.frame)) def test_visibility_hidden(self): """Check that elements with "visibility = hidden" are not visible.""" - elem = FakeWebElement(QRect(0, 0, 10, 10), self.frame, - visibility='hidden') + elem = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.frame, + visibility='hidden') self.assertFalse(webelem.is_visible(elem, self.frame)) def test_display_inline(self): """Check that elements with "display = inline" are visible.""" - elem = FakeWebElement(QRect(0, 0, 10, 10), self.frame, - display='inline') + elem = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.frame, + display='inline') self.assertTrue(webelem.is_visible(elem, self.frame)) def test_display_none(self): """Check that elements with "display = none" are not visible.""" - elem = FakeWebElement(QRect(0, 0, 10, 10), self.frame, display='none') + elem = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.frame, + display='none') self.assertFalse(webelem.is_visible(elem, self.frame)) @@ -158,12 +159,13 @@ class IsVisibleIframeTests(unittest.TestCase): ############################## 300, 0 300, 300 """ - self.frame = FakeWebFrame(QRect(0, 0, 300, 300)) - self.iframe = FakeWebFrame(QRect(0, 10, 100, 100), parent=self.frame) - self.elem1 = FakeWebElement(QRect(0, 0, 10, 10), self.iframe) - self.elem2 = FakeWebElement(QRect(20, 90, 10, 10), self.iframe) - self.elem3 = FakeWebElement(QRect(20, 150, 10, 10), self.iframe) - self.elem4 = FakeWebElement(QRect(30, 180, 10, 10), self.frame) + self.frame = stubs.FakeWebFrame(QRect(0, 0, 300, 300)) + self.iframe = stubs.FakeWebFrame(QRect(0, 10, 100, 100), + parent=self.frame) + self.elem1 = stubs.FakeWebElement(QRect(0, 0, 10, 10), self.iframe) + self.elem2 = stubs.FakeWebElement(QRect(20, 90, 10, 10), self.iframe) + self.elem3 = stubs.FakeWebElement(QRect(20, 150, 10, 10), self.iframe) + self.elem4 = stubs.FakeWebElement(QRect(30, 180, 10, 10), self.frame) def test_not_scrolled(self): """Test base situation.""" @@ -210,17 +212,17 @@ class IsWritableTests(unittest.TestCase): def test_writable(self): """Test a normal element.""" - elem = FakeWebElement() + elem = stubs.FakeWebElement() self.assertTrue(webelem.is_writable(elem)) def test_disabled(self): """Test a disabled element.""" - elem = FakeWebElement(attributes=['disabled']) + elem = stubs.FakeWebElement(attributes=['disabled']) self.assertFalse(webelem.is_writable(elem)) def test_readonly(self): """Test a readonly element.""" - elem = FakeWebElement(attributes=['readonly']) + elem = stubs.FakeWebElement(attributes=['readonly']) self.assertFalse(webelem.is_writable(elem)) @@ -252,7 +254,7 @@ class GetChildFramesTests(unittest.TestCase): def test_single_frame(self): """Test get_child_frames with a single frame without children.""" - frame = FakeChildrenFrame() + frame = stubs.FakeChildrenFrame() children = webelem.get_child_frames(frame) self.assertEqual(len(children), 1) self.assertIs(children[0], frame) @@ -265,9 +267,9 @@ class GetChildFramesTests(unittest.TestCase): / \ child1 o o child2 """ - child1 = FakeChildrenFrame() - child2 = FakeChildrenFrame() - parent = FakeChildrenFrame([child1, child2]) + child1 = stubs.FakeChildrenFrame() + child2 = stubs.FakeChildrenFrame() + parent = stubs.FakeChildrenFrame([child1, child2]) children = webelem.get_child_frames(parent) self.assertEqual(len(children), 3) self.assertIs(children[0], parent) @@ -286,10 +288,10 @@ class GetChildFramesTests(unittest.TestCase): /\ /\ o o o o second """ - second = [FakeChildrenFrame() for _ in range(4)] - first = [FakeChildrenFrame(second[0:2]), - FakeChildrenFrame(second[2:4])] - root = FakeChildrenFrame(first) + second = [stubs.FakeChildrenFrame() for _ in range(4)] + first = [stubs.FakeChildrenFrame(second[0:2]), + stubs.FakeChildrenFrame(second[2:4])] + root = stubs.FakeChildrenFrame(first) children = webelem.get_child_frames(root) self.assertEqual(len(children), 7) self.assertIs(children[0], root) @@ -307,175 +309,189 @@ class IsEditableTests(unittest.TestCase): def test_input_plain(self): """Test with plain input element.""" - elem = FakeWebElement(tagname='input') + elem = stubs.FakeWebElement(tagname='input') self.assertTrue(webelem.is_editable(elem)) def test_input_text(self): """Test with text input element.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'text'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'text'}) self.assertTrue(webelem.is_editable(elem)) def test_input_text_caps(self): """Test with text input element with caps attributes.""" - elem = FakeWebElement(tagname='INPUT', attributes={'TYPE': 'TEXT'}) + elem = stubs.FakeWebElement(tagname='INPUT', + attributes={'TYPE': 'TEXT'}) self.assertTrue(webelem.is_editable(elem)) def test_input_email(self): """Test with email input element.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'email'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'email'}) self.assertTrue(webelem.is_editable(elem)) def test_input_url(self): """Test with url input element.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'url'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'url'}) self.assertTrue(webelem.is_editable(elem)) def test_input_tel(self): """Test with tel input element.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'tel'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'tel'}) self.assertTrue(webelem.is_editable(elem)) def test_input_number(self): """Test with number input element.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'number'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'number'}) self.assertTrue(webelem.is_editable(elem)) def test_input_password(self): """Test with password input element.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'password'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'password'}) self.assertTrue(webelem.is_editable(elem)) def test_input_search(self): """Test with search input element.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'search'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'search'}) self.assertTrue(webelem.is_editable(elem)) def test_input_button(self): """Button should not be editable.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'button'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'button'}) self.assertFalse(webelem.is_editable(elem)) def test_input_checkbox(self): """Checkbox should not be editable.""" - elem = FakeWebElement(tagname='input', attributes={'type': 'checkbox'}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'type': 'checkbox'}) self.assertFalse(webelem.is_editable(elem)) def test_textarea(self): """Test textarea element.""" - elem = FakeWebElement(tagname='textarea') + elem = stubs.FakeWebElement(tagname='textarea') self.assertTrue(webelem.is_editable(elem)) def test_select(self): """Test selectbox.""" - elem = FakeWebElement(tagname='select') + elem = stubs.FakeWebElement(tagname='select') self.assertFalse(webelem.is_editable(elem)) def test_input_disabled(self): """Test disabled input element.""" - elem = FakeWebElement(tagname='input', attributes={'disabled': None}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'disabled': None}) self.assertFalse(webelem.is_editable(elem)) def test_input_readonly(self): """Test readonly input element.""" - elem = FakeWebElement(tagname='input', attributes={'readonly': None}) + elem = stubs.FakeWebElement(tagname='input', + attributes={'readonly': None}) self.assertFalse(webelem.is_editable(elem)) def test_textarea_disabled(self): """Test disabled textarea element.""" - elem = FakeWebElement(tagname='textarea', - attributes={'disabled': None}) + elem = stubs.FakeWebElement(tagname='textarea', + attributes={'disabled': None}) self.assertFalse(webelem.is_editable(elem)) def test_textarea_readonly(self): """Test readonly textarea element.""" - elem = FakeWebElement(tagname='textarea', - attributes={'readonly': None}) + elem = stubs.FakeWebElement(tagname='textarea', + attributes={'readonly': None}) self.assertFalse(webelem.is_editable(elem)) def test_embed_true(self): """Test embed-element with insert-mode-on-plugins true.""" - webelem.config = ConfigStub({'input': - {'insert-mode-on-plugins': True}}) - elem = FakeWebElement(tagname='embed') + webelem.config = stubs.ConfigStub({'input': + {'insert-mode-on-plugins': True}}) + elem = stubs.FakeWebElement(tagname='embed') self.assertTrue(webelem.is_editable(elem)) def test_applet_true(self): """Test applet-element with insert-mode-on-plugins true.""" - webelem.config = ConfigStub({'input': - {'insert-mode-on-plugins': True}}) - elem = FakeWebElement(tagname='applet') + webelem.config = stubs.ConfigStub({'input': + {'insert-mode-on-plugins': True}}) + elem = stubs.FakeWebElement(tagname='applet') self.assertTrue(webelem.is_editable(elem)) def test_embed_false(self): """Test embed-element with insert-mode-on-plugins false.""" - webelem.config = ConfigStub({'input': - {'insert-mode-on-plugins': False}}) - elem = FakeWebElement(tagname='embed') + webelem.config = stubs.ConfigStub({'input': + {'insert-mode-on-plugins': False}}) + elem = stubs.FakeWebElement(tagname='embed') self.assertFalse(webelem.is_editable(elem)) def test_applet_false(self): """Test applet-element with insert-mode-on-plugins false.""" - webelem.config = ConfigStub({'input': - {'insert-mode-on-plugins': False}}) - elem = FakeWebElement(tagname='applet') + webelem.config = stubs.ConfigStub({'input': + {'insert-mode-on-plugins': False}}) + elem = stubs.FakeWebElement(tagname='applet') self.assertFalse(webelem.is_editable(elem)) def test_object_no_type(self): """Test object-element without type.""" - elem = FakeWebElement(tagname='object') + elem = stubs.FakeWebElement(tagname='object') self.assertFalse(webelem.is_editable(elem)) def test_object_image(self): """Test object-element with image type.""" - elem = FakeWebElement(tagname='object', - attributes={'type': 'image/gif'}) + elem = stubs.FakeWebElement(tagname='object', + attributes={'type': 'image/gif'}) self.assertFalse(webelem.is_editable(elem)) def test_object_application(self): """Test object-element with application type.""" - webelem.config = ConfigStub({'input': - {'insert-mode-on-plugins': True}}) - elem = FakeWebElement(tagname='object', - attributes={'type': 'application/foo'}) + webelem.config = stubs.ConfigStub({'input': + {'insert-mode-on-plugins': True}}) + elem = stubs.FakeWebElement(tagname='object', + attributes={'type': 'application/foo'}) self.assertTrue(webelem.is_editable(elem)) def test_object_application_false(self): """Test object-element with application type but not ...-on-plugins.""" - webelem.config = ConfigStub({'input': - {'insert-mode-on-plugins': False}}) - elem = FakeWebElement(tagname='object', - attributes={'type': 'application/foo'}) + webelem.config = stubs.ConfigStub({'input': + {'insert-mode-on-plugins': False}}) + elem = stubs.FakeWebElement(tagname='object', + attributes={'type': 'application/foo'}) self.assertFalse(webelem.is_editable(elem)) def test_object_classid(self): """Test object-element with classid.""" - webelem.config = ConfigStub({'input': - {'insert-mode-on-plugins': True}}) - elem = FakeWebElement(tagname='object', - attributes={'type': 'foo', 'classid': 'foo'}) + webelem.config = stubs.ConfigStub({'input': + {'insert-mode-on-plugins': True}}) + elem = stubs.FakeWebElement(tagname='object', + attributes={'type': 'foo', + 'classid': 'foo'}) self.assertTrue(webelem.is_editable(elem)) def test_object_classid_false(self): """Test object-element with classid but not insert-mode-on-plugins.""" - webelem.config = ConfigStub({'input': - {'insert-mode-on-plugins': False}}) - elem = FakeWebElement(tagname='object', - attributes={'type': 'foo', 'classid': 'foo'}) + webelem.config = stubs.ConfigStub({'input': + {'insert-mode-on-plugins': False}}) + elem = stubs.FakeWebElement(tagname='object', + attributes={'type': 'foo', + 'classid': 'foo'}) self.assertFalse(webelem.is_editable(elem)) def test_div_empty(self): """Test div-element without class.""" - elem = FakeWebElement(tagname='div') + elem = stubs.FakeWebElement(tagname='div') self.assertFalse(webelem.is_editable(elem)) def test_div_noneditable(self): """Test div-element with non-editableclass.""" - elem = FakeWebElement(tagname='div', classes='foo-kix-bar') + elem = stubs.FakeWebElement(tagname='div', classes='foo-kix-bar') self.assertFalse(webelem.is_editable(elem)) def test_div_xik(self): """Test div-element with xik class.""" - elem = FakeWebElement(tagname='div', classes='foo kix-foo') + elem = stubs.FakeWebElement(tagname='div', classes='foo kix-foo') self.assertTrue(webelem.is_editable(elem)) def test_div_xik_caps(self): @@ -483,12 +499,13 @@ class IsEditableTests(unittest.TestCase): This tests if classes are case sensitive as they should. """ - elem = FakeWebElement(tagname='div', classes='KIX-FOO') + elem = stubs.FakeWebElement(tagname='div', classes='KIX-FOO') self.assertFalse(webelem.is_editable(elem)) def test_div_codemirror(self): """Test div-element with codemirror class.""" - elem = FakeWebElement(tagname='div', classes='foo CodeMirror-foo') + elem = stubs.FakeWebElement(tagname='div', + classes='foo CodeMirror-foo') self.assertTrue(webelem.is_editable(elem)) diff --git a/qutebrowser/test/utils/usertypes/test_enum.py b/qutebrowser/test/utils/usertypes/test_enum.py index 1ce3a9258..4097e2df2 100644 --- a/qutebrowser/test/utils/usertypes/test_enum.py +++ b/qutebrowser/test/utils/usertypes/test_enum.py @@ -21,7 +21,7 @@ import unittest -from qutebrowser.utils.usertypes import enum +from qutebrowser.utils import usertypes # FIXME: Add some more tests, e.g. for is_int @@ -35,7 +35,7 @@ class EnumTests(unittest.TestCase): """ def setUp(self): - self.enum = enum('Enum', 'one', 'two') + self.enum = usertypes.enum('Enum', 'one', 'two') def test_values(self): """Test if enum members resolve to the right values.""" @@ -54,7 +54,7 @@ class EnumTests(unittest.TestCase): def test_start(self): """Test the start= argument.""" - e = enum('Enum', 'three', 'four', start=3) + e = usertypes.enum('Enum', 'three', 'four', start=3) self.assertEqual(e.three.value, 3) self.assertEqual(e.four.value, 4) diff --git a/qutebrowser/test/utils/usertypes/test_neighborlist.py b/qutebrowser/test/utils/usertypes/test_neighborlist.py index 7dac494de..4345899ec 100644 --- a/qutebrowser/test/utils/usertypes/test_neighborlist.py +++ b/qutebrowser/test/utils/usertypes/test_neighborlist.py @@ -23,7 +23,7 @@ import unittest -from qutebrowser.utils.usertypes import NeighborList +from qutebrowser.utils import usertypes class InitTests(unittest.TestCase): @@ -36,27 +36,27 @@ class InitTests(unittest.TestCase): def test_empty(self): """Test constructing an empty NeighborList.""" - nl = NeighborList() + nl = usertypes.NeighborList() self.assertEqual(nl.items, []) def test_items(self): """Test constructing an NeighborList with items.""" - nl = NeighborList([1, 2, 3]) + nl = usertypes.NeighborList([1, 2, 3]) self.assertEqual(nl.items, [1, 2, 3]) def test_len(self): """Test len() on NeighborList.""" - nl = NeighborList([1, 2, 3]) + nl = usertypes.NeighborList([1, 2, 3]) self.assertEqual(len(nl), 3) def test_repr(self): """Test repr() on NeighborList.""" - nl = NeighborList([1, 2, 3]) + nl = usertypes.NeighborList([1, 2, 3]) self.assertEqual(repr(nl), 'NeighborList([1, 2, 3])') def test_contains(self): """Test 'in' on NeighborList.""" - nl = NeighborList([1, 2, 3]) + nl = usertypes.NeighborList([1, 2, 3]) self.assertIn(2, nl) self.assertNotIn(4, nl) @@ -71,17 +71,17 @@ class DefaultTests(unittest.TestCase): def test_simple(self): """Test default with a numeric argument.""" - nl = NeighborList([1, 2, 3], default=2) + nl = usertypes.NeighborList([1, 2, 3], default=2) self.assertEqual(nl.idx, 1) def test_none(self): """Test default 'None'.""" - nl = NeighborList([1, 2, None], default=None) + nl = usertypes.NeighborList([1, 2, None], default=None) self.assertEqual(nl.idx, 2) def test_unset(self): """Test unset default value.""" - nl = NeighborList([1, 2, 3]) + nl = usertypes.NeighborList([1, 2, 3]) self.assertIsNone(nl.idx) @@ -94,7 +94,7 @@ class EmptyTests(unittest.TestCase): """ def setUp(self): - self.nl = NeighborList() + self.nl = usertypes.NeighborList() def test_curitem(self): """Test curitem with no item.""" @@ -126,7 +126,7 @@ class ItemTests(unittest.TestCase): """ def setUp(self): - self.nl = NeighborList([1, 2, 3, 4, 5], default=3) + self.nl = usertypes.NeighborList([1, 2, 3, 4, 5], default=3) def test_curitem(self): """Test curitem().""" @@ -183,11 +183,11 @@ class OneTests(unittest.TestCase): """ def setUp(self): - self.nl = NeighborList([1], default=1) + self.nl = usertypes.NeighborList([1], default=1) def test_first_wrap(self): """Test out of bounds previtem() with mode=wrap.""" - self.nl._mode = NeighborList.Modes.wrap + self.nl._mode = usertypes.NeighborList.Modes.wrap self.nl.firstitem() self.assertEqual(self.nl.idx, 0) self.assertEqual(self.nl.previtem(), 1) @@ -195,7 +195,7 @@ class OneTests(unittest.TestCase): def test_first_block(self): """Test out of bounds previtem() with mode=block.""" - self.nl._mode = NeighborList.Modes.block + self.nl._mode = usertypes.NeighborList.Modes.block self.nl.firstitem() self.assertEqual(self.nl.idx, 0) self.assertEqual(self.nl.previtem(), 1) @@ -203,7 +203,7 @@ class OneTests(unittest.TestCase): def test_first_raise(self): """Test out of bounds previtem() with mode=raise.""" - self.nl._mode = NeighborList.Modes.exception + self.nl._mode = usertypes.NeighborList.Modes.exception self.nl.firstitem() self.assertEqual(self.nl.idx, 0) with self.assertRaises(IndexError): @@ -212,7 +212,7 @@ class OneTests(unittest.TestCase): def test_last_wrap(self): """Test out of bounds nextitem() with mode=wrap.""" - self.nl._mode = NeighborList.Modes.wrap + self.nl._mode = usertypes.NeighborList.Modes.wrap self.nl.lastitem() self.assertEqual(self.nl.idx, 0) self.assertEqual(self.nl.nextitem(), 1) @@ -220,7 +220,7 @@ class OneTests(unittest.TestCase): def test_last_block(self): """Test out of bounds nextitem() with mode=block.""" - self.nl._mode = NeighborList.Modes.block + self.nl._mode = usertypes.NeighborList.Modes.block self.nl.lastitem() self.assertEqual(self.nl.idx, 0) self.assertEqual(self.nl.nextitem(), 1) @@ -228,7 +228,7 @@ class OneTests(unittest.TestCase): def test_last_raise(self): """Test out of bounds nextitem() with mode=raise.""" - self.nl._mode = NeighborList.Modes.exception + self.nl._mode = usertypes.NeighborList.Modes.exception self.nl.lastitem() self.assertEqual(self.nl.idx, 0) with self.assertRaises(IndexError): @@ -245,8 +245,9 @@ class BlockTests(unittest.TestCase): """ def setUp(self): - self.nl = NeighborList([1, 2, 3, 4, 5], default=3, - mode=NeighborList.Modes.block) + self.nl = usertypes.NeighborList( + [1, 2, 3, 4, 5], default=3, + mode=usertypes.NeighborList.Modes.block) def test_first(self): """Test ouf of bounds previtem().""" @@ -272,8 +273,8 @@ class WrapTests(unittest.TestCase): """ def setUp(self): - self.nl = NeighborList([1, 2, 3, 4, 5], default=3, - mode=NeighborList.Modes.wrap) + self.nl = usertypes.NeighborList( + [1, 2, 3, 4, 5], default=3, mode=usertypes.NeighborList.Modes.wrap) def test_first(self): """Test ouf of bounds previtem().""" @@ -299,8 +300,9 @@ class RaiseTests(unittest.TestCase): """ def setUp(self): - self.nl = NeighborList([1, 2, 3, 4, 5], default=3, - mode=NeighborList.Modes.exception) + self.nl = usertypes.NeighborList( + [1, 2, 3, 4, 5], default=3, + mode=usertypes.NeighborList.Modes.exception) def test_first(self): """Test ouf of bounds previtem().""" @@ -328,7 +330,7 @@ class SnapInTests(unittest.TestCase): """ def setUp(self): - self.nl = NeighborList([20, 9, 1, 5]) + self.nl = usertypes.NeighborList([20, 9, 1, 5]) def test_bigger(self): """Test fuzzyval with snapping to a bigger value.""" diff --git a/qutebrowser/utils/completer.py b/qutebrowser/utils/completer.py index 3d229a120..6b2256e95 100644 --- a/qutebrowser/utils/completer.py +++ b/qutebrowser/utils/completer.py @@ -21,15 +21,12 @@ from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject -import qutebrowser.config.config as config -import qutebrowser.config.configdata as configdata -import qutebrowser.commands.utils as cmdutils +from qutebrowser.config import config, configdata +from qutebrowser.commands import utils as cmdutils +from qutebrowser.utils import usertypes from qutebrowser.utils.log import completion as logger +from qutebrowser.models import completion as models from qutebrowser.models.completionfilter import CompletionFilterModel as CFM -from qutebrowser.models.completion import ( - CommandCompletionModel, SettingSectionCompletionModel, - SettingOptionCompletionModel, SettingValueCompletionModel) -from qutebrowser.utils.usertypes import Completion class Completer(QObject): @@ -58,31 +55,32 @@ class Completer(QObject): self.ignore_change = False self._models = { - Completion.option: {}, - Completion.value: {}, + usertypes.Completion.option: {}, + usertypes.Completion.value: {}, } self._init_command_completion() self._init_setting_completions() def _init_command_completion(self): """Initialize the command completion model.""" - self._models[Completion.command] = CFM( - CommandCompletionModel(self), self) + self._models[usertypes.Completion.command] = CFM( + models.CommandCompletionModel(self), self) def _init_setting_completions(self): """Initialize setting completion models.""" - self._models[Completion.section] = CFM( - SettingSectionCompletionModel(self), self) - self._models[Completion.option] = {} - self._models[Completion.value] = {} + self._models[usertypes.Completion.section] = CFM( + models.SettingSectionCompletionModel(self), self) + self._models[usertypes.Completion.option] = {} + self._models[usertypes.Completion.value] = {} for sectname in configdata.DATA: - model = SettingOptionCompletionModel(sectname, self) - self._models[Completion.option][sectname] = CFM(model, self) + model = models.SettingOptionCompletionModel(sectname, self) + self._models[usertypes.Completion.option][sectname] = CFM( + model, self) config.instance().changed.connect(model.on_config_changed) - self._models[Completion.value][sectname] = {} + self._models[usertypes.Completion.value][sectname] = {} for opt in configdata.DATA[sectname].keys(): - model = SettingValueCompletionModel(sectname, opt, self) - self._models[Completion.value][sectname][opt] = CFM( + model = models.SettingValueCompletionModel(sectname, opt, self) + self._models[usertypes.Completion.value][sectname][opt] = CFM( model, self) config.instance().changed.connect(model.on_config_changed) @@ -95,7 +93,7 @@ class Completer(QObject): """ if cursor_part == 0: # '|' or 'set|' - return self._models[Completion.command] + return self._models[usertypes.Completion.command] # delegate completion to command try: completions = cmdutils.cmd_dict[parts[0]].completion @@ -115,10 +113,10 @@ class Completer(QObject): return None dbg_completions[idx] = '*' + dbg_completions[idx] + '*' logger.debug("completions: {}".format(', '.join(dbg_completions))) - if completion == Completion.option: + if completion == usertypes.Completion.option: section = parts[cursor_part - 1] model = self._models[completion].get(section) - elif completion == Completion.value: + elif completion == usertypes.Completion.value: section = parts[cursor_part - 2] option = parts[cursor_part - 1] try: diff --git a/qutebrowser/utils/debug.py b/qutebrowser/utils/debug.py index 462aafe3a..db621c56e 100644 --- a/qutebrowser/utils/debug.py +++ b/qutebrowser/utils/debug.py @@ -23,13 +23,13 @@ import re import pdb import sys import types -from functools import wraps +import functools from PyQt5.QtCore import pyqtRemoveInputHook, QEvent, QCoreApplication -from qutebrowser.utils.misc import elide, compact_text +from qutebrowser.utils import misc as utils from qutebrowser.utils.log import misc as logger -import qutebrowser.commands.utils as cmdutils +from qutebrowser.commands import utils as cmdutils @cmdutils.register(debug=True, name='debug-set-trace') @@ -89,7 +89,7 @@ def log_events(klass): """Class decorator to log Qt events.""" old_event = klass.event - @wraps(old_event) + @functools.wraps(old_event) def new_event(self, e, *args, **kwargs): """Wrapper for event() which logs events.""" logger.debug("Event in {}: {}".format(klass.__name__, @@ -115,7 +115,7 @@ def trace_lines(do_trace): if sys is not None: loc = '{}:{}'.format(frame.f_code.co_filename, frame.f_lineno) if arg is not None: - arg = compact_text(str(arg), 200) + arg = utils.compact_text(str(arg), 200) else: arg = '' print("{:11} {:80} {}".format(event, loc, arg), file=sys.stderr) @@ -228,5 +228,6 @@ def dbg_signal(sig, args): Return: A human-readable string representation of signal/args. """ - argstr = ', '.join([elide(str(a).replace('\n', ' '), 20) for a in args]) + argstr = ', '.join([utils.elide(str(a).replace('\n', ' '), 20) + for a in args]) return '{}({})'.format(signal_name(sig), argstr) diff --git a/qutebrowser/utils/earlyinit.py b/qutebrowser/utils/earlyinit.py index 89e714f2a..57cd423ba 100644 --- a/qutebrowser/utils/earlyinit.py +++ b/qutebrowser/utils/earlyinit.py @@ -26,9 +26,9 @@ import faulthandler import traceback import signal try: - from tkinter import Tk, messagebox # pylint: disable=import-error + import tkinter # pylint: disable=import-error except ImportError: - Tk = None + tkinter = None def _missing_str(name, debian=None, arch=None, windows=None, pip=None): @@ -186,10 +186,10 @@ def check_pyqt_core(): text = text.replace('', '') text = text.replace('', '') text = text.replace('
', '\n') - if Tk: - root = Tk() + if tkinter: + root = tkinter.Tk() root.withdraw() - messagebox.showerror("qutebrowser: Fatal error!", text) + tkinter.messagebox.showerror("qutebrowser: Fatal error!", text) else: print(text, file=sys.stderr) if '--debug' in sys.argv: diff --git a/qutebrowser/utils/editor.py b/qutebrowser/utils/editor.py index bd6591951..c29c374fc 100644 --- a/qutebrowser/utils/editor.py +++ b/qutebrowser/utils/editor.py @@ -20,12 +20,12 @@ """Launcher for an external editor.""" import os -from tempfile import mkstemp +import tempfile from PyQt5.QtCore import pyqtSignal, QProcess, QObject -import qutebrowser.config.config as config -import qutebrowser.utils.message as message +from qutebrowser.config import config +from qutebrowser.utils import message from qutebrowser.utils.log import procs as logger @@ -109,7 +109,7 @@ class ExternalEditor(QObject): if self.text is not None: raise ValueError("Already editing a file!") self.text = text - self.oshandle, self.filename = mkstemp(text=True) + self.oshandle, self.filename = tempfile.mkstemp(text=True) if text: encoding = config.get('general', 'editor-encoding') with open(self.filename, 'w', encoding=encoding) as f: diff --git a/qutebrowser/utils/http.py b/qutebrowser/utils/http.py index 90b43a18d..d9fe36d0b 100644 --- a/qutebrowser/utils/http.py +++ b/qutebrowser/utils/http.py @@ -21,7 +21,7 @@ import os.path -import qutebrowser.utils.rfc6266 as rfc6266 +from qutebrowser.utils import rfc6266 from qutebrowser.utils.log import misc as logger from PyQt5.QtNetwork import QNetworkRequest diff --git a/qutebrowser/utils/log.py b/qutebrowser/utils/log.py index b51e0754b..72b1bce11 100644 --- a/qutebrowser/utils/log.py +++ b/qutebrowser/utils/log.py @@ -24,9 +24,8 @@ import os import sys import html as pyhtml import logging -from contextlib import contextmanager -from logging import getLogger -from collections import deque +import contextlib +import collections from PyQt5.QtCore import (QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, qInstallMessageHandler) @@ -38,9 +37,9 @@ except ImportError: colorama = None try: # pylint: disable=import-error - from colorlog import ColoredFormatter + import colorlog except ImportError: - ColoredFormatter = None + colorlog = None else: # colorlog calls colorama.init() which we don't want, also it breaks our # sys.stdout/sys.stderr if they are None. Bugreports: @@ -81,25 +80,25 @@ LOG_COLORS = { # The different loggers used. -statusbar = getLogger('statusbar') -completion = getLogger('completion') -destroy = getLogger('destroy') -modes = getLogger('modes') -webview = getLogger('webview') -mouse = getLogger('mouse') -misc = getLogger('misc') -url = getLogger('url') -procs = getLogger('procs') -commands = getLogger('commands') -init = getLogger('init') -signals = getLogger('signals') -hints = getLogger('hints') -keyboard = getLogger('keyboard') -downloads = getLogger('downloads') -js = getLogger('js') # Javascript console messages -qt = getLogger('qt') # Warnings produced by Qt -style = getLogger('style') -rfc6266 = getLogger('rfc6266') +statusbar = logging.getLogger('statusbar') +completion = logging.getLogger('completion') +destroy = logging.getLogger('destroy') +modes = logging.getLogger('modes') +webview = logging.getLogger('webview') +mouse = logging.getLogger('mouse') +misc = logging.getLogger('misc') +url = logging.getLogger('url') +procs = logging.getLogger('procs') +commands = logging.getLogger('commands') +init = logging.getLogger('init') +signals = logging.getLogger('signals') +hints = logging.getLogger('hints') +keyboard = logging.getLogger('keyboard') +downloads = logging.getLogger('downloads') +js = logging.getLogger('js') # Javascript console messages +qt = logging.getLogger('qt') # Warnings produced by Qt +style = logging.getLogger('style') +rfc6266 = logging.getLogger('rfc6266') ram_handler = None @@ -114,7 +113,7 @@ def init_log(args): raise ValueError("Invalid log level: {}".format(args.loglevel)) console, ram = _init_handlers(numeric_level, args.color, args.loglines) - root = getLogger() + root = logging.getLogger() if console is not None: if args.logfilter is not None: console.addFilter(LogFilter(args.logfilter.split(','))) @@ -126,7 +125,7 @@ def init_log(args): qInstallMessageHandler(qt_message_handler) -@contextmanager +@contextlib.contextmanager def disable_qt_msghandler(): """Contextmanager which temporarely disables the Qt message handler.""" old_handler = qInstallMessageHandler(None) @@ -191,10 +190,10 @@ def _init_formatters(level, color): if sys.stderr is None: return None, ram_formatter, html_formatter, False use_colorama = False - if (ColoredFormatter is not None and (os.name == 'posix' or colorama) and + if (colorlog is not None and (os.name == 'posix' or colorama) and sys.stderr.isatty() and color): - console_formatter = ColoredFormatter(console_fmt_colored, DATEFMT, - log_colors=LOG_COLORS) + console_formatter = colorlog.ColoredFormatter( + console_fmt_colored, DATEFMT, log_colors=LOG_COLORS) if colorama: use_colorama = True else: @@ -310,9 +309,9 @@ class RAMHandler(logging.Handler): super().__init__() self.html_formatter = None if capacity != -1: - self.data = deque(maxlen=capacity) + self.data = collections.deque(maxlen=capacity) else: - self.data = deque() + self.data = collections.deque() def emit(self, record): self.data.append(record) diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py index cd7356197..84d08653e 100644 --- a/qutebrowser/utils/message.py +++ b/qutebrowser/utils/message.py @@ -21,7 +21,7 @@ from PyQt5.QtCore import pyqtSignal, QCoreApplication, QObject, QTimer -from qutebrowser.utils.usertypes import PromptMode, Question +from qutebrowser.utils import usertypes from qutebrowser.utils.log import misc as logger @@ -64,7 +64,7 @@ def ask(message, mode, default=None): Return: The answer the user gave or None if the prompt was cancelled. """ - q = Question() + q = usertypes.Question() q.text = message q.mode = mode q.default = default @@ -75,9 +75,9 @@ def ask(message, mode, default=None): def alert(message): """Display an alert which needs to be confirmed.""" - q = Question() + q = usertypes.Question() q.text = message - q.mode = PromptMode.alert + q.mode = usertypes.PromptMode.alert instance().ask(q, blocking=True) q.deleteLater() @@ -91,10 +91,10 @@ def ask_async(message, mode, handler, default=None): handler: The function to get called with the answer as argument. default: The default value to display. """ - if not isinstance(mode, PromptMode): + if not isinstance(mode, usertypes.PromptMode): raise TypeError("Mode {} is no PromptMode member!".format(mode)) bridge = instance() - q = Question(bridge) + q = usertypes.Question(bridge) q.text = message q.mode = mode q.default = default @@ -113,9 +113,9 @@ def confirm_async(message, yes_action, no_action=None, default=None): default: True/False to set a default value, or None. """ bridge = instance() - q = Question(bridge) + q = usertypes.Question(bridge) q.text = message - q.mode = PromptMode.yesno + q.mode = usertypes.PromptMode.yesno q.default = default q.answered_yes.connect(yes_action) if no_action is not None: @@ -152,7 +152,7 @@ class MessageBridge(QObject): s_info = pyqtSignal(str, bool) s_set_text = pyqtSignal(str) s_set_cmd_text = pyqtSignal(str) - s_question = pyqtSignal(Question, bool) + s_question = pyqtSignal(usertypes.Question, bool) def __repr__(self): return '<{}>'.format(self.__class__.__name__) diff --git a/qutebrowser/utils/misc.py b/qutebrowser/utils/misc.py index f9b71ca85..de0b2b98f 100644 --- a/qutebrowser/utils/misc.py +++ b/qutebrowser/utils/misc.py @@ -25,17 +25,17 @@ import sys import shlex import os.path import urllib.request -from urllib.parse import urljoin, urlencode -from collections import OrderedDict -from functools import reduce -from contextlib import contextmanager +import urllib.parse +import collections +import functools +import contextlib from PyQt5.QtCore import QCoreApplication, QStandardPaths, Qt from PyQt5.QtGui import QKeySequence, QColor -from pkg_resources import resource_string +import pkg_resources import qutebrowser -from qutebrowser.utils.qt import qt_version_check, qt_ensure_valid +from qutebrowser.utils import qt as qtutils def elide(text, length): @@ -81,7 +81,8 @@ def read_file(filename): with open(fn, 'r', encoding='utf-8') as f: return f.read() else: - return resource_string(qutebrowser.__name__, filename).decode('UTF-8') + data = pkg_resources.resource_string(qutebrowser.__name__, filename) + return data.decode('UTF-8') def dotted_getattr(obj, path): @@ -94,7 +95,7 @@ def dotted_getattr(obj, path): Return: The object at path. """ - return reduce(getattr, path.split('.'), obj) + return functools.reduce(getattr, path.split('.'), obj) def safe_shlex_split(s): @@ -134,8 +135,8 @@ def pastebin(text): 'title': "qutebrowser crash", 'name': "qutebrowser", } - encoded_data = urlencode(data).encode('utf-8') - create_url = urljoin(api_url, 'create') + encoded_data = urllib.parse.urlencode(data).encode('utf-8') + create_url = urllib.parse.urljoin(api_url, 'create') headers = { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' } @@ -189,7 +190,7 @@ def actute_warning(): return # Qt >= 5.3 doesn't seem to be affected try: - if qt_version_check('5.3.0'): + if qtutils.qt_version_check('5.3.0'): return except ValueError: pass @@ -246,8 +247,8 @@ def interpolate_color(start, end, percent, colorspace=QColor.Rgb): Raise: ValueError if invalid parameters are passed. """ - qt_ensure_valid(start) - qt_ensure_valid(end) + qtutils.qt_ensure_valid(start) + qtutils.qt_ensure_valid(end) out = QColor() if colorspace == QColor.Rgb: a_c1, a_c2, a_c3, _alpha = start.getRgb() @@ -270,7 +271,7 @@ def interpolate_color(start, end, percent, colorspace=QColor.Rgb): else: raise ValueError("Invalid colorspace!") out = out.convertTo(start.spec()) - qt_ensure_valid(out) + qtutils.qt_ensure_valid(out) return out @@ -400,7 +401,7 @@ def keyevent_to_string(e): A name of the key (combination) as a string or None if only modifiers are pressed.. """ - modmask2str = OrderedDict([ + modmask2str = collections.OrderedDict([ (Qt.ControlModifier, 'Ctrl'), (Qt.AltModifier, 'Alt'), (Qt.MetaModifier, 'Meta'), @@ -460,7 +461,7 @@ class FakeIOStream(io.TextIOBase): return super().isatty() -@contextmanager +@contextlib.contextmanager def fake_io(write_func): """Run code with stdout and stderr replaced by FakeIOStreams. @@ -482,7 +483,7 @@ def fake_io(write_func): sys.stderr = old_stderr -@contextmanager +@contextlib.contextmanager def disabled_excepthook(): """Run code with the exception hook temporarely disabled.""" old_excepthook = sys.excepthook diff --git a/qutebrowser/utils/readline.py b/qutebrowser/utils/readline.py index 04c59e8e2..71f102a64 100644 --- a/qutebrowser/utils/readline.py +++ b/qutebrowser/utils/readline.py @@ -21,8 +21,8 @@ from PyQt5.QtWidgets import QApplication, QLineEdit -import qutebrowser.commands.utils as cmd -from qutebrowser.utils.usertypes import KeyMode +from qutebrowser.commands import utils as cmdutils +from qutebrowser.utils import usertypes as typ class ReadlineBridge: @@ -45,8 +45,8 @@ class ReadlineBridge: else: return None - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_backward_char(self): """Move back a character. @@ -56,8 +56,8 @@ class ReadlineBridge: return self.widget.cursorBackward(False) - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_forward_char(self): """Move forward a character. @@ -67,8 +67,8 @@ class ReadlineBridge: return self.widget.cursorForward(False) - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_backward_word(self): """Move back to the start of the current or previous word. @@ -78,8 +78,8 @@ class ReadlineBridge: return self.widget.cursorWordBackward(False) - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_forward_word(self): """Move forward to the end of the next word. @@ -89,8 +89,8 @@ class ReadlineBridge: return self.widget.cursorWordForward(False) - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_beginning_of_line(self): """Move to the start of the line. @@ -100,8 +100,8 @@ class ReadlineBridge: return self.widget.home(False) - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_end_of_line(self): """Move to the end of the line. @@ -111,8 +111,8 @@ class ReadlineBridge: return self.widget.end(False) - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_unix_line_discard(self): """Remove chars backward from the cursor to the beginning of the line. @@ -124,8 +124,8 @@ class ReadlineBridge: self.deleted[self.widget] = self.widget.selectedText() self.widget.del_() - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_kill_line(self): """Remove chars from the cursor to the end of the line. @@ -137,8 +137,8 @@ class ReadlineBridge: self.deleted[self.widget] = self.widget.selectedText() self.widget.del_() - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_unix_word_rubout(self): """Remove chars from the cursor to the beginning of the word. @@ -150,8 +150,8 @@ class ReadlineBridge: self.deleted[self.widget] = self.widget.selectedText() self.widget.del_() - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_kill_word(self): """Remove chars from the cursor to the end of the current word. @@ -163,8 +163,8 @@ class ReadlineBridge: self.deleted[self.widget] = self.widget.selectedText() self.widget.del_() - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_yank(self): """Paste the most recently deleted text. @@ -174,8 +174,8 @@ class ReadlineBridge: return self.widget.insert(self.deleted[self.widget]) - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_delete_char(self): """Delete the character after the cursor. @@ -185,8 +185,8 @@ class ReadlineBridge: return self.widget.del_() - @cmd.register(instance='rl_bridge', hide=True, - modes=[KeyMode.command, KeyMode.prompt]) + @cmdutils.register(instance='rl_bridge', hide=True, + modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_backward_delete_char(self): """Delete the character before the cursor. diff --git a/qutebrowser/utils/rfc6266.py b/qutebrowser/utils/rfc6266.py index c7751bff9..28b766c78 100644 --- a/qutebrowser/utils/rfc6266.py +++ b/qutebrowser/utils/rfc6266.py @@ -19,7 +19,7 @@ """pyPEG parsing for the RFC 6266 (Content-Disposition) header. """ -from collections import namedtuple +import collections import urllib.parse import string import re @@ -209,7 +209,7 @@ class ContentDispositionValue: peg.optional(';')) -LangTagged = namedtuple('LangTagged', 'string langtag') +LangTagged = collections.namedtuple('LangTagged', 'string langtag') class DuplicateParamError(Exception): diff --git a/qutebrowser/utils/url.py b/qutebrowser/utils/url.py index ebce89eb4..471647825 100644 --- a/qutebrowser/utils/url.py +++ b/qutebrowser/utils/url.py @@ -26,9 +26,9 @@ import urllib.parse from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QHostInfo -import qutebrowser.config.config as config +from qutebrowser.config import config +from qutebrowser.utils import qt as qtutils from qutebrowser.utils.log import url as logger -from qutebrowser.utils.misc import qt_ensure_valid # FIXME: we probably could raise some exceptions on invalid URLs @@ -65,7 +65,7 @@ def _get_search_url(txt): if not term: raise FuzzyUrlError("No search term given") url = QUrl.fromUserInput(template.format(urllib.parse.quote(term))) - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) return url @@ -143,7 +143,7 @@ def fuzzy_url(urlstr): url = QUrl.fromUserInput(stripped) logger.debug("Converting fuzzy term {} to URL -> {}".format( urlstr, url.toDisplayString())) - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) return url diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 43b31464d..c8c185a93 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -29,8 +29,8 @@ import enum as pyenum from PyQt5.QtCore import pyqtSignal, QObject, QTimer +from qutebrowser.utils import qt as qtutils from qutebrowser.utils.log import misc as logger -from qutebrowser.utils.qt import check_overflow _UNSET = object() @@ -372,13 +372,13 @@ class Timer(QTimer): def setInterval(self, msec): """Extend setInterval to check for overflows.""" - check_overflow(msec, 'int') + qtutils.check_overflow(msec, 'int') super().setInterval(msec) def start(self, msec=None): """Extend start to check for overflows.""" if msec is not None: - check_overflow(msec, 'int') + qtutils.check_overflow(msec, 'int') super().start(msec) else: super().start() diff --git a/qutebrowser/utils/utilcmds.py b/qutebrowser/utils/utilcmds.py index cc367cd17..07a897e71 100644 --- a/qutebrowser/utils/utilcmds.py +++ b/qutebrowser/utils/utilcmds.py @@ -21,10 +21,10 @@ from functools import partial -import qutebrowser.commands.utils as cmdutils -from qutebrowser.utils.usertypes import Timer -from qutebrowser.commands.exceptions import CommandError -from qutebrowser.commands.runners import CommandRunner +from qutebrowser.utils import usertypes +from qutebrowser.commands import runners +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc _timers = [] @@ -34,7 +34,7 @@ _commandrunner = None def init(): """Initialize the global _commandrunner.""" global _commandrunner - _commandrunner = CommandRunner() + _commandrunner = runners.CommandRunner() @cmdutils.register(nargs=(2, None)) @@ -46,15 +46,15 @@ def later(ms, *command): command: The command/args to run. """ ms = int(ms) - timer = Timer(name='later') + timer = usertypes.Timer(name='later') timer.setSingleShot(True) if ms < 0: - raise CommandError("I can't run something in the past!") + raise cmdexc.CommandError("I can't run something in the past!") try: timer.setInterval(ms) except OverflowError: - raise CommandError("Numeric argument is too large for internal int " - "representation.") + raise cmdexc.CommandError("Numeric argument is too large for internal " + "int representation.") _timers.append(timer) cmdline = ' '.join(command) timer.timeout.connect(partial(_commandrunner.run_safely, cmdline)) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index bfaa98b4c..66ab3e4f3 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -29,7 +29,7 @@ from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, qVersion from PyQt5.QtWebKit import qWebKitVersion import qutebrowser -from qutebrowser.utils.misc import read_file +from qutebrowser.utils import misc as utils from qutebrowser.utils.log import misc as logger @@ -91,7 +91,7 @@ def _git_str(): return commit # If that fails, check the git-commit-id file. try: - return read_file('git-commit-id') + return utils.read_file('git-commit-id') except (FileNotFoundError, ImportError): return None diff --git a/qutebrowser/utils/webelem.py b/qutebrowser/utils/webelem.py index 7dfc4cc08..2faea4e49 100644 --- a/qutebrowser/utils/webelem.py +++ b/qutebrowser/utils/webelem.py @@ -30,13 +30,13 @@ Module attributes: from PyQt5.QtCore import QRect, QUrl from PyQt5.QtWebKit import QWebElement -import qutebrowser.utils.log as log -import qutebrowser.config.config as config -from qutebrowser.utils.usertypes import enum -from qutebrowser.utils.misc import compact_text +from qutebrowser.config import config +from qutebrowser.utils import log, usertypes +from qutebrowser.utils import misc as utils -Group = enum('Group', 'all', 'links', 'images', 'url', 'prevnext', 'focus') +Group = usertypes.enum('Group', 'all', 'links', 'images', 'url', 'prevnext', + 'focus') SELECTORS = { @@ -284,4 +284,4 @@ def focus_elem(frame): def debug_text(elem): """Get a text based on an element suitable for debug output.""" - return compact_text(elem.toOuterXml(), 500) + return utils.compact_text(elem.toOuterXml(), 500) diff --git a/qutebrowser/widgets/completion.py b/qutebrowser/widgets/completion.py index 9d03cbd4a..32ec0a7b7 100644 --- a/qutebrowser/widgets/completion.py +++ b/qutebrowser/widgets/completion.py @@ -26,13 +26,11 @@ subclasses to provide completions. from PyQt5.QtWidgets import QStyle, QTreeView, QSizePolicy from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QItemSelectionModel -import qutebrowser.config.config as config -import qutebrowser.commands.utils as cmdutils -from qutebrowser.widgets.completiondelegate import CompletionItemDelegate -from qutebrowser.config.style import set_register_stylesheet -from qutebrowser.utils.completer import Completer -from qutebrowser.utils.qt import qt_ensure_valid -from qutebrowser.utils.usertypes import KeyMode +from qutebrowser.commands import utils as cmdutils +from qutebrowser.config import config, style +from qutebrowser.widgets import completiondelegate +from qutebrowser.utils import completer, usertypes +from qutebrowser.utils import qt as qtutils class CompletionView(QTreeView): @@ -94,12 +92,12 @@ class CompletionView(QTreeView): def __init__(self, parent=None): super().__init__(parent) - self.completer = Completer(self) + self.completer = completer.Completer(self) self.enabled = config.get('completion', 'show') - self._delegate = CompletionItemDelegate(self) + self._delegate = completiondelegate.CompletionItemDelegate(self) self.setItemDelegate(self._delegate) - set_register_stylesheet(self) + style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum) self.setHeaderHidden(True) self.setIndentation(0) @@ -169,7 +167,7 @@ class CompletionView(QTreeView): # No completion running at the moment, ignore keypress return idx = self._next_idx(prev) - qt_ensure_valid(idx) + qtutils.qt_ensure_valid(idx) self.selectionModel().setCurrentIndex( idx, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) @@ -212,13 +210,13 @@ class CompletionView(QTreeView): selmod.clearCurrentIndex() @cmdutils.register(instance='mainwindow.completion', hide=True, - modes=[KeyMode.command]) + modes=[usertypes.KeyMode.command]) def completion_item_prev(self): """Select the previous completion item.""" self._next_prev_item(prev=True) @cmdutils.register(instance='mainwindow.completion', hide=True, - modes=[KeyMode.command]) + modes=[usertypes.KeyMode.command]) def completion_item_next(self): """Select the next completion item.""" self._next_prev_item(prev=False) diff --git a/qutebrowser/widgets/completiondelegate.py b/qutebrowser/widgets/completiondelegate.py index c52ae2b00..303c4e643 100644 --- a/qutebrowser/widgets/completiondelegate.py +++ b/qutebrowser/widgets/completiondelegate.py @@ -28,10 +28,9 @@ from PyQt5.QtCore import QRectF, QSize, Qt from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption, QTextCursor, QAbstractTextDocumentLayout) -import qutebrowser.config.config as config -from qutebrowser.models.basecompletion import Role -from qutebrowser.config.style import get_stylesheet -from qutebrowser.utils.qt import qt_ensure_valid +from qutebrowser.config import config, style +from qutebrowser.models import basecompletion +from qutebrowser.utils import qt as qtutils class CompletionItemDelegate(QStyledItemDelegate): @@ -99,12 +98,12 @@ class CompletionItemDelegate(QStyledItemDelegate): text_rect_ = self._style.subElementRect( self._style.SE_ItemViewItemText, self._opt, self._opt.widget) - qt_ensure_valid(text_rect_) + qtutils.qt_ensure_valid(text_rect_) margin = self._style.pixelMetric(QStyle.PM_FocusFrameHMargin, self._opt, self._opt.widget) + 1 # remove width padding text_rect = text_rect_.adjusted(margin, 0, -margin, 0) - qt_ensure_valid(text_rect) + qtutils.qt_ensure_valid(text_rect) # move text upwards a bit if index.parent().isValid(): text_rect.adjust(0, -1, 0, -1) @@ -189,7 +188,7 @@ class CompletionItemDelegate(QStyledItemDelegate): self._doc.setHtml('{}'.format(html.escape(self._opt.text))) self._doc.setDefaultFont(self._opt.font) self._doc.setDefaultTextOption(text_option) - self._doc.setDefaultStyleSheet(get_stylesheet(""" + self._doc.setDefaultStyleSheet(style.get_stylesheet(""" .highlight {{ {color[completion.match.fg]} }} @@ -197,7 +196,7 @@ class CompletionItemDelegate(QStyledItemDelegate): self._doc.setDocumentMargin(2) if index.column() == 0: - marks = index.data(Role.marks) + marks = index.data(basecompletion.Role.marks) if marks is None: return for mark in marks: @@ -218,7 +217,7 @@ class CompletionItemDelegate(QStyledItemDelegate): o.rect = self._style.subElementRect( self._style.SE_ItemViewItemFocusRect, self._opt, self._opt.widget) o.state |= QStyle.State_KeyboardFocusChange | QStyle.State_Item - qt_ensure_valid(o.rect) + qtutils.qt_ensure_valid(o.rect) if state & QStyle.State_Enabled: cg = QPalette.Normal else: @@ -254,7 +253,7 @@ class CompletionItemDelegate(QStyledItemDelegate): docsize = self._doc.size().toSize() size = self._style.sizeFromContents(QStyle.CT_ItemViewItem, self._opt, docsize, self._opt.widget) - qt_ensure_valid(size) + qtutils.qt_ensure_valid(size) return size + QSize(10, 3) def paint(self, painter, option, index): diff --git a/qutebrowser/widgets/console.py b/qutebrowser/widgets/console.py index 40bfdb700..6051070ad 100644 --- a/qutebrowser/widgets/console.py +++ b/qutebrowser/widgets/console.py @@ -20,19 +20,18 @@ """Debugging console.""" import sys -from code import InteractiveInterpreter +import code from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt from PyQt5.QtWidgets import QTextEdit, QWidget, QVBoxLayout, QApplication -import qutebrowser.config.config as config -from qutebrowser.models.cmdhistory import (History, HistoryEmptyError, - HistoryEndReachedError) -from qutebrowser.utils.misc import fake_io, disabled_excepthook -from qutebrowser.widgets.misc import CommandLineEdit +from qutebrowser.config import config +from qutebrowser.models import cmdhistory +from qutebrowser.utils import misc as utils +from qutebrowser.widgets import misc -class ConsoleLineEdit(CommandLineEdit): +class ConsoleLineEdit(misc.CommandLineEdit): """A QLineEdit which executes entered code and provides a history.""" @@ -56,8 +55,8 @@ class ConsoleLineEdit(CommandLineEdit): # console, not just the line edit. 'self': parent, } - self._interpreter = InteractiveInterpreter(interpreter_locals) - self.history = History() + self._interpreter = code.InteractiveInterpreter(interpreter_locals) + self.history = cmdhistory.History() self.returnPressed.connect(self.execute) self.setText('') @@ -88,7 +87,7 @@ class ConsoleLineEdit(CommandLineEdit): # same. # - We disable our exception hook, so exceptions from the console get # printed and don't ooen a crashdialog. - with fake_io(self.write.emit), disabled_excepthook(): + with utils.fake_io(self.write.emit), utils.disabled_excepthook(): self._more = self._interpreter.runsource(source, '') self.set_prompt(self.curprompt) if not self._more: @@ -101,7 +100,8 @@ class ConsoleLineEdit(CommandLineEdit): item = self.history.start(self.text().strip()) else: item = self.history.previtem() - except (HistoryEmptyError, HistoryEndReachedError): + except (cmdhistory.HistoryEmptyError, + cmdhistory.HistoryEndReachedError): return self.setText(item) @@ -111,7 +111,7 @@ class ConsoleLineEdit(CommandLineEdit): return try: item = self.history.nextitem() - except HistoryEndReachedError: + except cmdhistory.HistoryEndReachedError: return self.setText(item) diff --git a/qutebrowser/widgets/crash.py b/qutebrowser/widgets/crash.py index e8b453c92..4bba8207a 100644 --- a/qutebrowser/widgets/crash.py +++ b/qutebrowser/widgets/crash.py @@ -21,17 +21,16 @@ import sys import traceback -from urllib.error import URLError -from getpass import getuser +import urllib.error +import getpass from PyQt5.QtCore import Qt, QSize from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton, QVBoxLayout, QHBoxLayout) -import qutebrowser.config.config as config -import qutebrowser.utils.misc as utils -import qutebrowser.utils.log as logutils -from qutebrowser.utils.version import version +from qutebrowser.config import config +from qutebrowser.utils import version, log +from qutebrowser.utils import misc as utils class _CrashDialog(QDialog): @@ -124,11 +123,11 @@ class _CrashDialog(QDialog): ] try: self._crash_info.append(("Contact info", - "User: {}".format(getuser()))) + "User: {}".format(getpass.getuser()))) except Exception as e: # pylint: disable=broad-except self._crash_info.append(("Contact info", "User: {}: {}".format( e.__class__.__name__, e))) - self._crash_info.append(("Version info", version())) + self._crash_info.append(("Version info", version.version())) try: self._crash_info.append(("Config", config.instance().dump_userconfig())) @@ -156,7 +155,7 @@ class _CrashDialog(QDialog): """Paste the crash info into the pastebin.""" try: url = utils.pastebin(self._txt.toPlainText()) - except (URLError, ValueError) as e: + except (urllib.error.URLError, ValueError) as e: self._url.setText('Error while reporting: {}: {}'.format( e.__class__.__name__, e)) return @@ -228,8 +227,7 @@ class ExceptionCrashDialog(_CrashDialog): ("Objects", self._objects), ] try: - self._crash_info.append(("Debug log", - logutils.ram_handler.dump_log())) + self._crash_info.append(("Debug log", log.ram_handler.dump_log())) except AttributeError as e: self._crash_info.append(("Debug log", "{}: {}".format( e.__class__.__name__, e))) @@ -245,8 +243,8 @@ class FatalCrashDialog(_CrashDialog): _btn_pastebin: The pastebin button. """ - def __init__(self, log, parent=None): - self._log = log + def __init__(self, text, parent=None): + self._log = text self._btn_ok = None self._btn_pastebin = None super().__init__(parent) @@ -329,8 +327,7 @@ class ReportDialog(_CrashDialog): ("Objects", self._objects), ] try: - self._crash_info.append(("Debug log", - logutils.ram_handler.dump_log())) + self._crash_info.append(("Debug log", log.ram_handler.dump_log())) except AttributeError as e: self._crash_info.append(("Debug log", "{}: {}".format( e.__class__.__name__, e))) diff --git a/qutebrowser/widgets/downloads.py b/qutebrowser/widgets/downloads.py index 390ce4bf3..edcb513c6 100644 --- a/qutebrowser/widgets/downloads.py +++ b/qutebrowser/widgets/downloads.py @@ -22,9 +22,9 @@ from PyQt5.QtCore import pyqtSlot, QSize, Qt from PyQt5.QtWidgets import QListView, QSizePolicy, QMenu -from qutebrowser.models.downloadmodel import DownloadModel, Role -from qutebrowser.config.style import set_register_stylesheet -from qutebrowser.utils.qt import qt_ensure_valid +from qutebrowser.models import downloadmodel +from qutebrowser.config import style +from qutebrowser.utils import qt as qtutils class DownloadView(QListView): @@ -49,13 +49,13 @@ class DownloadView(QListView): def __init__(self, parent=None): super().__init__(parent) - set_register_stylesheet(self) + style.set_register_stylesheet(self) self.setResizeMode(QListView.Adjust) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.setFlow(QListView.LeftToRight) self._menu = None - self._model = DownloadModel(self) + self._model = downloadmodel.DownloadModel(self) self._model.rowsInserted.connect(self.updateGeometry) self._model.rowsRemoved.connect(self.updateGeometry) self.setModel(self._model) @@ -73,7 +73,7 @@ class DownloadView(QListView): index = self.indexAt(point) if not index.isValid(): return - item = self.model().data(index, Role.item) + item = self.model().data(index, downloadmodel.Role.item) self._menu = QMenu(self) cancel = self._menu.addAction("Cancel") cancel.triggered.connect(item.cancel) @@ -91,5 +91,5 @@ class DownloadView(QListView): size = QSize(0, height + 2) else: size = QSize(0, 0) - qt_ensure_valid(size) + qtutils.qt_ensure_valid(size) return size diff --git a/qutebrowser/widgets/mainwindow.py b/qutebrowser/widgets/mainwindow.py index 7b73a9f3f..aacac384f 100644 --- a/qutebrowser/widgets/mainwindow.py +++ b/qutebrowser/widgets/mainwindow.py @@ -20,21 +20,17 @@ """The main window of qutebrowser.""" import binascii -from base64 import b64decode +import base64 from PyQt5.QtCore import pyqtSlot, QRect, QPoint, QCoreApplication, QTimer from PyQt5.QtWidgets import QWidget, QVBoxLayout -import qutebrowser.commands.utils as cmdutils -import qutebrowser.config.config as config -import qutebrowser.utils.message as message -import qutebrowser.utils.log as log -from qutebrowser.widgets.statusbar.bar import StatusBar -from qutebrowser.widgets.tabbedbrowser import TabbedBrowser -from qutebrowser.widgets.completion import CompletionView -from qutebrowser.widgets.downloads import DownloadView -from qutebrowser.utils.usertypes import PromptMode -from qutebrowser.utils.qt import check_overflow +from qutebrowser.commands import utils as cmdutils +from qutebrowser.config import config +from qutebrowser.utils import message, log, usertypes +from qutebrowser.utils import qt as qtutils +from qutebrowser.widgets import tabbedbrowser, completion, downloads +from qutebrowser.widgets.statusbar import bar class MainWindow(QWidget): @@ -57,9 +53,9 @@ class MainWindow(QWidget): self.setWindowTitle('qutebrowser') try: stateconf = QCoreApplication.instance().stateconfig - base64 = stateconf['geometry']['mainwindow'] - log.init.debug("Restoring mainwindow from {}".format(base64)) - geom = b64decode(base64, validate=True) + data = stateconf['geometry']['mainwindow'] + log.init.debug("Restoring mainwindow from {}".format(data)) + geom = base64.b64decode(data, validate=True) except (KeyError, binascii.Error) as e: log.init.warning("Error while reading geometry: {}: {}".format( e.__class__.__name__, e)) @@ -81,17 +77,17 @@ class MainWindow(QWidget): self._vbox.setContentsMargins(0, 0, 0, 0) self._vbox.setSpacing(0) - self.downloadview = DownloadView() + self.downloadview = downloads.DownloadView() self._vbox.addWidget(self.downloadview) self.downloadview.show() - self.tabs = TabbedBrowser() + self.tabs = tabbedbrowser.TabbedBrowser() self.tabs.title_changed.connect(self.setWindowTitle) self._vbox.addWidget(self.tabs) - self.completion = CompletionView(self) + self.completion = completion.CompletionView(self) - self.status = StatusBar() + self.status = bar.StatusBar() self._vbox.addWidget(self.status) # When we're here the statusbar might not even really exist yet, so @@ -139,7 +135,7 @@ class MainWindow(QWidget): # hpoint now would be the bottom-left edge of the widget if it was on # the top of the main window. topleft_y = self.height() - self.status.height() - height - topleft_y = check_overflow(topleft_y, 'int', fatal=False) + topleft_y = qtutils.check_overflow(topleft_y, 'int', fatal=False) topleft = QPoint(0, topleft_y) bottomright = self.status.geometry().topRight() rect = QRect(topleft, bottomright) @@ -178,7 +174,8 @@ class MainWindow(QWidget): else: text = "Close {} {}?".format( count, "tab" if count == 1 else "tabs") - confirmed = message.ask(text, PromptMode.yesno, default=True) + confirmed = message.ask(text, usertypes.PromptMode.yesno, + default=True) if confirmed: e.accept() else: diff --git a/qutebrowser/widgets/misc.py b/qutebrowser/widgets/misc.py index 1233a4f64..948f83680 100644 --- a/qutebrowser/widgets/misc.py +++ b/qutebrowser/widgets/misc.py @@ -23,7 +23,7 @@ from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QLineEdit from PyQt5.QtGui import QValidator -from qutebrowser.models.cmdhistory import History +from qutebrowser.models import cmdhistory class MinimalLineEditMixin: @@ -55,7 +55,7 @@ class CommandLineEdit(QLineEdit): def __init__(self, parent=None): super().__init__(parent) - self.history = History() + self.history = cmdhistory.History() self._validator = _CommandValidator(self) self.setValidator(self._validator) self.textEdited.connect(self.on_text_edited) diff --git a/qutebrowser/widgets/statusbar/bar.py b/qutebrowser/widgets/statusbar/bar.py index 08f68f1fc..ab459d2b3 100644 --- a/qutebrowser/widgets/statusbar/bar.py +++ b/qutebrowser/widgets/statusbar/bar.py @@ -19,27 +19,22 @@ """The main statusbar widget.""" -from collections import deque -from datetime import datetime +import collections +import datetime from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, Qt from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy -import qutebrowser.keyinput.modeman as modeman -import qutebrowser.config.config as config +from qutebrowser.keyinput import modeman +from qutebrowser.config import config, style +from qutebrowser.utils import usertypes from qutebrowser.utils.log import statusbar as logger -from qutebrowser.widgets.statusbar.command import Command -from qutebrowser.widgets.statusbar.progress import Progress -from qutebrowser.widgets.statusbar.text import Text -from qutebrowser.widgets.statusbar.keystring import KeyString -from qutebrowser.widgets.statusbar.percentage import Percentage -from qutebrowser.widgets.statusbar.url import UrlText -from qutebrowser.widgets.statusbar.prompt import Prompt -from qutebrowser.config.style import set_register_stylesheet, get_stylesheet -from qutebrowser.utils.usertypes import Timer, KeyMode, enum +from qutebrowser.widgets.statusbar import (command, progress, keystring, + percentage, url, prompt) +from qutebrowser.widgets.statusbar import text as textwidget -PreviousWidget = enum('PreviousWidget', 'none', 'prompt', 'command') +PreviousWidget = usertypes.enum('PreviousWidget', 'none', 'prompt', 'command') class StatusBar(QWidget): @@ -128,7 +123,7 @@ class StatusBar(QWidget): super().__init__(parent) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) - set_register_stylesheet(self) + style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) @@ -143,18 +138,18 @@ class StatusBar(QWidget): self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) - self.cmd = Command() + self.cmd = command.Command() self._stack.addWidget(self.cmd) - self.txt = Text() + self.txt = textwidget.Text() self._stack.addWidget(self.txt) self._timer_was_active = False - self._text_queue = deque() - self._text_pop_timer = Timer(self, 'statusbar_text_pop') + self._text_queue = collections.deque() + self._text_pop_timer = usertypes.Timer(self, 'statusbar_text_pop') self._text_pop_timer.setInterval(config.get('ui', 'message-timeout')) self._text_pop_timer.timeout.connect(self._pop_text) - self.prompt = Prompt() + self.prompt = prompt.Prompt() self._stack.addWidget(self.prompt) self._previous_widget = PreviousWidget.none @@ -165,19 +160,19 @@ class StatusBar(QWidget): self.prompt.hide_prompt.connect(self._hide_prompt_widget) self._hide_prompt_widget() - self.keystring = KeyString() + self.keystring = keystring.KeyString() self._hbox.addWidget(self.keystring) - self.url = UrlText() + self.url = url.UrlText() self._hbox.addWidget(self.url) - self.percentage = Percentage() + self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) # We add a parent to Progress here because it calls self.show() based # on some signals, and if that happens before it's added to the layout, # it will quickly blink up as independent window. - self.prog = Progress(self) + self.prog = progress.Progress(self) self._hbox.addWidget(self.prog) def __repr__(self): @@ -198,7 +193,7 @@ class StatusBar(QWidget): """ logger.debug("Setting error to {}".format(val)) self._error = val - self.setStyleSheet(get_stylesheet(self.STYLESHEET)) + self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) if val: # If we got an error while command/prompt was shown, raise the text # widget. @@ -219,7 +214,7 @@ class StatusBar(QWidget): """ logger.debug("Setting prompt_active to {}".format(val)) self._prompt_active = val - self.setStyleSheet(get_stylesheet(self.STYLESHEET)) + self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) @pyqtProperty(bool) def insert_active(self): @@ -236,7 +231,7 @@ class StatusBar(QWidget): """ logger.debug("Setting insert_active to {}".format(val)) self._insert_active = val - self.setStyleSheet(get_stylesheet(self.STYLESHEET)) + self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) def _pop_text(self): """Display a text in the statusbar and pop it from _text_queue.""" @@ -316,7 +311,7 @@ class StatusBar(QWidget): """ # FIXME probably using a QTime here would be easier. logger.debug("Displaying text: {} (error={})".format(text, error)) - now = datetime.now() + now = datetime.datetime.now() mindelta = config.get('ui', 'message-timeout') delta = (None if self._last_text_time is None else now - self._last_text_time) @@ -379,20 +374,20 @@ class StatusBar(QWidget): """Set a normal (persistent) text in the status bar.""" self.txt.normaltext = val - @pyqtSlot(KeyMode) + @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Mark certain modes in the commandline.""" if mode in modeman.instance().passthrough: self.txt.normaltext = "-- {} MODE --".format(mode.name.upper()) - if mode == KeyMode.insert: + if mode == usertypes.KeyMode.insert: self.insert_active = True - @pyqtSlot(KeyMode) + @pyqtSlot(usertypes.KeyMode) def on_mode_left(self, mode): """Clear marked mode.""" if mode in modeman.instance().passthrough: self.txt.normaltext = "" - if mode == KeyMode.insert: + if mode == usertypes.KeyMode.insert: self.insert_active = False @pyqtSlot(str, str) diff --git a/qutebrowser/widgets/statusbar/command.py b/qutebrowser/widgets/statusbar/command.py index 4efc17357..bd2f94a31 100644 --- a/qutebrowser/widgets/statusbar/command.py +++ b/qutebrowser/widgets/statusbar/command.py @@ -22,19 +22,17 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot from PyQt5.QtWidgets import QSizePolicy, QApplication -import qutebrowser.keyinput.modeman as modeman -import qutebrowser.commands.utils as cmdutils -from qutebrowser.widgets.misc import MinimalLineEditMixin, CommandLineEdit -from qutebrowser.commands.runners import CommandRunner -from qutebrowser.keyinput.modeparsers import STARTCHARS +from qutebrowser.keyinput import modeman, modeparsers +from qutebrowser.commands import runners +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.widgets import misc +from qutebrowser.models import cmdhistory +from qutebrowser.utils import usertypes from qutebrowser.utils.log import completion as logger -from qutebrowser.models.cmdhistory import (HistoryEmptyError, - HistoryEndReachedError) -from qutebrowser.commands.exceptions import CommandError -from qutebrowser.utils.usertypes import KeyMode -class Command(MinimalLineEditMixin, CommandLineEdit): +class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit): """The commandline part of the statusbar. @@ -76,8 +74,8 @@ class Command(MinimalLineEditMixin, CommandLineEdit): # for a possible fix. def __init__(self, parent=None): - CommandLineEdit.__init__(self, parent) - MinimalLineEditMixin.__init__(self) + misc.CommandLineEdit.__init__(self, parent) + misc.MinimalLineEditMixin.__init__(self) self.cursor_part = 0 self.history.history = QApplication.instance().cmd_history.data self._empty_item_idx = None @@ -92,7 +90,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit): text = self.text() if not text: return '' - elif text[0] in STARTCHARS: + elif text[0] in modeparsers.STARTCHARS: return text[0] else: return '' @@ -109,7 +107,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit): # Text is only whitespace so we treat this as a single element with # the whitespace. return [text] - runner = CommandRunner() + runner = runners.CommandRunner() parts = runner.parse(text, fallback=True, alias_no_args=False) if self._empty_item_idx is not None: logger.debug("Empty element queued at {}, inserting.".format( @@ -179,8 +177,9 @@ class Command(MinimalLineEditMixin, CommandLineEdit): strings: A list of strings to set. """ text = ' '.join(strings) - if not text[0] in STARTCHARS: - raise CommandError("Invalid command text '{}'.".format(text)) + if not text[0] in modeparsers.STARTCHARS: + raise cmdexc.CommandError( + "Invalid command text '{}'.".format(text)) self.set_cmd_text(text) @pyqtSlot(str, bool) @@ -215,7 +214,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit): self.show_cmd.emit() @cmdutils.register(instance='mainwindow.status.cmd', hide=True, - modes=[KeyMode.command]) + modes=[usertypes.KeyMode.command]) def command_history_prev(self): """Go back in the commandline history.""" try: @@ -223,26 +222,27 @@ class Command(MinimalLineEditMixin, CommandLineEdit): item = self.history.start(self.text().strip()) else: item = self.history.previtem() - except (HistoryEmptyError, HistoryEndReachedError): + except (cmdhistory.HistoryEmptyError, + cmdhistory.HistoryEndReachedError): return if item: self.set_cmd_text(item) @cmdutils.register(instance='mainwindow.status.cmd', hide=True, - modes=[KeyMode.command]) + modes=[usertypes.KeyMode.command]) def command_history_next(self): """Go forward in the commandline history.""" if not self.history.browsing: return try: item = self.history.nextitem() - except HistoryEndReachedError: + except cmdhistory.HistoryEndReachedError: return if item: self.set_cmd_text(item) @cmdutils.register(instance='mainwindow.status.cmd', hide=True, - modes=[KeyMode.command]) + modes=[usertypes.KeyMode.command]) def command_accept(self): """Execute the command currently in the commandline. @@ -258,7 +258,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit): } text = self.text() self.history.append(text) - modeman.leave(KeyMode.command, 'cmd accept') + modeman.leave(usertypes.KeyMode.command, 'cmd accept') if text[0] in signals: signals[text[0]].emit(text.lstrip(text[0])) @@ -271,7 +271,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit): # here, but that's already done for us by cursorPositionChanged # anyways, so we don't need to do it twice. - @pyqtSlot(KeyMode) + @pyqtSlot(usertypes.KeyMode) def on_mode_left(self, mode): """Clear up when ommand mode was left. @@ -286,7 +286,7 @@ class Command(MinimalLineEditMixin, CommandLineEdit): clear_completion_selection: Always emitted. hide_completion: Always emitted so the completion is hidden. """ - if mode == KeyMode.command: + if mode == usertypes.KeyMode.command: self.setText('') self.history.stop() self.hide_cmd.emit() @@ -295,14 +295,14 @@ class Command(MinimalLineEditMixin, CommandLineEdit): def focusInEvent(self, e): """Extend focusInEvent to enter command mode.""" - modeman.maybe_enter(KeyMode.command, 'cmd focus') + modeman.maybe_enter(usertypes.KeyMode.command, 'cmd focus') super().focusInEvent(e) def setText(self, text): """Extend setText to set prefix and make sure the prompt is ok.""" if not text: pass - elif text[0] in STARTCHARS: + elif text[0] in modeparsers.STARTCHARS: super().set_prompt(text[0]) else: raise AssertionError("setText got called with invalid text " diff --git a/qutebrowser/widgets/statusbar/keystring.py b/qutebrowser/widgets/statusbar/keystring.py index e674cac05..41a89aa09 100644 --- a/qutebrowser/widgets/statusbar/keystring.py +++ b/qutebrowser/widgets/statusbar/keystring.py @@ -19,10 +19,10 @@ """Keychain string displayed in the statusbar.""" -from qutebrowser.widgets.statusbar.textbase import TextBase +from qutebrowser.widgets.statusbar import textbase -class KeyString(TextBase): +class KeyString(textbase.TextBase): """Keychain string displayed in the statusbar.""" diff --git a/qutebrowser/widgets/statusbar/percentage.py b/qutebrowser/widgets/statusbar/percentage.py index 9ddb621b5..1cf38c7e2 100644 --- a/qutebrowser/widgets/statusbar/percentage.py +++ b/qutebrowser/widgets/statusbar/percentage.py @@ -21,10 +21,10 @@ from PyQt5.QtCore import pyqtSlot -from qutebrowser.widgets.statusbar.textbase import TextBase +from qutebrowser.widgets.statusbar import textbase -class Percentage(TextBase): +class Percentage(textbase.TextBase): """Reading percentage displayed in the statusbar.""" diff --git a/qutebrowser/widgets/statusbar/progress.py b/qutebrowser/widgets/statusbar/progress.py index 90d7b0867..d7223f733 100644 --- a/qutebrowser/widgets/statusbar/progress.py +++ b/qutebrowser/widgets/statusbar/progress.py @@ -22,8 +22,8 @@ from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QProgressBar, QSizePolicy -from qutebrowser.widgets.webview import LoadStatus -from qutebrowser.config.style import set_register_stylesheet +from qutebrowser.widgets import webview +from qutebrowser.config import style class Progress(QProgressBar): @@ -50,7 +50,7 @@ class Progress(QProgressBar): def __init__(self, parent=None): super().__init__(parent) - set_register_stylesheet(self) + style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Ignored) self.setTextVisible(False) self.hide() @@ -72,7 +72,7 @@ class Progress(QProgressBar): # sometimes. return self.setValue(tab.progress) - if tab.load_status == LoadStatus.loading: + if tab.load_status == webview.LoadStatus.loading: self.show() else: self.hide() diff --git a/qutebrowser/widgets/statusbar/prompt.py b/qutebrowser/widgets/statusbar/prompt.py index dddb075dd..80ed8405a 100644 --- a/qutebrowser/widgets/statusbar/prompt.py +++ b/qutebrowser/widgets/statusbar/prompt.py @@ -22,18 +22,17 @@ from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import QHBoxLayout, QWidget, QLineEdit -from qutebrowser.widgets.misc import MinimalLineEditMixin -from qutebrowser.widgets.statusbar.textbase import TextBase -from qutebrowser.widgets.statusbar.prompter import Prompter +from qutebrowser.widgets import misc +from qutebrowser.widgets.statusbar import textbase, prompter -class PromptLineEdit(MinimalLineEditMixin, QLineEdit): +class PromptLineEdit(misc.MinimalLineEditMixin, QLineEdit): """QLineEdit with a minimal stylesheet.""" def __init__(self, parent=None): QLineEdit.__init__(self, parent) - MinimalLineEditMixin.__init__(self) + misc.MinimalLineEditMixin.__init__(self) class Prompt(QWidget): @@ -60,13 +59,13 @@ class Prompt(QWidget): self._hbox.setContentsMargins(0, 0, 0, 0) self._hbox.setSpacing(5) - self.txt = TextBase() + self.txt = textbase.TextBase() self._hbox.addWidget(self.txt) self.lineedit = PromptLineEdit() self._hbox.addWidget(self.lineedit) - self.prompter = Prompter(self) + self.prompter = prompter.Prompter(self) def __repr__(self): return '<{}>'.format(self.__class__.__name__) diff --git a/qutebrowser/widgets/statusbar/prompter.py b/qutebrowser/widgets/statusbar/prompter.py index ccb7398f0..15e3df727 100644 --- a/qutebrowser/widgets/statusbar/prompter.py +++ b/qutebrowser/widgets/statusbar/prompter.py @@ -19,20 +19,21 @@ """Manager for questions to be shown in the statusbar.""" -from collections import namedtuple, deque +import collections from PyQt5.QtCore import pyqtSlot, QTimer from PyQt5.QtWidgets import QLineEdit -import qutebrowser.keyinput.modeman as modeman -import qutebrowser.commands.utils as cmdutils -from qutebrowser.utils.usertypes import PromptMode, Question, KeyMode -from qutebrowser.utils.qt import EventLoop +from qutebrowser.keyinput import modeman +from qutebrowser.commands import utils as cmdutils +from qutebrowser.utils import usertypes +from qutebrowser.utils import qt as qtutils from qutebrowser.utils.log import statusbar as logger -PromptContext = namedtuple('PromptContext', ['question', 'text', 'input_text', - 'echo_mode', 'input_visible']) +PromptContext = collections.namedtuple('PromptContext', + ['question', 'text', 'input_text', + 'echo_mode', 'input_visible']) class Prompter: @@ -67,7 +68,7 @@ class Prompter: def __init__(self, prompt): self.question = None self._loops = [] - self._queue = deque() + self._queue = collections.deque() self._busy = False self._prompt = prompt @@ -124,7 +125,7 @@ class Prompter: Raise: ValueError if the set PromptMode is invalid. """ - if self.question.mode == PromptMode.yesno: + if self.question.mode == usertypes.PromptMode.yesno: if self.question.default is None: suffix = "" elif self.question.default: @@ -133,23 +134,23 @@ class Prompter: suffix = " (no)" self._prompt.txt.setText(self.question.text + suffix) self._prompt.lineedit.hide() - mode = KeyMode.yesno - elif self.question.mode == PromptMode.text: + mode = usertypes.KeyMode.yesno + elif self.question.mode == usertypes.PromptMode.text: self._prompt.txt.setText(self.question.text) if self.question.default: self._prompt.lineedit.setText(self.question.default) self._prompt.lineedit.show() - mode = KeyMode.prompt - elif self.question.mode == PromptMode.user_pwd: + mode = usertypes.KeyMode.prompt + elif self.question.mode == usertypes.PromptMode.user_pwd: self._prompt.txt.setText(self.question.text) if self.question.default: self._prompt.lineedit.setText(self.question.default) self._prompt.lineedit.show() - mode = KeyMode.prompt - elif self.question.mode == PromptMode.alert: + mode = usertypes.KeyMode.prompt + elif self.question.mode == usertypes.PromptMode.alert: self._prompt.txt.setText(self.question.text + ' (ok)') self._prompt.lineedit.hide() - mode = KeyMode.prompt + mode = usertypes.KeyMode.prompt else: raise ValueError("Invalid prompt mode!") self._prompt.lineedit.setFocus() @@ -174,10 +175,10 @@ class Prompter: else: return False - @pyqtSlot(KeyMode) + @pyqtSlot(usertypes.KeyMode) def on_mode_left(self, mode): """Clear and reset input when the mode was left.""" - if mode in (KeyMode.prompt, KeyMode.yesno): + if mode in (usertypes.KeyMode.prompt, usertypes.KeyMode.yesno): self._prompt.txt.setText('') self._prompt.lineedit.clear() self._prompt.lineedit.setEchoMode(QLineEdit.Normal) @@ -187,7 +188,8 @@ class Prompter: self.question.cancel() @cmdutils.register(instance='mainwindow.status.prompt.prompter', hide=True, - modes=[KeyMode.prompt, KeyMode.yesno]) + modes=[usertypes.KeyMode.prompt, + usertypes.KeyMode.yesno]) def prompt_accept(self): """Accept the current prompt. @@ -196,60 +198,60 @@ class Prompter: This executes the next action depending on the question mode, e.g. asks for the password or leaves the mode. """ - if (self.question.mode == PromptMode.user_pwd and + if (self.question.mode == usertypes.PromptMode.user_pwd and self.question.user is None): # User just entered an username self.question.user = self._prompt.lineedit.text() self._prompt.txt.setText("Password:") self._prompt.lineedit.clear() self._prompt.lineedit.setEchoMode(QLineEdit.Password) - elif self.question.mode == PromptMode.user_pwd: + elif self.question.mode == usertypes.PromptMode.user_pwd: # User just entered a password password = self._prompt.lineedit.text() self.question.answer = (self.question.user, password) - modeman.leave(KeyMode.prompt, 'prompt accept') + modeman.leave(usertypes.KeyMode.prompt, 'prompt accept') self.question.done() - elif self.question.mode == PromptMode.text: + elif self.question.mode == usertypes.PromptMode.text: # User just entered text. self.question.answer = self._prompt.lineedit.text() - modeman.leave(KeyMode.prompt, 'prompt accept') + modeman.leave(usertypes.KeyMode.prompt, 'prompt accept') self.question.done() - elif self.question.mode == PromptMode.yesno: + elif self.question.mode == usertypes.PromptMode.yesno: # User wants to accept the default of a yes/no question. self.question.answer = self.question.default - modeman.leave(KeyMode.yesno, 'yesno accept') + modeman.leave(usertypes.KeyMode.yesno, 'yesno accept') self.question.done() - elif self.question.mode == PromptMode.alert: + elif self.question.mode == usertypes.PromptMode.alert: # User acknowledged an alert self.question.answer = None - modeman.leave(KeyMode.prompt, 'alert accept') + modeman.leave(usertypes.KeyMode.prompt, 'alert accept') self.question.done() else: raise ValueError("Invalid question mode!") @cmdutils.register(instance='mainwindow.status.prompt.prompter', hide=True, - modes=[KeyMode.yesno]) + modes=[usertypes.KeyMode.yesno]) def prompt_yes(self): """Answer yes to a yes/no prompt.""" - if self.question.mode != PromptMode.yesno: + if self.question.mode != usertypes.PromptMode.yesno: # We just ignore this if we don't have a yes/no question. return self.question.answer = True - modeman.leave(KeyMode.yesno, 'yesno accept') + modeman.leave(usertypes.KeyMode.yesno, 'yesno accept') self.question.done() @cmdutils.register(instance='mainwindow.status.prompt.prompter', hide=True, - modes=[KeyMode.yesno]) + modes=[usertypes.KeyMode.yesno]) def prompt_no(self): """Answer no to a yes/no prompt.""" - if self.question.mode != PromptMode.yesno: + if self.question.mode != usertypes.PromptMode.yesno: # We just ignore this if we don't have a yes/no question. return self.question.answer = False - modeman.leave(KeyMode.yesno, 'prompt accept') + modeman.leave(usertypes.KeyMode.yesno, 'prompt accept') self.question.done() - @pyqtSlot(Question, bool) + @pyqtSlot(usertypes.Question, bool) def ask_question(self, question, blocking): """Dispkay a question in the statusbar. @@ -282,12 +284,12 @@ class Prompter: try: modeman.enter(mode, 'question asked') except modeman.ModeLockedError: - if modeman.instance().mode != KeyMode.prompt: + if modeman.instance().mode != usertypes.KeyMode.prompt: question.abort() return None modeman.instance().locked = True if blocking: - loop = EventLoop() + loop = qtutils.EventLoop() self._loops.append(loop) loop.destroyed.connect(lambda: self._loops.remove(loop)) question.completed.connect(loop.quit) diff --git a/qutebrowser/widgets/statusbar/text.py b/qutebrowser/widgets/statusbar/text.py index 53465104a..ec1be31a7 100644 --- a/qutebrowser/widgets/statusbar/text.py +++ b/qutebrowser/widgets/statusbar/text.py @@ -21,11 +21,11 @@ from PyQt5.QtCore import pyqtSlot -import qutebrowser.config.config as config -from qutebrowser.widgets.statusbar.textbase import TextBase +from qutebrowser.config import config +from qutebrowser.widgets.statusbar import textbase -class Text(TextBase): +class Text(textbase.TextBase): """Text displayed in the statusbar. diff --git a/qutebrowser/widgets/statusbar/textbase.py b/qutebrowser/widgets/statusbar/textbase.py index 2037b45d9..7335a522e 100644 --- a/qutebrowser/widgets/statusbar/textbase.py +++ b/qutebrowser/widgets/statusbar/textbase.py @@ -23,7 +23,7 @@ from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QLabel, QSizePolicy from PyQt5.QtGui import QPainter -from qutebrowser.utils.qt import qt_ensure_valid +from qutebrowser.utils import qt as qtutils class TextBase(QLabel): @@ -79,7 +79,7 @@ class TextBase(QLabel): """Extend QLabel::resizeEvent to update the elided text afterwards.""" super().resizeEvent(e) size = e.size() - qt_ensure_valid(size) + qtutils.qt_ensure_valid(size) self._update_elided_text(size.width()) def paintEvent(self, e): @@ -90,6 +90,6 @@ class TextBase(QLabel): e.accept() painter = QPainter(self) geom = self.geometry() - qt_ensure_valid(geom) + qtutils.qt_ensure_valid(geom) painter.drawText(0, 0, geom.width(), geom.height(), self.alignment(), self._elided_text) diff --git a/qutebrowser/widgets/statusbar/url.py b/qutebrowser/widgets/statusbar/url.py index d07dffe2f..5366eafe1 100644 --- a/qutebrowser/widgets/statusbar/url.py +++ b/qutebrowser/widgets/statusbar/url.py @@ -21,17 +21,18 @@ from PyQt5.QtCore import pyqtSlot, pyqtProperty, Qt -from qutebrowser.widgets.webview import LoadStatus -from qutebrowser.widgets.statusbar.textbase import TextBase -from qutebrowser.config.style import set_register_stylesheet, get_stylesheet -from qutebrowser.utils.usertypes import enum +from qutebrowser.widgets import webview +from qutebrowser.widgets.statusbar import textbase +from qutebrowser.config import style +from qutebrowser.utils import usertypes # Note this has entries for success/error/warn from widgets.webview:LoadStatus -UrlType = enum('UrlType', 'success', 'error', 'warn', 'hover', 'normal') +UrlType = usertypes.enum('UrlType', 'success', 'error', 'warn', 'hover', + 'normal') -class UrlText(TextBase): +class UrlText(textbase.TextBase): """URL displayed in the statusbar. @@ -80,7 +81,7 @@ class UrlText(TextBase): """Override TextBase.__init__ to elide in the middle by default.""" super().__init__(parent, Qt.ElideMiddle) self.setObjectName(self.__class__.__name__) - set_register_stylesheet(self) + style.set_register_stylesheet(self) self._hover_url = None self._normal_url = None self._normal_url_type = UrlType.normal @@ -104,7 +105,7 @@ class UrlText(TextBase): if not isinstance(val, UrlType): raise TypeError("Type {} is no UrlType member!".format(val)) self._urltype = val - self.setStyleSheet(get_stylesheet(self.STYLESHEET)) + self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) @property def hover_url(self): @@ -164,8 +165,9 @@ class UrlText(TextBase): Args: status_str: The LoadStatus as string. """ - status = LoadStatus[status_str] - if status in (LoadStatus.success, LoadStatus.error, LoadStatus.warn): + status = webview.LoadStatus[status_str] + if status in (webview.LoadStatus.success, webview.LoadStatus.error, + webview.LoadStatus.warn): self.normal_url_type = UrlType[status_str] else: self.normal_url_type = UrlType.normal diff --git a/qutebrowser/widgets/tabbedbrowser.py b/qutebrowser/widgets/tabbedbrowser.py index 718c30634..cee56405b 100644 --- a/qutebrowser/widgets/tabbedbrowser.py +++ b/qutebrowser/widgets/tabbedbrowser.py @@ -19,29 +19,25 @@ """The main tabbed browser widget.""" -from functools import partial +import functools from PyQt5.QtWidgets import QSizePolicy from PyQt5.QtCore import pyqtSignal, pyqtSlot, QSize, QTimer from PyQt5.QtGui import QIcon from PyQt5.QtWebKitWidgets import QWebPage -import qutebrowser.config.config as config -import qutebrowser.commands.utils as cmdutils -import qutebrowser.keyinput.modeman as modeman -import qutebrowser.utils.log as log -import qutebrowser.utils.misc as utils -import qutebrowser.utils.message as message -from qutebrowser.widgets.tabwidget import TabWidget -from qutebrowser.widgets.webview import WebView -from qutebrowser.browser.signalfilter import SignalFilter -from qutebrowser.browser.commands import CommandDispatcher -from qutebrowser.utils.qt import qt_ensure_valid, QtValueError -from qutebrowser.commands.exceptions import CommandError -from qutebrowser.utils.usertypes import KeyMode +from qutebrowser.config import config +from qutebrowser.commands import utils as cmdutils +from qutebrowser.commands import exceptions as cmdexc +from qutebrowser.keyinput import modeman +from qutebrowser.widgets import tabwidget, webview +from qutebrowser.browser import signalfilter, commands +from qutebrowser.utils import log, message, usertypes +from qutebrowser.utils import misc as utils +from qutebrowser.utils import qt as qtutils -class TabbedBrowser(TabWidget): +class TabbedBrowser(tabwidget.TabWidget): """A TabWidget with QWebViews inside. @@ -104,7 +100,7 @@ class TabbedBrowser(TabWidget): quit = pyqtSignal() resized = pyqtSignal('QRect') got_cmd = pyqtSignal(str) - current_tab_changed = pyqtSignal(WebView) + current_tab_changed = pyqtSignal(webview.WebView) title_changed = pyqtSignal(str) def __init__(self, parent=None): @@ -116,8 +112,8 @@ class TabbedBrowser(TabWidget): self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self._tabs = [] self.url_stack = [] - self._filter = SignalFilter(self) - self.cmd = CommandDispatcher(self) + self._filter = signalfilter.SignalFilter(self) + self.cmd = commands.CommandDispatcher(self) self.last_focused = None self._now_focused = None # FIXME adjust this to font size @@ -159,7 +155,8 @@ class TabbedBrowser(TabWidget): self._filter.create(self.cur_url_text_changed, tab)) tab.load_status_changed.connect( self._filter.create(self.cur_load_status_changed, tab)) - tab.url_text_changed.connect(partial(self.on_url_text_changed, tab)) + tab.url_text_changed.connect( + functools.partial(self.on_url_text_changed, tab)) # hintmanager tab.hintmanager.hint_strings_updated.connect(self.hint_strings_updated) tab.hintmanager.download_get.connect(self.download_get) @@ -168,13 +165,18 @@ class TabbedBrowser(TabWidget): # downloads page.start_download.connect(self.start_download) # misc - tab.titleChanged.connect(partial(self.on_title_changed, tab)) - tab.iconChanged.connect(partial(self.on_icon_changed, tab)) - tab.loadProgress.connect(partial(self.on_load_progress, tab)) - frame.loadFinished.connect(partial(self.on_load_finished, tab)) - frame.loadStarted.connect(partial(self.on_load_started, tab)) + tab.titleChanged.connect( + functools.partial(self.on_title_changed, tab)) + tab.iconChanged.connect( + functools.partial(self.on_icon_changed, tab)) + tab.loadProgress.connect( + functools.partial(self.on_load_progress, tab)) + frame.loadFinished.connect( + functools.partial(self.on_load_finished, tab)) + frame.loadStarted.connect( + functools.partial(self.on_load_started, tab)) page.windowCloseRequested.connect( - partial(self.on_window_close_requested, tab)) + functools.partial(self.on_window_close_requested, tab)) def cntwidget(self, count=None): """Return a widget based on a count/idx. @@ -208,13 +210,13 @@ class TabbedBrowser(TabWidget): """ url = self.currentWidget().cur_url try: - qt_ensure_valid(url) - except QtValueError as e: + qtutils.qt_ensure_valid(url) + except qtutils.QtValueError as e: msg = "Current URL is invalid" if e.reason: msg += " ({})".format(e.reason) msg += "!" - raise CommandError(msg) + raise cmdexc.CommandError(msg) return url def shutdown(self): @@ -264,7 +266,7 @@ class TabbedBrowser(TabWidget): if tab is self.last_focused: self.last_focused = None if not tab.cur_url.isEmpty(): - qt_ensure_valid(tab.cur_url) + qtutils.qt_ensure_valid(tab.cur_url) self.url_stack.append(tab.cur_url) tab.shutdown() self._tabs.remove(tab) @@ -279,7 +281,7 @@ class TabbedBrowser(TabWidget): url: The URL to open as QUrl. newtab: True to open URL in a new tab, False otherwise. """ - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) if newtab: self.tabopen(url, background=False) else: @@ -295,7 +297,7 @@ class TabbedBrowser(TabWidget): return self.close_tab(tab) - @pyqtSlot(WebView) + @pyqtSlot(webview.WebView) def on_window_close_requested(self, widget): """Close a tab with a widget given.""" self.close_tab(widget) @@ -322,9 +324,9 @@ class TabbedBrowser(TabWidget): The opened WebView instance. """ if url is not None: - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) log.webview.debug("Creating new tab with URL {}".format(url)) - tab = WebView(self) + tab = webview.WebView(self) self._connect_tab_signals(tab) self._tabs.append(tab) if explicit: @@ -440,10 +442,10 @@ class TabbedBrowser(TabWidget): @pyqtSlot() def on_cur_load_started(self): """Leave insert/hint mode when loading started.""" - modeman.maybe_leave(KeyMode.insert, 'load started') - modeman.maybe_leave(KeyMode.hint, 'load started') + modeman.maybe_leave(usertypes.KeyMode.insert, 'load started') + modeman.maybe_leave(usertypes.KeyMode.hint, 'load started') - @pyqtSlot(WebView, str) + @pyqtSlot(webview.WebView, str) def on_title_changed(self, tab, text): """Set the title of a tab. @@ -470,7 +472,7 @@ class TabbedBrowser(TabWidget): if idx == self.currentIndex(): self.title_changed.emit('{} - qutebrowser'.format(text)) - @pyqtSlot(WebView, str) + @pyqtSlot(webview.WebView, str) def on_url_text_changed(self, tab, url): """Set the new URL as title if there's no title yet. @@ -490,7 +492,7 @@ class TabbedBrowser(TabWidget): if not self.tabText(idx): self.setTabText(idx, url) - @pyqtSlot(WebView) + @pyqtSlot(webview.WebView) def on_icon_changed(self, tab): """Set the icon of a tab. @@ -512,10 +514,10 @@ class TabbedBrowser(TabWidget): return self.setTabIcon(idx, tab.icon()) - @pyqtSlot(KeyMode) + @pyqtSlot(usertypes.KeyMode) def on_mode_left(self, mode): """Give focus to current tab if command mode was left.""" - if mode == KeyMode.command: + if mode == usertypes.KeyMode.command: self.currentWidget().setFocus() @pyqtSlot(int) @@ -523,7 +525,7 @@ class TabbedBrowser(TabWidget): """Set last_focused and leave hinting mode when focus changed.""" tab = self.widget(idx) tab.setFocus() - modeman.maybe_leave(KeyMode.hint, 'tab changed') + modeman.maybe_leave(usertypes.KeyMode.hint, 'tab changed') self.last_focused = self._now_focused self._now_focused = tab self.current_tab_changed.emit(tab) diff --git a/qutebrowser/widgets/tabwidget.py b/qutebrowser/widgets/tabwidget.py index d19467b33..2bd85531f 100644 --- a/qutebrowser/widgets/tabwidget.py +++ b/qutebrowser/widgets/tabwidget.py @@ -32,8 +32,8 @@ from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle, QApplication) from PyQt5.QtGui import QIcon, QPalette, QColor -from qutebrowser.utils.qt import qt_ensure_valid -import qutebrowser.config.config as config +from qutebrowser.utils import qt as qtutils +from qutebrowser.config import config PM_TabBarPadding = QStyle.PM_CustomBase @@ -211,7 +211,7 @@ class TabBar(QTabBar): # If we *do* have enough space, tabs should occupy the whole window # width. size = QSize(self.width() / self.count(), height) - qt_ensure_valid(size) + qtutils.qt_ensure_valid(size) return size def paintEvent(self, _e): @@ -311,7 +311,7 @@ class TabBarStyle(QCommonStyle): elif element == QStyle.CE_TabBarTabLabel: text_rect, icon_rect = self._tab_layout(opt) if not opt.icon.isNull(): - qt_ensure_valid(icon_rect) + qtutils.qt_ensure_valid(icon_rect) icon_mode = (QIcon.Normal if opt.state & QStyle.State_Enabled else QIcon.Disabled) icon_state = (QIcon.On if opt.state & QStyle.State_Selected @@ -382,7 +382,7 @@ class TabBarStyle(QCommonStyle): padding = self.pixelMetric(PM_TabBarPadding, opt) icon_rect = QRect() text_rect = QRect(opt.rect) - qt_ensure_valid(text_rect) + qtutils.qt_ensure_valid(text_rect) indicator_width = config.get('tabs', 'indicator-width') text_rect.adjust(padding, 0, 0, 0) if indicator_width != 0: @@ -419,5 +419,5 @@ class TabBarStyle(QCommonStyle): text_rect.center().y() - tab_icon_size.height() / 2, tab_icon_size.width(), tab_icon_size.height()) icon_rect = self._style.visualRect(opt.direction, opt.rect, icon_rect) - qt_ensure_valid(icon_rect) + qtutils.qt_ensure_valid(icon_rect) return icon_rect diff --git a/qutebrowser/widgets/webview.py b/qutebrowser/widgets/webview.py index 44708d05b..b7606ac27 100644 --- a/qutebrowser/widgets/webview.py +++ b/qutebrowser/widgets/webview.py @@ -24,21 +24,17 @@ from PyQt5.QtWidgets import QApplication from PyQt5.QtWebKit import QWebSettings from PyQt5.QtWebKitWidgets import QWebView, QWebPage -import qutebrowser.config.config as config -import qutebrowser.keyinput.modeman as modeman -import qutebrowser.utils.message as message -import qutebrowser.utils.webelem as webelem -import qutebrowser.utils.log as log -from qutebrowser.utils.misc import elide -from qutebrowser.utils.qt import qt_ensure_valid -from qutebrowser.browser.webpage import BrowserPage -from qutebrowser.browser.hints import HintManager -from qutebrowser.utils.usertypes import (NeighborList, ClickTarget, KeyMode, - enum) -from qutebrowser.commands.exceptions import CommandError +from qutebrowser.config import config +from qutebrowser.keyinput import modeman +from qutebrowser.utils import message, webelem, log, usertypes +from qutebrowser.utils import misc as utils +from qutebrowser.utils import qt as qtutils +from qutebrowser.browser import webpage, hints +from qutebrowser.commands import exceptions as cmdexc -LoadStatus = enum('LoadStatus', 'none', 'success', 'error', 'warn', 'loading') +LoadStatus = usertypes.enum('LoadStatus', 'none', 'success', 'error', 'warn', + 'loading') class WebView(QWebView): @@ -93,7 +89,7 @@ class WebView(QWebView): self.statusbar_message = '' self._old_scroll_pos = (-1, -1) self._open_target = None - self.open_target = ClickTarget.normal + self.open_target = usertypes.ClickTarget.normal self._force_open_target = None self._zoom = None self._has_ssl_errors = False @@ -101,9 +97,9 @@ class WebView(QWebView): self._cur_url = None self.cur_url = QUrl() self.progress = 0 - self._page = BrowserPage(self) + self._page = webpage.BrowserPage(self) self.setPage(self._page) - self.hintmanager = HintManager(self) + self.hintmanager = hints.HintManager(self) self.hintmanager.mouse_event.connect(self.on_mouse_event) self.hintmanager.set_open_target.connect(self.set_force_open_target) self._page.linkHovered.connect(self.linkHovered) @@ -120,7 +116,7 @@ class WebView(QWebView): def __repr__(self): url = self.url().toDisplayString() - return "WebView(url='{}')".format(elide(url, 50)) + return "WebView(url='{}')".format(utils.elide(url, 50)) @property def open_target(self): @@ -130,7 +126,7 @@ class WebView(QWebView): @open_target.setter def open_target(self, val): """Setter for open_target to do type checking.""" - if not isinstance(val, ClickTarget): + if not isinstance(val, usertypes.ClickTarget): raise TypeError("Target {} is no ClickTarget member!".format(val)) self._open_target = val @@ -172,9 +168,10 @@ class WebView(QWebView): def _init_neighborlist(self): """Initialize the _zoom neighborlist.""" - self._zoom = NeighborList(config.get('ui', 'zoom-levels'), - default=config.get('ui', 'default-zoom'), - mode=NeighborList.Modes.block) + levels = config.get('ui', 'zoom-levels') + default = config.get('ui', 'default-zoom') + self._zoom = usertypes.NeighborList( + levels, default, mode=usertypes.NeighborList.Modes.block) def _mousepress_backforward(self, e): """Handle back/forward mouse button presses. @@ -186,13 +183,13 @@ class WebView(QWebView): # Back button on mice which have it. try: self.go_back() - except CommandError as ex: + except cmdexc.CommandError as ex: message.error(ex, immediately=True) elif e.button() == Qt.XButton2: # Forward button on mice which have it. try: self.go_forward() - except CommandError as ex: + except cmdexc.CommandError as ex: message.error(ex, immediately=True) def _mousepress_insertmode(self, e): @@ -233,11 +230,11 @@ class WebView(QWebView): elif ((hitresult.isContentEditable() and webelem.is_writable(elem)) or webelem.is_editable(elem)): log.mouse.debug("Clicked editable element!") - modeman.maybe_enter(KeyMode.insert, 'click') + modeman.maybe_enter(usertypes.KeyMode.insert, 'click') else: log.mouse.debug("Clicked non-editable element!") if config.get('input', 'auto-leave-insert-mode'): - modeman.maybe_leave(KeyMode.insert, 'click') + modeman.maybe_leave(usertypes.KeyMode.insert, 'click') def mouserelease_insertmode(self): """If we have an insertmode check scheduled, handle it.""" @@ -247,11 +244,11 @@ class WebView(QWebView): elem = webelem.focus_elem(self.page().currentFrame()) if webelem.is_editable(elem): log.mouse.debug("Clicked editable element (delayed)!") - modeman.maybe_enter(KeyMode.insert, 'click-delayed') + modeman.maybe_enter(usertypes.KeyMode.insert, 'click-delayed') else: log.mouse.debug("Clicked non-editable element (delayed)!") if config.get('input', 'auto-leave-insert-mode'): - modeman.maybe_leave(KeyMode.insert, 'click-delayed') + modeman.maybe_leave(usertypes.KeyMode.insert, 'click-delayed') def _mousepress_opentarget(self, e): """Set the open target when something was clicked. @@ -267,13 +264,13 @@ class WebView(QWebView): elif (e.button() == Qt.MidButton or e.modifiers() & Qt.ControlModifier): if config.get('tabs', 'background-tabs'): - self.open_target = ClickTarget.tab_bg + self.open_target = usertypes.ClickTarget.tab_bg else: - self.open_target = ClickTarget.tab + self.open_target = usertypes.ClickTarget.tab log.mouse.debug("Middle click, setting target: {}".format( self.open_target)) else: - self.open_target = ClickTarget.normal + self.open_target = usertypes.ClickTarget.normal log.mouse.debug("Normal click, setting normal target") def shutdown(self): @@ -304,7 +301,7 @@ class WebView(QWebView): Emit: titleChanged """ - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) urlstr = url.toDisplayString() log.webview.debug("New title: {}".format(urlstr)) self.titleChanged.emit(urlstr) @@ -321,7 +318,7 @@ class WebView(QWebView): if fuzzyval: self._zoom.fuzzyval = int(perc) if perc < 0: - raise CommandError("Can't zoom {}%!".format(perc)) + raise cmdexc.CommandError("Can't zoom {}%!".format(perc)) self.setZoomFactor(float(perc) / 100) message.info("Zoom level: {}%".format(perc)) @@ -349,19 +346,19 @@ class WebView(QWebView): if self.page().history().canGoBack(): self.back() else: - raise CommandError("At beginning of history.") + raise cmdexc.CommandError("At beginning of history.") def go_forward(self): """Go forward a page in the history.""" if self.page().history().canGoForward(): self.forward() else: - raise CommandError("At end of history.") + raise cmdexc.CommandError("At end of history.") @pyqtSlot('QUrl') def on_url_changed(self, url): """Update cur_url when URL has changed.""" - qt_ensure_valid(url) + qtutils.qt_ensure_valid(url) self.cur_url = url @pyqtSlot(str, str) @@ -394,7 +391,7 @@ class WebView(QWebView): self.load_status = LoadStatus.error if not config.get('input', 'auto-insert-mode'): return - if modeman.instance().mode == KeyMode.insert or not ok: + if modeman.instance().mode == usertypes.KeyMode.insert or not ok: return frame = self.page().currentFrame() elem = frame.findFirstElement(':focus') @@ -402,7 +399,7 @@ class WebView(QWebView): if elem.isNull(): log.webview.debug("Focused element is null!") elif webelem.is_editable(elem): - modeman.maybe_enter(KeyMode.insert, 'load finished') + modeman.maybe_enter(usertypes.KeyMode.insert, 'load finished') @pyqtSlot(str) def set_force_open_target(self, target): @@ -411,7 +408,7 @@ class WebView(QWebView): Args: target: A string to set self._force_open_target to. """ - t = getattr(ClickTarget, target) + t = getattr(usertypes.ClickTarget, target) log.webview.debug("Setting force target to {}/{}".format(target, t)) self._force_open_target = t diff --git a/scripts/cleanup.py b/scripts/cleanup.py index 5a257c732..2315e061e 100755 --- a/scripts/cleanup.py +++ b/scripts/cleanup.py @@ -25,7 +25,7 @@ import os.path import sys import glob import shutil -from fnmatch import fnmatch +import fnmatch recursive_lint = ('__pycache__', '*.pyc') @@ -47,11 +47,17 @@ def remove(path): os.remove(path) -for elem in lint: - for f in glob.glob(elem): - remove(f) +def main(): + """Clean up lint in the current dir.""" + for elem in lint: + for f in glob.glob(elem): + remove(f) + + for root, _dirs, _files in os.walk(os.getcwd()): + path = os.path.basename(root) + if any([fnmatch.fnmatch(path, e) for e in recursive_lint]): + remove(root) -for root, dirs, files in os.walk(os.getcwd()): - if any([fnmatch(os.path.basename(root), e) for e in recursive_lint]): - remove(root) +if __name__ == '__main__': + main() diff --git a/scripts/freeze.py b/scripts/freeze.py index 09541c465..281734fc2 100755 --- a/scripts/freeze.py +++ b/scripts/freeze.py @@ -27,12 +27,12 @@ Builds a standalone executable. import os import os.path import sys -from distutils.sysconfig import get_python_lib +import distutils -from cx_Freeze import setup, Executable +import cx_Freeze as cx sys.path.insert(0, os.getcwd()) -from scripts.setupcommon import setupdata, write_git_file +from scripts import setupcommon try: @@ -46,7 +46,8 @@ def get_egl_path(): """Get the path for PyQt5's libEGL.dll.""" if not sys.platform.startswith('win'): return None - return os.path.join(get_python_lib(), r'PyQt5\libEGL.dll') + return os.path.join(distutils.sysconfig.get_python_lib(), + r'PyQt5\libEGL.dll') build_exe_options = { 'include_files': [ @@ -69,20 +70,20 @@ bdist_msi_options = { base = 'Win32GUI' if sys.platform.startswith('win') else None -executable = Executable('qutebrowser/__main__.py', base=base, - targetName='qutebrowser.exe', - shortcutName='qutebrowser', - shortcutDir='ProgramMenuFolder') +executable = cx.Executable('qutebrowser/__main__.py', base=base, + targetName='qutebrowser.exe', + shortcutName='qutebrowser', + shortcutDir='ProgramMenuFolder') try: - write_git_file() - setup( + setupcommon.write_git_file() + cx.setup( executables=[executable], options={ 'build_exe': build_exe_options, 'bdist_msi': bdist_msi_options, }, - **setupdata + **setupcommon.setupdata ) finally: if BASEDIR is not None: diff --git a/scripts/generate_doc.py b/scripts/generate_doc.py index 9846d63dd..136f393fd 100755 --- a/scripts/generate_doc.py +++ b/scripts/generate_doc.py @@ -27,18 +27,18 @@ import html import shutil import inspect import subprocess -from collections import Counter, OrderedDict -from tempfile import mkstemp +import collections +import tempfile sys.path.insert(0, os.getcwd()) import qutebrowser # We import qutebrowser.app so all @cmdutils-register decorators are run. import qutebrowser.app -import qutebrowser.commands.utils as cmdutils -import qutebrowser.config.configdata as configdata -import qutebrowser.qutebrowser as qutequtebrowser -from qutebrowser.utils.usertypes import enum +from qutebrowser import qutebrowser as qutequtebrowser +from qutebrowser.commands import utils as cmdutils +from qutebrowser.config import configdata +from qutebrowser.utils import usertypes def _open_file(name, mode='w'): @@ -58,8 +58,9 @@ def _parse_docstring(func): # noqa A (short_desc, long_desc, arg_descs) tuple. """ # pylint: disable=too-many-branches - State = enum('State', 'short', 'desc', # pylint: disable=invalid-name - 'desc_hidden', 'arg_start', 'arg_inside', 'misc') + State = usertypes.enum('State', 'short', # pylint: disable=invalid-name + 'desc', 'desc_hidden', 'arg_start', 'arg_inside', + 'misc') doc = inspect.getdoc(func) lines = doc.splitlines() @@ -67,7 +68,7 @@ def _parse_docstring(func): # noqa short_desc = [] long_desc = [] - arg_descs = OrderedDict() + arg_descs = collections.OrderedDict() cur_arg_name = None for line in lines: @@ -385,7 +386,7 @@ def generate_settings(f): def _get_authors(): """Get a list of authors based on git commit logs.""" commits = subprocess.check_output(['git', 'log', '--format=%aN']) - cnt = Counter(commits.decode('utf-8').splitlines()) + cnt = collections.Counter(commits.decode('utf-8').splitlines()) return sorted(cnt, key=lambda k: cnt[k]) @@ -442,7 +443,7 @@ def generate_manpage_resources(f): def regenerate_authors(filename): """Re-generate the authors inside README based on the commits made.""" - oshandle, tmpname = mkstemp() + oshandle, tmpname = tempfile.mkstemp() with _open_file(filename, mode='r') as infile, \ _open_file(oshandle, mode='w') as temp: ignore = False diff --git a/scripts/pylint_checkers/config.py b/scripts/pylint_checkers/config.py index 1b0bc3c62..43538905e 100644 --- a/scripts/pylint_checkers/config.py +++ b/scripts/pylint_checkers/config.py @@ -20,18 +20,17 @@ """Custom astroid checker for config calls.""" import astroid -from pylint.interfaces import IAstroidChecker -from pylint.checkers import BaseChecker +from pylint import interfaces, checkers from pylint.checkers import utils -import qutebrowser.config.configdata as configdata +from qutebrowser.config import configdata -class ConfigChecker(BaseChecker): +class ConfigChecker(checkers.BaseChecker): """Custom astroid checker for config calls.""" - __implements__ = IAstroidChecker + __implements__ = interfaces.IAstroidChecker name = 'config' msgs = { 'E0000': ('"%s -> %s" is no valid config option.', 'bad-config-call', diff --git a/scripts/pylint_checkers/crlf.py b/scripts/pylint_checkers/crlf.py index 80f5c200f..87cc04c07 100644 --- a/scripts/pylint_checkers/crlf.py +++ b/scripts/pylint_checkers/crlf.py @@ -18,15 +18,14 @@ """Checker for CRLF in files.""" -from pylint.interfaces import IRawChecker -from pylint.checkers import BaseChecker +from pylint import interfaces, checkers -class CrlfChecker(BaseChecker): +class CrlfChecker(checkers.BaseChecker): """Check for CRLF in files.""" - __implements__ = IRawChecker + __implements__ = interfaces.IRawChecker name = 'crlf' msgs = {'W9001': ('Uses CRLFs', 'crlf', None)} diff --git a/scripts/pylint_checkers/modeline.py b/scripts/pylint_checkers/modeline.py index 960ec4465..4c9325d69 100644 --- a/scripts/pylint_checkers/modeline.py +++ b/scripts/pylint_checkers/modeline.py @@ -20,15 +20,14 @@ import os.path -from pylint.interfaces import IRawChecker -from pylint.checkers import BaseChecker +from pylint import interfaces, checkers -class ModelineChecker(BaseChecker): +class ModelineChecker(checkers.BaseChecker): """Check for vim modelines in files.""" - __implements__ = IRawChecker + __implements__ = interfaces.IRawChecker name = 'modeline' msgs = {'W9002': ('Does not have vim modeline', 'modeline-missing', None), diff --git a/scripts/pylint_checkers/openencoding.py b/scripts/pylint_checkers/openencoding.py index cf985cdad..caee996c8 100644 --- a/scripts/pylint_checkers/openencoding.py +++ b/scripts/pylint_checkers/openencoding.py @@ -20,16 +20,15 @@ """Make sure open() has an encoding set.""" import astroid -from pylint.interfaces import IAstroidChecker -from pylint.checkers import BaseChecker +from pylint import interfaces, checkers from pylint.checkers import utils -class OpenEncodingChecker(BaseChecker): +class OpenEncodingChecker(checkers.BaseChecker): """Checker to check open() has an encoding set.""" - __implements__ = IAstroidChecker + __implements__ = interfaces.IAstroidChecker name = 'open-encoding' msgs = { diff --git a/scripts/run_checks.py b/scripts/run_checks.py index af19a8479..10f05a7f7 100755 --- a/scripts/run_checks.py +++ b/scripts/run_checks.py @@ -38,13 +38,13 @@ import logging import tokenize import configparser import argparse -from collections import OrderedDict -from functools import partial -from contextlib import contextmanager +import collections +import functools +import contextlib import colorama as col import pep257 -from pkg_resources import load_entry_point, DistributionNotFound +import pkg_resources as pkg sys.path.insert(0, os.getcwd()) @@ -59,7 +59,7 @@ config = configparser.ConfigParser() config.read('.run_checks') -@contextmanager +@contextlib.contextmanager def _adjusted_pythonpath(name): """Adjust PYTHONPATH for pylint.""" if name == 'pylint': @@ -82,7 +82,7 @@ def _run_distutils(name, args): """Run a checker via its distutils entry point.""" sys.argv = [name] + args try: - ep = load_entry_point(name, 'console_scripts', name) + ep = pkg.load_entry_point(name, 'console_scripts', name) ep() except SystemExit as e: return e.code @@ -114,7 +114,7 @@ def run(name, target=None): with _adjusted_pythonpath(name): try: status = _run_distutils(name, args) - except DistributionNotFound: + except pkg.DistributionNotFound: status = _run_subprocess(name, args) print() return status @@ -244,23 +244,23 @@ def _get_args(checker): def _get_checkers(): """Get a dict of checkers we need to execute.""" # "Static" checkers - checkers = OrderedDict([ - ('global', OrderedDict([ + checkers = collections.OrderedDict([ + ('global', collections.OrderedDict([ ('unittest', check_unittest), ('git', check_git), ])), - ('setup', OrderedDict([ - ('pyroma', partial(run, 'pyroma')), - ('check-manifest', partial(run, 'check-manifest')), + ('setup', collections.OrderedDict([ + ('pyroma', functools.partial(run, 'pyroma')), + ('check-manifest', functools.partial(run, 'check-manifest')), ])), ]) # "Dynamic" checkers which exist once for each target. for target in config.get('DEFAULT', 'targets').split(','): - checkers[target] = OrderedDict([ - ('pep257', partial(check_pep257, target)), - ('flake8', partial(run, 'flake8', target)), - ('vcs', partial(check_vcs_conflict, target)), - ('pylint', partial(run, 'pylint', target)), + checkers[target] = collections.OrderedDict([ + ('pep257', functools.partial(check_pep257, target)), + ('flake8', functools.partial(run, 'flake8', target)), + ('vcs', functools.partial(check_vcs_conflict, target)), + ('pylint', functools.partial(run, 'pylint', target)), ]) return checkers @@ -279,7 +279,7 @@ def _checker_enabled(args, group, name): def main(): """Main entry point.""" col.init() - exit_status = OrderedDict() + exit_status = collections.OrderedDict() exit_status_bool = {} parser = argparse.ArgumentParser(description='Run various checkers.') parser.add_argument('-s', '--setup', help="Run additional setup checks", diff --git a/scripts/run_profile.py b/scripts/run_profile.py index 6e3dcb389..f433938a4 100755 --- a/scripts/run_profile.py +++ b/scripts/run_profile.py @@ -23,20 +23,20 @@ import sys import cProfile import os.path -from os import getcwd -from tempfile import mkdtemp -from subprocess import call -from shutil import rmtree +import os +import tempfile +import subprocess +import shutil -sys.path.insert(0, getcwd()) +sys.path.insert(0, os.getcwd()) import qutebrowser.qutebrowser # pylint: disable=unused-import -tempdir = mkdtemp() +tempdir = tempfile.mkdtemp() if '--profile-keep' in sys.argv: sys.argv.remove('--profile-keep') - profilefile = os.path.join(getcwd(), 'profile') + profilefile = os.path.join(os.getcwd(), 'profile') else: profilefile = os.path.join(tempdir, 'profile') if '--profile-noconv' in sys.argv: @@ -51,5 +51,6 @@ profiler.run('qutebrowser.qutebrowser.main()') profiler.dump_stats(profilefile) if not noconv: - call(['pyprof2calltree', '-k', '-i', profilefile, '-o', callgraphfile]) -rmtree(tempdir) + subprocess.call(['pyprof2calltree', '-k', '-i', profilefile, + '-o', callgraphfile]) +shutil.rmtree(tempdir) diff --git a/scripts/update_3rdparty.py b/scripts/update_3rdparty.py index b63a69cd9..fddcbefcb 100755 --- a/scripts/update_3rdparty.py +++ b/scripts/update_3rdparty.py @@ -20,7 +20,8 @@ """Update 3rd-party files (currently only ez_setup.py).""" -from urllib.request import urlretrieve +import urllib.request -urlretrieve('https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py', - 'scripts/ez_setup.py') +urllib.request.urlretrieve( + 'https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py', + 'scripts/ez_setup.py') diff --git a/setup.py b/setup.py index e53649326..ff6efbaff 100755 --- a/setup.py +++ b/setup.py @@ -24,11 +24,11 @@ import os import os.path -from scripts.setupcommon import setupdata, write_git_file +from scripts import setupcommon as common -from scripts.ez_setup import use_setuptools -use_setuptools() -from setuptools import setup, find_packages +from scripts import ez_setup +ez_setup.use_setuptools() +import setuptools try: @@ -38,9 +38,9 @@ except NameError: try: - write_git_file() - setup( - packages=find_packages(exclude=['qutebrowser.test']), + common.write_git_file() + setuptools.setup( + packages=setuptools.find_packages(exclude=['qutebrowser.test']), include_package_data=True, package_data={'qutebrowser': ['html/*', 'git-commit-id']}, entry_points={'gui_scripts': @@ -51,7 +51,7 @@ try: extras_require={'nice-debugging': ['colorlog', 'colorama'], 'checks': ['flake8', 'pylint', 'check-manifest', 'pyroma']}, - **setupdata + **common.setupdata ) finally: if BASEDIR is not None: