From eb3b0b960f145c3bfa346e1e836fc264c67fd79f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 31 Mar 2015 19:02:42 +0200 Subject: [PATCH 01/69] Use hunter for line tracing. --- qutebrowser/app.py | 14 +++++++++++--- qutebrowser/misc/earlyinit.py | 7 +++++++ qutebrowser/misc/utilcmds.py | 20 ++++++++++++++++++++ qutebrowser/utils/debug.py | 31 ------------------------------- 4 files changed, 38 insertions(+), 34 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index d29c12201..6595d604c 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -36,6 +36,10 @@ from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon from PyQt5.QtCore import (pyqtSlot, qInstallMessageHandler, QTimer, QUrl, QObject, Qt, QSocketNotifier) +try: + import hunter +except ImportError: + hunter = None import qutebrowser import qutebrowser.resources # pylint: disable=unused-import @@ -50,7 +54,7 @@ from qutebrowser.misc import (crashdialog, readline, ipc, earlyinit, from qutebrowser.misc import utilcmds # pylint: disable=unused-import from qutebrowser.keyinput import modeman from qutebrowser.utils import (log, version, message, utils, qtutils, urlutils, - debug, objreg, usertypes, standarddir) + objreg, usertypes, standarddir) # We import utilcmds to run the cmdutils.register decorators. @@ -924,6 +928,10 @@ class Application(QApplication): """Extend QApplication::exit to log the event.""" log.destroy.debug("Now calling QApplication::exit.") if self._args.debug_exit: - print("Now logging late shutdown.", file=sys.stderr) - debug.trace_lines(True) + if hunter is None: + print("Not logging late shutdown because hunter could not be " + "imported!", file=sys.stderr) + else: + print("Now logging late shutdown.", file=sys.stderr) + hunter.trace() super().exit(status) diff --git a/qutebrowser/misc/earlyinit.py b/qutebrowser/misc/earlyinit.py index 017686072..906f8a51b 100644 --- a/qutebrowser/misc/earlyinit.py +++ b/qutebrowser/misc/earlyinit.py @@ -20,6 +20,13 @@ At this point we can be sure we have all python 3.4 features available. """ +try: + # Importing hunter to register its atexit handler early so it gets called + # late. + import hunter # pylint: disable=import-error,unused-import +except ImportError: + hunter = None + import os import sys import faulthandler diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index ac60d1b5d..b5a8e7e03 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -24,6 +24,10 @@ import functools import types from PyQt5.QtCore import QCoreApplication +try: + import hunter +except ImportError: + hunter = None from qutebrowser.utils import log, objreg, usertypes from qutebrowser.commands import cmdutils, runners, cmdexc @@ -119,6 +123,22 @@ def debug_console(): con_widget.show() +@cmdutils.register(debug=True, maxsplit=0) +def debug_trace(expr=""): + """Trace executed code via hunter. + + Args: + expr: What to trace, passed to hunter. + """ + if hunter is None: + raise cmdexc.CommandError("You need to install 'hunter' to use this " + "command!") + try: + eval('hunter.trace({})'.format(expr)) + except Exception as e: + raise cmdexc.CommandError("{}: {}".format(e.__class__.__name__, e)) + + @cmdutils.register(hide=True) def fooled(): """Turn off april's fools.""" diff --git a/qutebrowser/utils/debug.py b/qutebrowser/utils/debug.py index 72ef4cf9e..eee310f4e 100644 --- a/qutebrowser/utils/debug.py +++ b/qutebrowser/utils/debug.py @@ -20,7 +20,6 @@ """Utilities used for debugging.""" import re -import sys import inspect import functools import datetime @@ -87,36 +86,6 @@ def log_signals(obj): connect_log_slot(obj) -def trace_lines(do_trace): - """Turn on/off printing each executed line. - - Args: - do_trace: Whether to start tracing (True) or stop it (False). - """ - def trace(frame, event, arg): - """Trace function passed to sys.settrace. - - Return: - Itself, so tracing continues. - """ - if sys is not None: - loc = '{}:{}'.format(frame.f_code.co_filename, frame.f_lineno) - if arg is not None: - arg = utils.compact_text(str(arg), 200) - else: - arg = '' - print("{:11} {:80} {}".format(event, loc, arg), file=sys.stderr) - return trace - else: - # When tracing while shutting down, it seems sys can be None - # sometimes... if that's the case, we stop tracing. - return None - if do_trace: - sys.settrace(trace) - else: - sys.settrace(None) - - def qenum_key(base, value, add_base=False, klass=None): """Convert a Qt Enum value to its key as a string. From 8ebac8d38c32bbc028661130fc1ffe746fae9cc4 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 31 Mar 2015 20:49:29 +0200 Subject: [PATCH 02/69] Various spelling fixes. --- CONTRIBUTING.asciidoc | 6 ++-- README.asciidoc | 6 ++-- doc/FAQ.asciidoc | 4 +-- doc/help/commands.asciidoc | 2 +- doc/help/settings.asciidoc | 14 ++++----- doc/quickstart.asciidoc | 6 ++-- doc/qutebrowser.1.asciidoc | 2 +- doc/userscripts.asciidoc | 6 ++-- qutebrowser/app.py | 8 ++--- qutebrowser/browser/adblock.py | 2 +- qutebrowser/browser/commands.py | 4 +-- qutebrowser/browser/downloads.py | 4 +-- qutebrowser/browser/downloadview.py | 2 +- qutebrowser/browser/hints.py | 10 +++---- qutebrowser/browser/network/networkmanager.py | 2 +- qutebrowser/browser/tabhistory.py | 2 +- qutebrowser/browser/webelem.py | 2 +- qutebrowser/browser/webpage.py | 18 +++++------ qutebrowser/browser/webview.py | 12 ++++---- qutebrowser/commands/cmdexc.py | 2 +- qutebrowser/commands/cmdutils.py | 4 +-- qutebrowser/commands/command.py | 2 +- qutebrowser/commands/runners.py | 2 +- qutebrowser/commands/userscripts.py | 4 +-- qutebrowser/completion/completer.py | 2 +- qutebrowser/config/config.py | 14 ++++----- qutebrowser/config/configdata.py | 28 ++++++++--------- qutebrowser/config/configexc.py | 4 +-- qutebrowser/config/configtypes.py | 2 +- qutebrowser/config/parsers/ini.py | 2 +- qutebrowser/config/parsers/keyconf.py | 14 ++++----- qutebrowser/config/sections.py | 2 +- qutebrowser/config/style.py | 2 +- qutebrowser/config/value.py | 2 +- qutebrowser/keyinput/basekeyparser.py | 30 +++++++++---------- qutebrowser/keyinput/modeman.py | 6 ++-- qutebrowser/keyinput/modeparsers.py | 2 +- qutebrowser/mainwindow/mainwindow.py | 4 +-- qutebrowser/mainwindow/statusbar/command.py | 2 +- qutebrowser/mainwindow/statusbar/prompter.py | 2 +- qutebrowser/mainwindow/statusbar/textbase.py | 4 +-- qutebrowser/mainwindow/statusbar/url.py | 2 +- qutebrowser/mainwindow/tabbedbrowser.py | 10 +++---- qutebrowser/mainwindow/tabwidget.py | 22 +++++++------- qutebrowser/misc/consolewidget.py | 6 ++-- qutebrowser/misc/crashdialog.py | 8 ++--- qutebrowser/misc/earlyinit.py | 10 +++---- qutebrowser/misc/miscwidgets.py | 2 +- qutebrowser/misc/savemanager.py | 13 ++++---- qutebrowser/misc/split.py | 4 +-- qutebrowser/qutebrowser.py | 2 +- .../browser/http/test_content_disposition.py | 6 ++-- qutebrowser/test/browser/test_webelem.py | 6 ++-- qutebrowser/test/config/test_configtypes.py | 2 +- .../test/keyinput/test_basekeyparser.py | 8 ++--- qutebrowser/test/log.py | 2 +- qutebrowser/test/misc/test_editor.py | 4 +-- qutebrowser/test/misc/test_split.py | 6 ++-- qutebrowser/test/utils/test_debug.py | 6 ++-- qutebrowser/test/utils/test_log.py | 2 +- qutebrowser/test/utils/test_qtutils.py | 2 +- qutebrowser/test/utils/test_standarddir.py | 6 ++-- qutebrowser/test/utils/test_utils.py | 10 +++---- .../test/utils/usertypes/test_neighborlist.py | 12 ++++---- qutebrowser/utils/jinja.py | 2 +- qutebrowser/utils/standarddir.py | 2 +- qutebrowser/utils/urlutils.py | 2 +- qutebrowser/utils/usertypes.py | 6 ++-- qutebrowser/utils/utils.py | 6 ++-- scripts/misc_checks.py | 2 +- scripts/segfault_test.py | 2 +- scripts/utils.py | 2 +- 72 files changed, 212 insertions(+), 211 deletions(-) diff --git a/CONTRIBUTING.asciidoc b/CONTRIBUTING.asciidoc index 79e6b28c7..e8d81e911 100644 --- a/CONTRIBUTING.asciidoc +++ b/CONTRIBUTING.asciidoc @@ -278,7 +278,7 @@ There are currently these object registries, also called 'scopes': `cookie-jar`, etc.) * The `tab` scope with objects which are per-tab (`hintmanager`, `webview`, etc.). Passing this scope to `objreg.get()` selects the object in the currently -focused tab by default. A tab can be explicitely selected by passing +focused tab by default. A tab can be explicitly selected by passing +tab=_tab-id_, window=_win-id_+ to it. A new object can be registered by using @@ -373,7 +373,7 @@ The types of the function arguments are inferred based on their default values, e.g. an argument `foo=True` will be converted to a flag `-f`/`--foo` in qutebrowser's commandline. -This behaviour can be overridden using Python's +This behavior can be overridden using Python's http://legacy.python.org/dev/peps/pep-3107/[function annotations]. The annotation should always be a `dict`, like this: @@ -447,7 +447,7 @@ This option controls Valgrind's detection of self-modifying code. If no checking is done, if a program executes some code, then overwrites it with new code, and executes the new code, Valgrind will continue to execute the translations it made for the old code. This will likely lead to incorrect -behaviour and/or crashes. +behavior and/or crashes. ... diff --git a/README.asciidoc b/README.asciidoc index 85ee3d5ec..e7be9b6b1 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -43,8 +43,8 @@ Documentation In addition to the topics mentioned in this README, the following documents are available: -* A http://qutebrowser.org/img/cheatsheet-big.png[keybinding cheatsheet]: + -image:http://qutebrowser.org/img/cheatsheet-small.png["qutebrowser keybinding cheatsheet",link="http://qutebrowser.org/img/cheatsheet-big.png"] +* A http://qutebrowser.org/img/cheatsheet-big.png[key binding cheatsheet]: + +image:http://qutebrowser.org/img/cheatsheet-small.png["qutebrowser key binding cheatsheet",link="http://qutebrowser.org/img/cheatsheet-big.png"] * link:doc/quickstart.asciidoc[Quick start guide] * link:doc/FAQ.asciidoc[Frequently asked questions] * link:CONTRIBUTING.asciidoc[Contributing to qutebrowser] @@ -164,7 +164,7 @@ Contributors, sorted by the number of commits in descending order: The following people have contributed graphics: * WOFall (icon) -* regines (keybinding cheatsheet) +* regines (key binding cheatsheet) Thanks / Similiar projects -------------------------- diff --git a/doc/FAQ.asciidoc b/doc/FAQ.asciidoc index cc0ab0088..ca9ca6e68 100644 --- a/doc/FAQ.asciidoc +++ b/doc/FAQ.asciidoc @@ -9,7 +9,7 @@ What is qutebrowser based on?:: + The concept of it is largely inspired by http://portix.bitbucket.org/dwb/[dwb] and http://www.vimperator.org/vimperator[Vimperator]. Many actions and -keybindings are similar to dwb. +key bindings are similar to dwb. Why another browser?:: It might be hard to believe, but I didn't find any browser which I was @@ -76,7 +76,7 @@ Is there an adblocker?:: for v0.1 if at all. How do I play Youtube videos with mpv?:: - You can easily add a keybinding to play youtube videos inside a real video + You can easily add a key binding to play youtube videos inside a real video player - optionally even with hinting for links: + ---- diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index f9e6287b9..3c45c56ff 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -503,7 +503,7 @@ Close the current/[count]th tab. ==== optional arguments * +*-l*+, +*--left*+: Force selecting the tab to the left of the current tab. * +*-r*+, +*--right*+: Force selecting the tab to the right of the current tab. -* +*-o*+, +*--opposite*+: Force selecting the tab in the oppsite direction of what's configured in 'tabs->select-on-remove'. +* +*-o*+, +*--opposite*+: Force selecting the tab in the opposite direction of what's configured in 'tabs->select-on-remove'. ==== count diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 4493f7dea..393738868 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -74,8 +74,8 @@ [options="header",width="75%",cols="25%,75%"] |============== |Setting|Description -|<>|Timeout for ambiguous keybindings. -|<>|Timeout for partially typed keybindings. +|<>|Timeout for ambiguous key bindings. +|<>|Timeout for partially typed key bindings. |<>|Whether to switch to insert mode when clicking flash and other plugins. |<>|Whether to leave insert mode if a non-editable element is clicked. |<>|Whether to automatically enter insert mode if an editable element is focused after page load. @@ -93,7 +93,7 @@ |<>|Whether to open new tabs (middleclick/ctrl+click) in background. |<>|Which tab to select when the focused tab is removed. |<>|How new tabs are positioned. -|<>|How new tabs opened explicitely are positioned. +|<>|How new tabs opened explicitly are positioned. |<>|Behaviour when the last tab is closed. |<>|Hide the tabbar if only one tab is open. |<>|Always hide the tabbar. @@ -697,13 +697,13 @@ Options related to input modes. [[input-timeout]] === timeout -Timeout for ambiguous keybindings. +Timeout for ambiguous key bindings. Default: +pass:[500]+ [[input-partial-timeout]] === partial-timeout -Timeout for partially typed keybindings. +Timeout for partially typed key bindings. Default: +pass:[1000]+ @@ -834,7 +834,7 @@ Default: +pass:[right]+ [[tabs-new-tab-position-explicit]] === new-tab-position-explicit -How new tabs opened explicitely are positioned. +How new tabs opened explicitly are positioned. Valid values: @@ -1208,7 +1208,7 @@ Whether to accept cookies. Valid values: - * +default+: Default QtWebKit behaviour. + * +default+: Default QtWebKit behavior. * +never+: Don't accept cookies at all. Default: +pass:[default]+ diff --git a/doc/quickstart.asciidoc b/doc/quickstart.asciidoc index 4c5387c7a..ac3be3a9c 100644 --- a/doc/quickstart.asciidoc +++ b/doc/quickstart.asciidoc @@ -8,9 +8,9 @@ time, use the `:help` command. What to do now -------------- -* View the http://qutebrowser.org/img/cheatsheet-big.png[keybinding cheatsheet] -to make yourself familiar with the keybindings: + -image:http://qutebrowser.org/img/cheatsheet-small.png["qutebrowser keybinding cheatsheet",link="http://qutebrowser.org/img/cheatsheet-big.png"] +* View the http://qutebrowser.org/img/cheatsheet-big.png[key binding cheatsheet] +to make yourself familiar with the key bindings: + +image:http://qutebrowser.org/img/cheatsheet-small.png["qutebrowser key binding cheatsheet",link="http://qutebrowser.org/img/cheatsheet-big.png"] * If you just cloned the repository, you'll need to run `scripts/asciidoc2html.py` to generate the documentation. * Go to the link:qute://settings[settings page] to set up qutebrowser the way you want it. diff --git a/doc/qutebrowser.1.asciidoc b/doc/qutebrowser.1.asciidoc index 8c72f91f0..68e6e1d14 100644 --- a/doc/qutebrowser.1.asciidoc +++ b/doc/qutebrowser.1.asciidoc @@ -106,7 +106,7 @@ It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl. - '~/.config/qutebrowser/qutebrowser.conf': Main config file. - '~/.config/qutebrowser/quickmarks': Saved quickmarks. -- '~/.config/qutebrowser/keys.conf': Defined keybindings. +- '~/.config/qutebrowser/keys.conf': Defined key bindings. - '~/.local/share/qutebrowser/': Various state information. - '~/.cache/qutebrowser/': Temporary data. diff --git a/doc/userscripts.asciidoc b/doc/userscripts.asciidoc index 5734e0e63..0e34f5d4d 100644 --- a/doc/userscripts.asciidoc +++ b/doc/userscripts.asciidoc @@ -3,14 +3,14 @@ Writing qutebrowser userscripts The Compiler qutebrowser is extensible by writing userscripts which can be called via the -`:spawn --userscript` command, or via a keybinding. +`:spawn --userscript` command, or via a key binding. These userscripts are similiar to the (non-javascript) dwb userscripts. They can be written in any language which can read environment variables and write to a FIFO. Note for simple things such as opening the current page with another browser or -mpv, a simple keybinding to something like `:spawn mpv {url}` should suffice. +mpv, a simple key binding to something like `:spawn mpv {url}` should suffice. Also note userscripts need to have the executable bit set (`chmod +x`) for qutebrowser to run them. @@ -21,7 +21,7 @@ Getting information The following environment variables will be set when an userscript is launched: - `QUTE_MODE`: Either `hints` (started via hints) or `command` (started via - command or keybinding). + command or key binding). - `QUTE_USER_AGENT`: The currently set user agent. - `QUTE_FIFO`: The FIFO or file to write commands to. diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 6595d604c..ffe515f4c 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -734,7 +734,7 @@ class Application(QApplication): @cmdutils.register(instance='app', maxsplit=0, debug=True) def debug_pyeval(self, s): - """Evaluate a python string and display the results as a webpage. + """Evaluate a python string and display the results as a web page. // @@ -847,8 +847,8 @@ class Application(QApplication): deferrer = True if deferrer: # If shutdown was called while we were asking a question, we're in - # a still sub-eventloop (which gets quitted now) and not in the - # main one. + # a still sub-eventloop (which gets quit now) and not in the main + # one. # This means we need to defer the real shutdown to when we're back # in the real main event loop, or we'll get a segfault. log.destroy.debug("Deferring real shutdown because question was " @@ -898,7 +898,7 @@ class Application(QApplication): qInstallMessageHandler(None) # Now we can hopefully quit without segfaults log.destroy.debug("Deferring QApplication::exit...") - # We use a singleshot timer to exit here to minimize the likelyhood of + # We use a singleshot timer to exit here to minimize the likelihood of # segfaults. QTimer.singleShot(0, functools.partial(self.exit, status)) diff --git a/qutebrowser/browser/adblock.py b/qutebrowser/browser/adblock.py index 467175ece..312e36cf5 100644 --- a/qutebrowser/browser/adblock.py +++ b/qutebrowser/browser/adblock.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Functions related to adblocking.""" +"""Functions related to ad blocking.""" import io import os.path diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index c3de9e661..7dc0a35fd 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -227,7 +227,7 @@ class CommandDispatcher: Args: left: Force selecting the tab to the left of the current tab. right: Force selecting the tab to the right of the current tab. - opposite: Force selecting the tab in the oppsite direction of + opposite: Force selecting the tab in the opposite direction of what's configured in 'tabs->select-on-remove'. Return: @@ -259,7 +259,7 @@ class CommandDispatcher: Args: left: Force selecting the tab to the left of the current tab. right: Force selecting the tab to the right of the current tab. - opposite: Force selecting the tab in the oppsite direction of + opposite: Force selecting the tab in the opposite direction of what's configured in 'tabs->select-on-remove'. count: The tab index to close, or None """ diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index ae3e2548b..2a012a5b3 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -185,7 +185,7 @@ class DownloadItem(QObject): done: Whether the download is finished. stats: A DownloadItemStats object. index: The index of the download in the view. - successful: Whether the download has completed sucessfully. + successful: Whether the download has completed successfully. error_msg: The current error message, or None autoclose: Whether to close the associated file if the download is done. @@ -204,7 +204,7 @@ class DownloadItem(QObject): data_changed: The downloads metadata changed. finished: The download was finished. cancelled: The download was cancelled. - error: An error with the download occured. + error: An error with the download occurred. arg: The error message as string. redirected: Signal emitted when a download was redirected. arg 0: The new QNetworkRequest. diff --git a/qutebrowser/browser/downloadview.py b/qutebrowser/browser/downloadview.py index ef016e799..0e21d1fb4 100644 --- a/qutebrowser/browser/downloadview.py +++ b/qutebrowser/browser/downloadview.py @@ -123,7 +123,7 @@ class DownloadView(QListView): Return: A list of either: - (QAction, callable) tuples. - - (None, None) for a seperator + - (None, None) for a separator """ actions = [] if item is None: diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 846f89f7f..debe5658b 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -62,7 +62,7 @@ class HintContext: frames: The QWebFrames to use. destroyed_frames: id()'s of QWebFrames which have been destroyed. (Workaround for https://github.com/The-Compiler/qutebrowser/issues/152) - elems: A mapping from keystrings to (elem, label) namedtuples. + elems: A mapping from key strings to (elem, label) namedtuples. baseurl: The URL of the current page. target: What to do with the opened links. normal/tab/tab_bg/window: Get passed to BrowserTab. @@ -77,7 +77,7 @@ class HintContext: args: Custom arguments for userscript/spawn rapid: Whether to do rapid hinting. mainframe: The main QWebFrame where we started hinting in. - group: The group of webelements to hint. + group: The group of web elements to hint. """ def __init__(self): @@ -455,7 +455,7 @@ class HintManager(QObject): """Yank an element to the clipboard or primary selection. Args: - url: The URL to open as a QURL. + url: The URL to open as a QUrl. context: The HintContext to use. """ sel = context.target == Target.yank_primary @@ -816,7 +816,7 @@ class HintManager(QObject): '{}{}'.format( match_color, matched, rest)) if self._is_hidden(elems.label): - # hidden element which matches again -> unhide it + # hidden element which matches again -> show it self._show_elem(elems.label) else: # element doesn't match anymore -> hide it @@ -835,7 +835,7 @@ class HintManager(QObject): if (filterstr is None or str(elems.elem).lower().startswith(filterstr)): if self._is_hidden(elems.label): - # hidden element which matches again -> unhide it + # hidden element which matches again -> show it self._show_elem(elems.label) else: # element doesn't match anymore -> hide it diff --git a/qutebrowser/browser/network/networkmanager.py b/qutebrowser/browser/network/networkmanager.py index af857a5ac..1ee04f034 100644 --- a/qutebrowser/browser/network/networkmanager.py +++ b/qutebrowser/browser/network/networkmanager.py @@ -176,7 +176,7 @@ class NetworkManager(QNetworkAccessManager): if answer is not None: # Since the answer could be something else than (user, password) # pylint seems to think we're unpacking a non-sequence. However we - # *did* explicitely ask for a tuple, so it *will* always be one. + # *did* explicitly ask for a tuple, so it *will* always be one. user, password = answer authenticator.setUser(user) authenticator.setPassword(password) diff --git a/qutebrowser/browser/tabhistory.py b/qutebrowser/browser/tabhistory.py index 3263f7a1e..937684a0e 100644 --- a/qutebrowser/browser/tabhistory.py +++ b/qutebrowser/browser/tabhistory.py @@ -133,7 +133,7 @@ def serialize(items): Return: A (stream, data, user_data) tuple. - stream: The resetted QDataStream. + stream: The reseted QDataStream. data: The QByteArray with the raw data. user_data: A list with each item's user data. diff --git a/qutebrowser/browser/webelem.py b/qutebrowser/browser/webelem.py index fdf4ca196..59fea9897 100644 --- a/qutebrowser/browser/webelem.py +++ b/qutebrowser/browser/webelem.py @@ -332,7 +332,7 @@ def get_child_frames(startframe): def focus_elem(frame): - """Get the focused element in a webframe. + """Get the focused element in a web frame. FIXME: Add tests. diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index 70339ee31..72b3c3629 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -41,7 +41,7 @@ class BrowserPage(QWebPage): """Our own QWebPage with advanced features. Attributes: - error_occured: Whether an error occured while loading. + error_occurred: Whether an error occurred while loading. open_target: Where to open the next navigation request. ("normal", "tab", "tab_bg") _hint_target: Override for open_target while hinting, or None. @@ -69,7 +69,7 @@ class BrowserPage(QWebPage): QWebPage.ChooseMultipleFilesExtension: self._handle_multiple_files, } self._ignore_load_started = False - self.error_occured = False + self.error_occurred = False self.open_target = usertypes.ClickTarget.normal self._hint_target = None self._networkmanager = networkmanager.NetworkManager( @@ -147,7 +147,7 @@ class BrowserPage(QWebPage): else: error_str = info.errorString if error_str == networkmanager.HOSTBLOCK_ERROR_STRING: - # We don't set error_occured in this case. + # We don't set error_occurred in this case. error_str = "Request blocked by host blocker." main_frame = info.frame.page().mainFrame() if info.frame != main_frame: @@ -160,7 +160,7 @@ class BrowserPage(QWebPage): return False else: self._ignore_load_started = True - self.error_occured = True + self.error_occurred = True log.webview.error("Error while loading {}: {}".format( urlstr, error_str)) log.webview.debug("Error domain: {}, error code: {}".format( @@ -248,7 +248,7 @@ class BrowserPage(QWebPage): frame.setScrollPosition, cur_data['scroll-pos'])) def display_content(self, reply, mimetype): - """Display a QNetworkReply with an explicitely set mimetype.""" + """Display a QNetworkReply with an explicitly set mimetype.""" self.mainFrame().setContent(reply.readAll(), mimetype, reply.url()) reply.deleteLater() @@ -312,11 +312,11 @@ class BrowserPage(QWebPage): @pyqtSlot() def on_load_started(self): - """Reset error_occured when loading of a new page started.""" + """Reset error_occurred when loading of a new page started.""" if self._ignore_load_started: self._ignore_load_started = False else: - self.error_occured = False + self.error_occurred = False @pyqtSlot('QWebFrame', 'QWebPage::Feature') def on_feature_permission_requested(self, frame, feature): @@ -393,8 +393,8 @@ class BrowserPage(QWebPage): # With Qt 5.2.1 (Ubuntu Trusty) we get this when closing a tab: # RuntimeError: wrapped C/C++ object of type BrowserPage has # been deleted - # Since the information here isn't that important for closing - # webviews anyways, we ignore this error. + # Since the information here isn't that important for closing web + # views anyways, we ignore this error. return data = { 'zoom': frame.zoomFactor(), diff --git a/qutebrowser/browser/webview.py b/qutebrowser/browser/webview.py index 39985953e..ee88e4089 100644 --- a/qutebrowser/browser/webview.py +++ b/qutebrowser/browser/webview.py @@ -52,7 +52,7 @@ class WebView(QWebView): hintmanager: The HintManager instance for this view. progress: loading progress of this page. scroll_pos: The current scroll position as (x%, y%) tuple. - statusbar_message: The current javscript statusbar message. + statusbar_message: The current javascript statusbar message. inspector: The QWebInspector used for this webview. load_status: loading status of this page (index into LoadStatus) viewing_source: Whether the webview is currently displaying source @@ -63,7 +63,7 @@ class WebView(QWebView): tab_id: The tab ID of the view. win_id: The window ID of the view. _cur_url: The current URL (accessed via cur_url property). - _has_ssl_errors: Whether SSL errors occured during loading. + _has_ssl_errors: Whether SSL errors occurred during loading. _zoom: A NeighborList with the zoom levels. _old_scroll_pos: The old scroll position. _check_insertmode: If True, in mouseReleaseEvent we should check if we @@ -234,7 +234,7 @@ class WebView(QWebView): # me, but it works this way. hitresult = frame.hitTestContent(pos) if hitresult.isNull(): - # For some reason, the whole hitresult can be null sometimes (e.g. + # For some reason, the whole hit result can be null sometimes (e.g. # on doodle menu links). If this is the case, we schedule a check # later (in mouseReleaseEvent) which uses webelem.focus_elem. log.mouse.debug("Hitresult is null!") @@ -243,7 +243,7 @@ class WebView(QWebView): try: elem = webelem.WebElementWrapper(hitresult.element()) except webelem.IsNullError: - # For some reason, the hitresult element can be a null element + # For some reason, the hit result element can be a null element # sometimes (e.g. when clicking the timetable fields on # http://www.sbb.ch/ ). If this is the case, we schedule a check # later (in mouseReleaseEvent) which uses webelem.focus_elem. @@ -372,7 +372,7 @@ class WebView(QWebView): @pyqtSlot('QMouseEvent') def on_mouse_event(self, evt): - """Post a new mouseevent from a hintmanager.""" + """Post a new mouse event from a hintmanager.""" log.modes.debug("Hint triggered, focusing {!r}".format(self)) self.setFocus() QApplication.postEvent(self, evt) @@ -393,7 +393,7 @@ class WebView(QWebView): true when the QWebPage has an ErrorPageExtension implemented. See https://github.com/The-Compiler/qutebrowser/issues/84 """ - ok = not self.page().error_occured + ok = not self.page().error_occurred if ok and not self._has_ssl_errors: self._set_load_status(LoadStatus.success) elif ok: diff --git a/qutebrowser/commands/cmdexc.py b/qutebrowser/commands/cmdexc.py index dcc0e8ffa..ccc88ba1b 100644 --- a/qutebrowser/commands/cmdexc.py +++ b/qutebrowser/commands/cmdexc.py @@ -32,7 +32,7 @@ class CommandError(Exception): class CommandMetaError(Exception): - """Common base class for exceptions occuring before a command is run.""" + """Common base class for exceptions occurring before a command is run.""" class NoSuchCommandError(CommandMetaError): diff --git a/qutebrowser/commands/cmdutils.py b/qutebrowser/commands/cmdutils.py index a9c51434b..5a5b5db0c 100644 --- a/qutebrowser/commands/cmdutils.py +++ b/qutebrowser/commands/cmdutils.py @@ -101,7 +101,7 @@ class register: # pylint: disable=invalid-name _instance: The object from the object registry to be used as "self". _scope: The scope to get _instance for. _name: The name (as string) or names (as list) of the command. - _maxsplit: The maxium amounts of splits to do for the commandline, or + _maxsplit: The maximum amounts of splits to do for the commandline, or None. _hide: Whether to hide the command or not. _completion: Which completion to use for arguments, as a list of @@ -151,7 +151,7 @@ class register: # pylint: disable=invalid-name def _get_names(self, func): """Get the name(s) which should be used for the current command. - If the name hasn't been overridden explicitely, the function name is + If the name hasn't been overridden explicitly, the function name is transformed. If it has been set, it can either be a string which is diff --git a/qutebrowser/commands/command.py b/qutebrowser/commands/command.py index 498eed62d..1781f25a5 100644 --- a/qutebrowser/commands/command.py +++ b/qutebrowser/commands/command.py @@ -160,7 +160,7 @@ class Command: return type_conv def _get_nameconv(self, param, annotation_info): - """Get a dict with a name conversion for the paraeter. + """Get a dict with a name conversion for the parameter. Args: param: The inspect.Parameter to handle. diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 5543f1455..e8f6917e4 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -55,7 +55,7 @@ def replace_variables(win_id, arglist): class SearchRunner(QObject): - """Run searches on webpages. + """Run searches on web pages. Attributes: _text: The text from the last search. diff --git a/qutebrowser/commands/userscripts.py b/qutebrowser/commands/userscripts.py index c60a32868..5612263af 100644 --- a/qutebrowser/commands/userscripts.py +++ b/qutebrowser/commands/userscripts.py @@ -52,7 +52,7 @@ class _QtFIFOReader(QObject): @pyqtSlot() def read_line(self): - """(Try to) read a line from the fifo.""" + """(Try to) read a line from the FIFO.""" log.procs.debug("QSocketNotifier triggered!") self._notifier.setEnabled(False) for line in self.fifo: @@ -60,7 +60,7 @@ class _QtFIFOReader(QObject): self._notifier.setEnabled(True) def cleanup(self): - """Clean up so the fifo can be closed.""" + """Clean up so the FIFO can be closed.""" self._notifier.setEnabled(False) diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py index 69923192b..368026aba 100644 --- a/qutebrowser/completion/completer.py +++ b/qutebrowser/completion/completer.py @@ -245,7 +245,7 @@ class Completer(QObject): if self._cmd.prefix() != ':': # This is a search or gibberish, so we don't need to complete # anything (yet) - # FIXME complete searchs + # FIXME complete searches # https://github.com/The-Compiler/qutebrowser/issues/32 completion.hide() return diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 3fb0aefd3..621eba4a8 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -20,8 +20,8 @@ """Configuration storage and config-related utilities. This borrows a lot of ideas from configparser, but also has some things that -are fundamentally different. This is why nothing inherts from configparser, but -we borrow some methods and classes from there where it makes sense. +are fundamentally different. This is why nothing inherits from configparser, +but we borrow some methods and classes from there where it makes sense. """ import os @@ -144,7 +144,7 @@ def _init_main_config(): for sect in config_obj.sections.values(): for opt in sect.values.values(): if opt.values['conf'] is None: - # Option added to builtin defaults but not in user's + # Option added to built-in defaults but not in user's # config yet save_manager.save('config', explicit=True, force=True) return @@ -262,8 +262,8 @@ class ConfigManager(QObject): ('completion', 'history-length'): 'cmd-history-max-items', } DELETED_OPTIONS = [ - ('colors', 'tab.seperator'), - ('colors', 'tabs.seperator'), + ('colors', 'tab.separator'), + ('colors', 'tabs.separator'), ('colors', 'completion.item.bg'), ] @@ -476,7 +476,7 @@ class ConfigManager(QObject): def items(self, sectname, raw=True): """Get a list of (optname, value) tuples for a section. - Implemented for configparser interpolation compatbility. + Implemented for configparser interpolation compatibility Args: sectname: The name of the section to get. @@ -539,7 +539,7 @@ class ConfigManager(QObject): The value of the option. """ if not self._initialized: - raise Exception("get got called before initialisation was " + raise Exception("get got called before initialization was " "complete!") try: sect = self.sections[sectname] diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 5cc1f5bd3..7a561bf93 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -56,7 +56,7 @@ FIRST_COMMENT = r""" # described below. # # This is the default config, so if you want to remove anything from -# here (as opposed to change/add), for example a keybinding, set it to +# here (as opposed to change/add), for example a key binding, set it to # an empty value. # # You will need to escape the following values: @@ -270,7 +270,7 @@ DATA = collections.OrderedDict([ "are defined:\n\n" "* `{perc}`: The percentage as a string like `[10%]`.\n" "* `{perc_raw}`: The raw percentage, e.g. `10`\n" - "* `{title}`: The title of the current webpage\n" + "* `{title}`: The title of the current web page\n" "* `{title_sep}`: The string ` - ` if a title is set, empty " "otherwise.\n" "* `{id}`: The internal window ID of this window."), @@ -350,11 +350,11 @@ DATA = collections.OrderedDict([ ('input', sect.KeyValue( ('timeout', SettingValue(typ.Int(minval=0, maxval=MAXVALS['int']), '500'), - "Timeout for ambiguous keybindings."), + "Timeout for ambiguous key bindings."), ('partial-timeout', SettingValue(typ.Int(minval=0, maxval=MAXVALS['int']), '1000'), - "Timeout for partially typed keybindings."), + "Timeout for partially typed key bindings."), ('insert-mode-on-plugins', SettingValue(typ.Bool(), 'false'), @@ -414,7 +414,7 @@ DATA = collections.OrderedDict([ ('new-tab-position-explicit', SettingValue(typ.NewTabPosition(), 'last'), - "How new tabs opened explicitely are positioned."), + "How new tabs opened explicitly are positioned."), ('last-close', SettingValue(typ.LastClose(), 'ignore'), @@ -422,11 +422,11 @@ DATA = collections.OrderedDict([ ('hide-auto', SettingValue(typ.Bool(), 'false'), - "Hide the tabbar if only one tab is open."), + "Hide the tab bar if only one tab is open."), ('hide-always', SettingValue(typ.Bool(), 'false'), - "Always hide the tabbar."), + "Always hide the tab bar."), ('wrap', SettingValue(typ.Bool(), 'true'), @@ -473,7 +473,7 @@ DATA = collections.OrderedDict([ "are defined:\n\n" "* `{perc}`: The percentage as a string like `[10%]`.\n" "* `{perc_raw}`: The raw percentage, e.g. `10`\n" - "* `{title}`: The title of the current webpage\n" + "* `{title}`: The title of the current web page\n" "* `{title_sep}`: The string ` - ` if a title is set, empty " "otherwise.\n" "* `{index}`: The index of this tab.\n" @@ -810,7 +810,7 @@ DATA = collections.OrderedDict([ ('tabs.bg.bar', SettingValue(typ.QtColor(), '#555555'), - "Background color of the tabbar."), + "Background color of the tab bar."), ('tabs.indicator.start', SettingValue(typ.QtColor(), '#0000aa'), @@ -881,7 +881,7 @@ DATA = collections.OrderedDict([ ('tabbar', SettingValue(typ.QtFont(), DEFAULT_FONT_SIZE + ' ${_monospace}'), - "Font used in the tabbar."), + "Font used in the tab bar."), ('statusbar', SettingValue(typ.Font(), DEFAULT_FONT_SIZE + ' ${_monospace}'), @@ -949,7 +949,7 @@ DATA = collections.OrderedDict([ KEY_FIRST_COMMENT = """ # vim: ft=conf # -# In this config file, qutebrowser's keybindings are configured. +# In this config file, qutebrowser's key bindings are configured. # The format looks like this: # # [keymode] @@ -962,8 +962,8 @@ KEY_FIRST_COMMENT = """ # All blank lines and lines starting with '#' are ignored. # Inline-comments are not permitted. # -# keymode is a comma separated list of modes in which the keybinding should be -# active. If keymode starts with !, the keybinding is active in all modes +# keymode is a comma separated list of modes in which the key binding should be +# active. If keymode starts with !, the key binding is active in all modes # except the listed modes. # # For special keys (can't be part of a keychain), enclose them in `<`...`>`. @@ -975,7 +975,7 @@ KEY_FIRST_COMMENT = """ # * Shift: `Shift` # # For simple keys (no `<>`-signs), a capital letter means the key is pressed -# with Shift. For special keys (with `<>`-signs), you need to explicitely add +# with Shift. For special keys (with `<>`-signs), you need to explicitly add # `Shift-` to match a key pressed with shift. You can bind multiple commands # by separating them with `;;`. """ diff --git a/qutebrowser/config/configexc.py b/qutebrowser/config/configexc.py index 6b577f39c..279ae949c 100644 --- a/qutebrowser/config/configexc.py +++ b/qutebrowser/config/configexc.py @@ -32,9 +32,9 @@ class ValidationError(Error): """Raised when a value for a config type was invalid. Attributes: - section: Section in which the error occured (added when catching and + section: Section in which the error occurred (added when catching and re-raising the exception). - option: Option in which the error occured. + option: Option in which the error occurred. """ def __init__(self, value, msg): diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 19b3854b0..e9aee8d2a 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1328,7 +1328,7 @@ class AcceptCookies(BaseType): """Whether to accept a cookie.""" - valid_values = ValidValues(('default', "Default QtWebKit behaviour."), + valid_values = ValidValues(('default', "Default QtWebKit behavior."), ('never', "Don't accept cookies at all.")) diff --git a/qutebrowser/config/parsers/ini.py b/qutebrowser/config/parsers/ini.py index 004e5965e..e8d24d249 100644 --- a/qutebrowser/config/parsers/ini.py +++ b/qutebrowser/config/parsers/ini.py @@ -60,7 +60,7 @@ class ReadConfigParser(configparser.ConfigParser): class ReadWriteConfigParser(ReadConfigParser): - """ConfigParser subclass used for auxillary config files.""" + """ConfigParser subclass used for auxiliary config files.""" def save(self): """Save the config file.""" diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index f27a0b721..2a792fb89 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -34,7 +34,7 @@ class KeyConfigError(Exception): """Raised on errors with the key config. Attributes: - lineno: The config line in which the exception occured. + lineno: The config line in which the exception occurred. """ def __init__(self, msg=None): @@ -73,7 +73,7 @@ class KeyConfigParser(QObject): super().__init__(parent) self._cur_section = None self._cur_command = None - # Mapping of section name(s) to keybinding -> command dicts. + # Mapping of section name(s) to key binding -> command dicts. self.keybindings = collections.OrderedDict() if configdir is None: self._configfile = None @@ -208,7 +208,7 @@ class KeyConfigParser(QObject): return sections def _load_default(self): - """Load the built-in default keybindings.""" + """Load the built-in default key bindings.""" for sectname, sect in configdata.KEY_DATA.items(): sectname = self._normalize_sectname(sectname) if not sect: @@ -242,7 +242,7 @@ class KeyConfigParser(QObject): e.lineno = i raise except OSError: - log.keyboard.exception("Failed to read keybindings!") + log.keyboard.exception("Failed to read key bindings!") for sectname in self.keybindings: self.changed.emit(sectname) @@ -258,9 +258,9 @@ class KeyConfigParser(QObject): self._cur_command = line def _read_keybinding(self, line): - """Read a keybinding from a line.""" + """Read a key binding from a line.""" if self._cur_command is None: - raise KeyConfigError("Got keybinding '{}' without getting a " + raise KeyConfigError("Got key binding '{}' without getting a " "command!".format(line)) else: assert self._cur_section is not None @@ -280,7 +280,7 @@ class KeyConfigParser(QObject): self.keybindings[sectname][keychain] = command def get_bindings_for(self, section): - """Get a dict with all merged keybindings for a section.""" + """Get a dict with all merged key bindings for a section.""" bindings = {} for sectstring, d in self.keybindings.items(): if sectstring.startswith('!'): diff --git a/qutebrowser/config/sections.py b/qutebrowser/config/sections.py index cf7a8dc93..7197802fd 100644 --- a/qutebrowser/config/sections.py +++ b/qutebrowser/config/sections.py @@ -133,7 +133,7 @@ class ValueList(Section): """This class represents a section with a list key-value settings. These are settings inside sections which don't have fixed keys, but instead - have a dynamic list of "key = value" pairs, like keybindings or + have a dynamic list of "key = value" pairs, like key bindings or searchengines. They basically consist of two different SettingValues. diff --git a/qutebrowser/config/style.py b/qutebrowser/config/style.py index da999ff14..e2754789c 100644 --- a/qutebrowser/config/style.py +++ b/qutebrowser/config/style.py @@ -94,7 +94,7 @@ class ColorDict(dict): log.style.exception("No color defined for {}!") return '' if isinstance(val, QColor): - # This could happen when accidentaly declarding something as + # This could happen when accidentally declaring something as # QtColor instead of Color in the config, and it'd go unnoticed as # the CSS is invalid then. raise TypeError("QColor passed to ColorDict!") diff --git a/qutebrowser/config/value.py b/qutebrowser/config/value.py index da4e45b09..6e0dcf619 100644 --- a/qutebrowser/config/value.py +++ b/qutebrowser/config/value.py @@ -26,7 +26,7 @@ class SettingValue: """Base class for setting values. - Intended to be subclassed by config value "types". + Intended to be sub-classed by config value "types". Attributes: typ: A BaseType subclass instance. diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py index 7d6a2b22b..c5e70f414 100644 --- a/qutebrowser/keyinput/basekeyparser.py +++ b/qutebrowser/keyinput/basekeyparser.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Base class for vim-like keysequence parser.""" +"""Base class for vim-like key sequence parser.""" import re import functools @@ -44,20 +44,20 @@ class BaseKeyParser(QObject): ambiguous: There are both a partial and a definitive match. none: No more matches possible. - Types: type of a keybinding. - chain: execute() was called via a chain-like keybinding - special: execute() was called via a special keybinding + Types: type of a key binding. + chain: execute() was called via a chain-like key binding + special: execute() was called via a special key binding do_log: Whether to log keypresses or not. Attributes: - bindings: Bound keybindings + bindings: Bound key bindings special_bindings: Bound special bindings (). _win_id: The window ID this keyparser is associated with. _warn_on_keychains: Whether a warning should be logged when binding keychains in a section which does not support them. _keystring: The currently entered key sequence - _ambigious_timer: Timer for delayed execution with ambigious bindings. + _ambiguous_timer: Timer for delayed execution with ambiguous bindings. _modename: The name of the input mode associated with this keyparser. _supports_count: Whether count is supported _supports_chains: Whether keychains are supported @@ -78,8 +78,8 @@ class BaseKeyParser(QObject): supports_chains=False): super().__init__(parent) self._win_id = win_id - self._ambigious_timer = usertypes.Timer(self, 'ambigious-match') - self._ambigious_timer.setSingleShot(True) + self._ambiguous_timer = usertypes.Timer(self, 'ambiguous-match') + self._ambiguous_timer.setSingleShot(True) self._modename = None self._keystring = '' if supports_count is None: @@ -248,11 +248,11 @@ class BaseKeyParser(QObject): def _stop_timers(self): """Stop a delayed execution if any is running.""" - if self._ambigious_timer.isActive() and self.do_log: + if self._ambiguous_timer.isActive() and self.do_log: log.keyboard.debug("Stopping delayed execution.") - self._ambigious_timer.stop() + self._ambiguous_timer.stop() try: - self._ambigious_timer.timeout.disconnect() + self._ambiguous_timer.timeout.disconnect() except TypeError: # no connections pass @@ -274,10 +274,10 @@ class BaseKeyParser(QObject): # execute in `time' ms self._debug_log("Scheduling execution of {} in {}ms".format( binding, time)) - self._ambigious_timer.setInterval(time) - self._ambigious_timer.timeout.connect( + self._ambiguous_timer.setInterval(time) + self._ambiguous_timer.timeout.connect( functools.partial(self.delayed_exec, binding, count)) - self._ambigious_timer.start() + self._ambiguous_timer.start() def delayed_exec(self, command, count): """Execute a delayed command. @@ -350,7 +350,7 @@ class BaseKeyParser(QObject): @pyqtSlot(str) def on_keyconfig_changed(self, mode): - """Re-read the config if a keybinding was changed.""" + """Re-read the config if a key binding was changed.""" if self._modename is None: raise AttributeError("on_keyconfig_changed called but no section " "defined!") diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py index e43b47e7b..0d7fdd088 100644 --- a/qutebrowser/keyinput/modeman.py +++ b/qutebrowser/keyinput/modeman.py @@ -95,7 +95,7 @@ def maybe_leave(win_id, mode, reason=None): class EventFilter(QObject): - """Event filter which passes the event to the corrent ModeManager.""" + """Event filter which passes the event to the current ModeManager.""" def __init__(self, parent=None): super().__init__(parent) @@ -229,7 +229,7 @@ class ModeManager(QObject): """ # handle like matching KeyPress if event in self._releaseevents_to_pass: - # remove all occurences + # remove all occurrences self._releaseevents_to_pass = [ e for e in self._releaseevents_to_pass if e != event] filter_this = False @@ -245,7 +245,7 @@ class ModeManager(QObject): Args: mode: The name of the mode. handler: Handler for keyPressEvents. - passthrough: Whether to pass keybindings in this mode through to + passthrough: Whether to pass key bindings in this mode through to the widgets. """ if not isinstance(mode, usertypes.KeyMode): diff --git a/qutebrowser/keyinput/modeparsers.py b/qutebrowser/keyinput/modeparsers.py index 802d17681..7ca4eabc7 100644 --- a/qutebrowser/keyinput/modeparsers.py +++ b/qutebrowser/keyinput/modeparsers.py @@ -37,7 +37,7 @@ LastPress = usertypes.enum('LastPress', ['none', 'filtertext', 'keystring']) class NormalKeyParser(keyparser.CommandKeyParser): - """KeyParser for normalmode with added STARTCHARS detection and more. + """KeyParser for normal mode with added STARTCHARS detection and more. Attributes: _partial_timer: Timer to clear partial keypresses. diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py index 88b282b73..3c646e5cf 100644 --- a/qutebrowser/mainwindow/mainwindow.py +++ b/qutebrowser/mainwindow/mainwindow.py @@ -43,7 +43,7 @@ class MainWindow(QWidget): """The main window of qutebrowser. - Adds all needed components to a vbox, initializes subwidgets and connects + Adds all needed components to a vbox, initializes sub-widgets and connects signals. Attributes: @@ -84,7 +84,7 @@ class MainWindow(QWidget): self._load_state_geometry() else: self._set_default_geometry() - log.init.debug("Initial mainwindow geometry: {}".format( + log.init.debug("Initial main window geometry: {}".format( self.geometry())) self._vbox = QVBoxLayout(self) self._vbox.setContentsMargins(0, 0, 0, 0) diff --git a/qutebrowser/mainwindow/statusbar/command.py b/qutebrowser/mainwindow/statusbar/command.py index 53e9b1fed..d5d8e1196 100644 --- a/qutebrowser/mainwindow/statusbar/command.py +++ b/qutebrowser/mainwindow/statusbar/command.py @@ -179,7 +179,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit): def on_mode_left(self, mode): """Clear up when command mode was left. - - Clear the statusbar text if it's explicitely unfocused. + - Clear the statusbar text if it's explicitly unfocused. - Clear completion selection - Hide completion diff --git a/qutebrowser/mainwindow/statusbar/prompter.py b/qutebrowser/mainwindow/statusbar/prompter.py index 84d9a5a8b..fe5907f88 100644 --- a/qutebrowser/mainwindow/statusbar/prompter.py +++ b/qutebrowser/mainwindow/statusbar/prompter.py @@ -187,7 +187,7 @@ class Prompter(QObject): def shutdown(self): """Cancel all blocking questions. - Quits and removes all running eventloops. + Quits and removes all running event loops. Return: True if loops needed to be aborted, diff --git a/qutebrowser/mainwindow/statusbar/textbase.py b/qutebrowser/mainwindow/statusbar/textbase.py index fe4529a70..1006effe7 100644 --- a/qutebrowser/mainwindow/statusbar/textbase.py +++ b/qutebrowser/mainwindow/statusbar/textbase.py @@ -32,7 +32,7 @@ class TextBase(QLabel): Unlike QLabel, the text will get elided. - Eliding is loosly based on + Eliding is loosely based on http://gedgedev.blogspot.ch/2010/12/elided-labels-in-qt.html Attributes: @@ -64,7 +64,7 @@ class TextBase(QLabel): This update the elided text after setting the text, and also works around a weird QLabel redrawing bug where it doesn't redraw correctly - when the text is empty -- we explicitely need to call repaint() to + when the text is empty -- we explicitly need to call repaint() to resolve this. More info: diff --git a/qutebrowser/mainwindow/statusbar/url.py b/qutebrowser/mainwindow/statusbar/url.py index db2e3c8f1..d18816b00 100644 --- a/qutebrowser/mainwindow/statusbar/url.py +++ b/qutebrowser/mainwindow/statusbar/url.py @@ -40,7 +40,7 @@ class UrlText(textbase.TextBase): _normal_url: The normal URL to be displayed as a UrlType instance. _normal_url_type: The type of the normal URL as a UrlType instance. _hover_url: The URL we're currently hovering over. - _ssl_errors: Whether SSL errors occured while loading. + _ssl_errors: Whether SSL errors occurred while loading. Class attributes: _urltype: The URL type to show currently (normal/ok/error/warn/hover). diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py index 0254aef22..30cdf1245 100644 --- a/qutebrowser/mainwindow/tabbedbrowser.py +++ b/qutebrowser/mainwindow/tabbedbrowser.py @@ -48,12 +48,12 @@ class TabbedBrowser(tabwidget.TabWidget): """A TabWidget with QWebViews inside. Provides methods to manage tabs, convenience methods to interact with the - current tab (cur_*) and filters signals to re-emit them when they occured + current tab (cur_*) and filters signals to re-emit them when they occurred in the currently visible tab. For all tab-specific signals (cur_*) emitted by a tab, this happens: - the signal gets filtered with _filter_signals and self.cur_* gets - emitted if the signal occured in the current tab. + emitted if the signal occurred in the current tab. Attributes: _win_id: The window ID this tabbedbrowser is associated with. @@ -331,7 +331,7 @@ class TabbedBrowser(tabwidget.TabWidget): url: The URL to open as QUrl or None for an empty tab. background: Whether to open the tab in the background. if None, the background-tabs setting decides. - explicit: Whether the tab was opened explicitely. + explicit: Whether the tab was opened explicitly. If this is set, the new position might be different. With the default settings we handle it like Chromium does: - Tabs from clicked links etc. are to the right of @@ -368,7 +368,7 @@ class TabbedBrowser(tabwidget.TabWidget): """Get the index of a tab to insert. Args: - explicit: Whether the tab was opened explicitely. + explicit: Whether the tab was opened explicitly. Return: The index of the new tab. @@ -590,7 +590,7 @@ class TabbedBrowser(tabwidget.TabWidget): except TabDeletedError: # We can get signals for tabs we already deleted... return - if tab.page().error_occured: + if tab.page().error_occurred: color = config.get('colors', 'tabs.indicator.error') else: start = config.get('colors', 'tabs.indicator.start') diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index 46c2d991c..590f0e89a 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -41,7 +41,7 @@ PM_TabBarPadding = QStyle.PM_CustomBase class TabWidget(QTabWidget): - """The tabwidget used for TabbedBrowser.""" + """The tab widget used for TabbedBrowser.""" def __init__(self, win_id, parent=None): super().__init__(parent) @@ -65,10 +65,10 @@ class TabWidget(QTabWidget): self.setMovable(config.get('tabs', 'movable')) self.setTabsClosable(False) position = config.get('tabs', 'position') - selection_behaviour = config.get('tabs', 'select-on-remove') + selection_behavior = config.get('tabs', 'select-on-remove') self.setTabPosition(position) tabbar.vertical = position in (QTabWidget.West, QTabWidget.East) - tabbar.setSelectionBehaviorOnRemove(selection_behaviour) + tabbar.setSelectionBehaviorOnRemove(selection_behavior) tabbar.refresh() def set_tab_indicator_color(self, idx, color): @@ -187,7 +187,7 @@ class TabWidget(QTabWidget): class TabBar(QTabBar): - """Custom tabbar with our own style. + """Custom tab bar with our own style. FIXME: Dragging tabs doesn't look as nice as it does in QTabBar. However, fixing this would be a lot of effort, so we'll postpone it until we're @@ -221,16 +221,16 @@ class TabBar(QTabBar): @config.change_filter('tabs', 'hide-auto') def autohide(self): - """Hide tabbar if needed when tabs->hide-auto got changed.""" + """Hide tab bar if needed when tabs->hide-auto got changed.""" self._tabhide() @config.change_filter('tabs', 'hide-always') def alwayshide(self): - """Hide tabbar if needed when tabs->hide-always got changed.""" + """Hide tab bar if needed when tabs->hide-always got changed.""" self._tabhide() def _tabhide(self): - """Hide the tabbar if needed.""" + """Hide the tab bar if needed.""" hide_auto = config.get('tabs', 'hide-auto') hide_always = config.get('tabs', 'hide-always') if hide_always or (hide_auto and self.count() == 1): @@ -264,7 +264,7 @@ class TabBar(QTabBar): Args: idx: The tab index to get the title for. - handle_unset: Whether to return an emtpy string on KeyError. + handle_unset: Whether to return an empty string on KeyError. """ try: return self.tab_data(idx, 'page-title') @@ -279,12 +279,12 @@ class TabBar(QTabBar): @config.change_filter('fonts', 'tabbar') def set_font(self): - """Set the tabbar font.""" + """Set the tab bar font.""" self.setFont(config.get('fonts', 'tabbar')) @config.change_filter('colors', 'tabs.bg.bar') def set_colors(self): - """Set the tabbar colors.""" + """Set the tab bar colors.""" p = self.palette() p.setColor(QPalette.Window, config.get('colors', 'tabs.bg.bar')) self.setPalette(p) @@ -311,7 +311,7 @@ class TabBar(QTabBar): """Set the minimum tab size to indicator/icon/... text. Args: - index: The index of the tab to get a sizehint for. + index: The index of the tab to get a size hint for. Return: A QSize. diff --git a/qutebrowser/misc/consolewidget.py b/qutebrowser/misc/consolewidget.py index 8e81335a0..4434275cb 100644 --- a/qutebrowser/misc/consolewidget.py +++ b/qutebrowser/misc/consolewidget.py @@ -149,7 +149,7 @@ class ConsoleWidget(QWidget): _output: The output widget in the console. _vbox: The layout which contains everything. _more: A flag which is set when more input is expected. - _buffer: The buffer for multiline commands. + _buffer: The buffer for multi-line commands. _interpreter: The InteractiveInterpreter to execute code with. """ @@ -195,13 +195,13 @@ class ConsoleWidget(QWidget): self._buffer.append(line) source = '\n'.join(self._buffer) self.write(line + '\n') - # We do two special things with the contextmanagers here: + # We do two special things with the context managers here: # - We replace stdout/stderr to capture output. Even if we could # override InteractiveInterpreter's write method, most things are # printed elsewhere (e.g. by exec). Other Python GUI shells do the # same. # - We disable our exception hook, so exceptions from the console get - # printed and don't ooen a crashdialog. + # printed and don't open a crashdialog. with utils.fake_io(self.write), utils.disabled_excepthook(): self._more = self._interpreter.runsource(source, '') self.write(self._curprompt()) diff --git a/qutebrowser/misc/crashdialog.py b/qutebrowser/misc/crashdialog.py index dd20e7a07..4a5a4f0ea 100644 --- a/qutebrowser/misc/crashdialog.py +++ b/qutebrowser/misc/crashdialog.py @@ -82,7 +82,7 @@ def get_fatal_crash_dialog(debug, data): else: title = "qutebrowser was restarted after a fatal crash!" text = ("qutebrowser was restarted after a fatal crash!
" - "Unfortunately, this crash occured in Qt (the library " + "Unfortunately, this crash occurred in Qt (the library " "qutebrowser uses), and your version ({}) is outdated - " "Qt 5.4 or later is recommended. Unfortuntately Debian and " "Ubuntu don't ship a newer version (yet?)...".format( @@ -403,12 +403,12 @@ class ExceptionCrashDialog(_CrashDialog): class FatalCrashDialog(_CrashDialog): - """Dialog which gets shown when a fatal error occured. + """Dialog which gets shown when a fatal error occurred. Attributes: _log: The log text to display. - _type: The type of error which occured. - _func: The function (top of the stack) in which the error occured. + _type: The type of error which occurred. + _func: The function (top of the stack) in which the error occurred. _chk_history: A checkbox for the user to decide if page history should be sent. """ diff --git a/qutebrowser/misc/earlyinit.py b/qutebrowser/misc/earlyinit.py index 906f8a51b..2307cc8c0 100644 --- a/qutebrowser/misc/earlyinit.py +++ b/qutebrowser/misc/earlyinit.py @@ -39,7 +39,7 @@ try: except ImportError: tkinter = None # NOTE: No qutebrowser or PyQt import should be done here, as some early -# initialisation needs to take place before that! +# initialization needs to take place before that! def _missing_str(name, *, windows=None, pip=None): @@ -97,7 +97,7 @@ def _die(message, exception=None): def init_faulthandler(fileobj=sys.__stderr__): """Enable faulthandler module if available. - This print a nice traceback on segfauls. + This print a nice traceback on segfaults. We use sys.__stderr__ instead of sys.stderr here so this will still work when sys.stderr got replaced, e.g. by "Python Tools for Visual Studio". @@ -163,7 +163,7 @@ def fix_harfbuzz(args): elif args.harfbuzz in ('old', 'new'): # forced harfbuzz variant # FIXME looking at the Qt code, 'new' isn't a valid value, but leaving - # it empty and using new yields different behaviour... + # it empty and using new yields different behavior... # (probably irrelevant when workaround gets removed) log.init.debug("Using {} harfbuzz engine (forced)".format( args.harfbuzz)) @@ -263,7 +263,7 @@ def init_log(args): def earlyinit(args): - """Do all needed early initialisation. + """Do all needed early initialization. Note that it's vital the other earlyinit functions get called in the right order! @@ -272,7 +272,7 @@ def earlyinit(args): args: The argparse namespace. """ # First we initialize the faulthandler as early as possible, so we - # theoretically could catch segfaults occuring later during earlyinit. + # theoretically could catch segfaults occurring later during earlyinit. init_faulthandler() # Here we check if QtCore is available, and if not, print a message to the # console or via Tk. diff --git a/qutebrowser/misc/miscwidgets.py b/qutebrowser/misc/miscwidgets.py index e612b2db0..74dd8f92e 100644 --- a/qutebrowser/misc/miscwidgets.py +++ b/qutebrowser/misc/miscwidgets.py @@ -127,7 +127,7 @@ class _CommandValidator(QValidator): Args: string: The string to validate. - pos: The current curser position. + pos: The current cursor position. Return: A tuple (status, string, pos) as a QValidator should. diff --git a/qutebrowser/misc/savemanager.py b/qutebrowser/misc/savemanager.py index ffef8d361..f55387542 100644 --- a/qutebrowser/misc/savemanager.py +++ b/qutebrowser/misc/savemanager.py @@ -39,7 +39,8 @@ class Saveable: _save_handler: The function to call to save this Saveable. _save_on_exit: Whether to always save this saveable on exit. _config_opt: A (section, option) tuple of a config option which decides - whether to autosave or not. None if no such option exists. + whether to auto-save or not. None if no such option + exists. _filename: The filename of the underlying file. """ @@ -77,7 +78,7 @@ class Saveable: Args: is_exit: Whether we're currently exiting qutebrowser. - explicit: Whether the user explicitely requested this save. + explicit: Whether the user explicitly requested this save. silent: Don't write informations to log. force: Force saving, no matter what. """ @@ -119,7 +120,7 @@ class SaveManager(QObject): return utils.get_repr(self, saveables=self.saveables) def init_autosave(self): - """Initialize autosaving. + """Initialize auto-saving. We don't do this in __init__ because the config needs to be initialized first, but the config needs the save manager. @@ -129,7 +130,7 @@ class SaveManager(QObject): @config.change_filter('general', 'auto-save-interval') def set_autosave_interval(self): - """Set the autosave interval.""" + """Set the auto-save interval.""" interval = config.get('general', 'auto-save-interval') if interval == 0: self._save_timer.stop() @@ -145,7 +146,7 @@ class SaveManager(QObject): name: The name to use. save: The function to call to save this saveable. changed: The signal emitted when this saveable changed. - config_opt: A (section, option) tuple deciding whether to autosave + config_opt: A (section, option) tuple deciding whether to auto-save or not. filename: The filename of the underlying file, so we can force saving if it doesn't exist. @@ -161,7 +162,7 @@ class SaveManager(QObject): Args: is_exit: Whether we're currently exiting qutebrowser. - explicit: Whether this save operation was triggered explicitely. + explicit: Whether this save operation was triggered explicitly. silent: Don't write informations to log. Used to reduce log spam when autosaving. force: Force saving, no matter what. diff --git a/qutebrowser/misc/split.py b/qutebrowser/misc/split.py index 716c685ab..bd1904763 100644 --- a/qutebrowser/misc/split.py +++ b/qutebrowser/misc/split.py @@ -49,7 +49,7 @@ class ShellLexer: self.reset() def reset(self): - """Reset the statemachine state to the defaults.""" + """Reset the state machine state to the defaults.""" self.quoted = False self.escapedstate = ' ' self.token = '' @@ -190,7 +190,7 @@ def simple_split(s, keep=False, maxsplit=None): whitespace = '\n\t ' if maxsplit == 0: # re.split with maxsplit=0 splits everything, while str.split splits - # nothing (which is the behaviour we want). + # nothing (which is the behavior we want). if keep: return [s] else: diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py index 6be8e1bb8..7961bdbbb 100644 --- a/qutebrowser/qutebrowser.py +++ b/qutebrowser/qutebrowser.py @@ -133,7 +133,7 @@ def main(): """ return app.exec_() - # We set qApp explicitely here to reduce the risk of segfaults while + # We set qApp explicitly here to reduce the risk of segfaults while # quitting. # See https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/561303/comments/7 # While this is a workaround for PyQt4 which should be fixed in PyQt, it diff --git a/qutebrowser/test/browser/http/test_content_disposition.py b/qutebrowser/test/browser/http/test_content_disposition.py index b1ba36d10..63f5505fd 100644 --- a/qutebrowser/test/browser/http/test_content_disposition.py +++ b/qutebrowser/test/browser/http/test_content_disposition.py @@ -36,7 +36,7 @@ DEFAULT_NAME = 'qutebrowser-download' class AttachmentTestCase(unittest.TestCase): - """Helper class with some convienence methods to check filenames.""" + """Helper class with some convenience methods to check filenames.""" def _check_filename(self, header, filename): """Check if the passed header has the given filename.""" @@ -120,7 +120,7 @@ class InlineTests(unittest.TestCase): variation of the test checks whether whatever handles PDF display receives the filename information, and acts upon it (this was tested with the latest Acrobat Reader plugin, or, in the case of Chrome, using - the builtin PDF handler). + the built-in PDF handler). """ self._check_filename('inline; filename="foo.pdf"', "foo.pdf") @@ -824,7 +824,7 @@ class EncodingFallbackTests(AttachmentTestCase): "filename=\"foo-ae.html\"", 'foo-ä.html') def test_attfnboth3(self): - """'attachment', specifying an ambigious filename. + """'attachment', specifying an ambiguous filename. currency-sign=¤ in the simple RFC2231/5987 format, and euro-sign=€ in RFC2231-with-continuations format. diff --git a/qutebrowser/test/browser/test_webelem.py b/qutebrowser/test/browser/test_webelem.py index bc423521b..dc320d341 100644 --- a/qutebrowser/test/browser/test_webelem.py +++ b/qutebrowser/test/browser/test_webelem.py @@ -40,8 +40,8 @@ def get_webelem(geometry=None, frame=None, null=False, visibility='', geometry: The geometry of the QWebElement as QRect. frame: The QWebFrame the element is in. null: Whether the element is null or not. - visibility: The CSS visibility style property calue. - display: The CSS display style property calue. + visibility: The CSS visibility style property value. + display: The CSS display style property value. attributes: Boolean HTML attributes to be added. tagname: The tag name. classes: HTML classes to be added. @@ -535,7 +535,7 @@ class IsEditableTests(unittest.TestCase): self.assertFalse(elem.is_editable()) def test_div_noneditable(self): - """Test div-element with non-editableclass.""" + """Test div-element with non-editable class.""" elem = get_webelem(tagname='div', classes='foo-kix-bar') self.assertFalse(elem.is_editable()) diff --git a/qutebrowser/test/config/test_configtypes.py b/qutebrowser/test/config/test_configtypes.py index a922e6fde..022d89c46 100644 --- a/qutebrowser/test/config/test_configtypes.py +++ b/qutebrowser/test/config/test_configtypes.py @@ -1828,7 +1828,7 @@ class SearchEngineUrlTests(unittest.TestCase): self.t.validate('http://example.com/?q={}') def test_validate_invalid_url(self): - """Test validate with an invalud URL.""" + """Test validate with an invalid URL.""" with self.assertRaises(configexc.ValidationError): self.t.validate(':{}') diff --git a/qutebrowser/test/keyinput/test_basekeyparser.py b/qutebrowser/test/keyinput/test_basekeyparser.py index 971e4e181..eb80aa07c 100644 --- a/qutebrowser/test/keyinput/test_basekeyparser.py +++ b/qutebrowser/test/keyinput/test_basekeyparser.py @@ -210,11 +210,11 @@ class KeyChainTests(unittest.TestCase): @mock.patch('qutebrowser.keyinput.basekeyparser.config', new=stubs.ConfigStub(CONFIG)) - def test_ambigious_keychain(self): - """Test ambigious keychain.""" - timer = self.kp._ambigious_timer + def test_ambiguous_keychain(self): + """Test ambiguous keychain.""" + timer = self.kp._ambiguous_timer self.assertFalse(timer.isActive()) - # We start with 'a' where the keychain gives us an ambigious result. + # We start with 'a' where the keychain gives us an ambiguous result. # Then we check if the timer has been set up correctly self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a')) self.assertFalse(self.kp.execute.called) diff --git a/qutebrowser/test/log.py b/qutebrowser/test/log.py index db31cdaa0..37148be0e 100644 --- a/qutebrowser/test/log.py +++ b/qutebrowser/test/log.py @@ -52,7 +52,7 @@ def qt_message_handler(msg_type, context, msg): QtFatalMsg: logging.CRITICAL, } level = qt_to_logging[msg_type] - # There's very similiar code in utils.log, but we want it duplicated here + # There's very similar code in utils.log, but we want it duplicated here # for the tests. if context.function is None: func = 'none' diff --git a/qutebrowser/test/misc/test_editor.py b/qutebrowser/test/misc/test_editor.py index 31843368c..7a707eaed 100644 --- a/qutebrowser/test/misc/test_editor.py +++ b/qutebrowser/test/misc/test_editor.py @@ -100,7 +100,7 @@ class FileHandlingTests(unittest.TestCase): self.editor = editor.ExternalEditor(0) def test_file_handling_closed_ok(self, _proc_mock): - """Test file handling when closing with an exitstatus == 0.""" + """Test file handling when closing with an exit status == 0.""" self.editor.edit("") filename = self.editor._filename self.assertTrue(os.path.exists(filename)) @@ -108,7 +108,7 @@ class FileHandlingTests(unittest.TestCase): self.assertFalse(os.path.exists(filename)) def test_file_handling_closed_error(self, _proc_mock): - """Test file handling when closing with an exitstatus != 0.""" + """Test file handling when closing with an exit status != 0.""" self.editor.edit("") filename = self.editor._filename self.assertTrue(os.path.exists(filename)) diff --git a/qutebrowser/test/misc/test_split.py b/qutebrowser/test/misc/test_split.py index 354c03b16..c2c930b50 100644 --- a/qutebrowser/test/misc/test_split.py +++ b/qutebrowser/test/misc/test_split.py @@ -146,20 +146,20 @@ class SimpleSplitTests(unittest.TestCase): } def test_str_split(self): - """Test if the behaviour matches str.split.""" + """Test if the behavior matches str.split.""" for test in self.TESTS: with self.subTest(string=test): self.assertEqual(split.simple_split(test), test.rstrip().split()) def test_str_split_maxsplit_1(self): - """Test if the behaviour matches str.split with maxsplit=1.""" + """Test if the behavior matches str.split with maxsplit=1.""" string = "foo bar baz" self.assertEqual(split.simple_split(string, maxsplit=1), string.rstrip().split(maxsplit=1)) def test_str_split_maxsplit_0(self): - """Test if the behaviour matches str.split with maxsplit=0.""" + """Test if the behavior matches str.split with maxsplit=0.""" string = " foo bar baz " self.assertEqual(split.simple_split(string, maxsplit=0), string.rstrip().split(maxsplit=0)) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 6ec334f8f..b21db3fb0 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -36,7 +36,7 @@ class QEnumKeyTests(unittest.TestCase): """Tests for qenum_key.""" def test_no_metaobj(self): - """Test with an enum with no metaobject.""" + """Test with an enum with no meta-object.""" with self.assertRaises(AttributeError): # Make sure it doesn't have a meta object # pylint: disable=pointless-statement,no-member @@ -45,9 +45,9 @@ class QEnumKeyTests(unittest.TestCase): self.assertEqual(key, 'PE_PanelButtonCommand') def test_metaobj(self): - """Test with an enum with metaobject.""" + """Test with an enum with meta-object.""" # pylint: disable=pointless-statement - QFrame.staticMetaObject # make sure it has a metaobject + QFrame.staticMetaObject # make sure it has a meta-object key = debug.qenum_key(QFrame, QFrame.Sunken) self.assertEqual(key, 'Sunken') diff --git a/qutebrowser/test/utils/test_log.py b/qutebrowser/test/utils/test_log.py index e91d6aa5d..d52adf552 100644 --- a/qutebrowser/test/utils/test_log.py +++ b/qutebrowser/test/utils/test_log.py @@ -114,7 +114,7 @@ class LogFilterTests(unittest.TestCase): self.assertTrue(logfilter.filter(record)) def test_matching(self): - """Test if a filter lets an exactly matching logrecord through.""" + """Test if a filter lets an exactly matching log record through.""" logfilter = log.LogFilter(["eggs", "bacon"]) record = self._make_record("eggs") self.assertTrue(logfilter.filter(record)) diff --git a/qutebrowser/test/utils/test_qtutils.py b/qutebrowser/test/utils/test_qtutils.py index 3723e4868..582abbf07 100644 --- a/qutebrowser/test/utils/test_qtutils.py +++ b/qutebrowser/test/utils/test_qtutils.py @@ -83,7 +83,7 @@ class CheckOverflowTests(unittest.TestCase): def argparser_exit(status=0, message=None): # pylint: disable=unused-argument - """Function to monkeypatch .exit() of the argparser so it doesn't exit.""" + """Function to monkey-patch .exit() of the argparser so it doesn't exit.""" raise Exception diff --git a/qutebrowser/test/utils/test_standarddir.py b/qutebrowser/test/utils/test_standarddir.py index 8703eed5d..3dfa3fe98 100644 --- a/qutebrowser/test/utils/test_standarddir.py +++ b/qutebrowser/test/utils/test_standarddir.py @@ -46,7 +46,7 @@ class GetStandardDirLinuxTests(unittest.TestCase): @unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux") def test_data_explicit(self): - """Test data dir with XDG_DATA_HOME explicitely set.""" + """Test data dir with XDG_DATA_HOME explicitly set.""" with helpers.environ_set_temp({'XDG_DATA_HOME': self.temp_dir}): standarddir.init(None) expected = os.path.join(self.temp_dir, 'qutebrowser') @@ -54,7 +54,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.""" + """Test config dir with XDG_CONFIG_HOME explicitly set.""" with helpers.environ_set_temp({'XDG_CONFIG_HOME': self.temp_dir}): standarddir.init(None) expected = os.path.join(self.temp_dir, 'qutebrowser') @@ -62,7 +62,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.""" + """Test cache dir with XDG_CACHE_HOME explicitly set.""" with helpers.environ_set_temp({'XDG_CACHE_HOME': self.temp_dir}): standarddir.init(None) expected = os.path.join(self.temp_dir, 'qutebrowser') diff --git a/qutebrowser/test/utils/test_utils.py b/qutebrowser/test/utils/test_utils.py index 088ce49c7..96bc8a4fa 100644 --- a/qutebrowser/test/utils/test_utils.py +++ b/qutebrowser/test/utils/test_utils.py @@ -71,7 +71,7 @@ class ReadFileTests(unittest.TestCase): """Test read_file.""" def test_readfile(self): - """Read a testfile.""" + """Read a test file.""" content = utils.read_file(os.path.join('test', 'testfile')) self.assertEqual(content.splitlines()[0], "Hello World!") @@ -299,13 +299,13 @@ class KeyEventToStringTests(unittest.TestCase): """Test keyevent_to_string.""" def test_only_control(self): - """Test keyeevent when only control is pressed.""" + """Test keyevent when only control is pressed.""" 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.""" + """Test keyevent when only Hyper_L is pressed.""" evt = helpers.fake_keyevent(key=Qt.Key_Hyper_L, modifiers=Qt.MetaModifier) self.assertIsNone(utils.keyevent_to_string(evt)) @@ -423,7 +423,7 @@ class ForceEncodingTests(unittest.TestCase): """Test force_encoding.""" def test_fitting_ascii(self): - """Test with a text fitting into ascii.""" + """Test with a text fitting into ASCII.""" text = 'hello world' self.assertEqual(utils.force_encoding(text, 'ascii'), text) @@ -433,7 +433,7 @@ class ForceEncodingTests(unittest.TestCase): self.assertEqual(utils.force_encoding(text, 'utf-8'), text) def test_not_fitting_ascii(self): - """Test with a text not fitting into ascii.""" + """Test with a text not fitting into ASCII.""" text = 'hellö wörld' self.assertEqual(utils.force_encoding(text, 'ascii'), 'hell? w?rld') diff --git a/qutebrowser/test/utils/usertypes/test_neighborlist.py b/qutebrowser/test/utils/usertypes/test_neighborlist.py index 9895c4b7d..ebde77a60 100644 --- a/qutebrowser/test/utils/usertypes/test_neighborlist.py +++ b/qutebrowser/test/utils/usertypes/test_neighborlist.py @@ -245,14 +245,14 @@ class BlockTests(unittest.TestCase): mode=usertypes.NeighborList.Modes.block) def test_first(self): - """Test ouf of bounds previtem().""" + """Test out of bounds previtem().""" self.nl.firstitem() self.assertEqual(self.nl._idx, 0) self.assertEqual(self.nl.previtem(), 1) self.assertEqual(self.nl._idx, 0) def test_last(self): - """Test ouf of bounds nextitem().""" + """Test out of bounds nextitem().""" self.nl.lastitem() self.assertEqual(self.nl._idx, 4) self.assertEqual(self.nl.nextitem(), 5) @@ -272,14 +272,14 @@ class WrapTests(unittest.TestCase): [1, 2, 3, 4, 5], default=3, mode=usertypes.NeighborList.Modes.wrap) def test_first(self): - """Test ouf of bounds previtem().""" + """Test out of bounds previtem().""" self.nl.firstitem() self.assertEqual(self.nl._idx, 0) self.assertEqual(self.nl.previtem(), 5) self.assertEqual(self.nl._idx, 4) def test_last(self): - """Test ouf of bounds nextitem().""" + """Test out of bounds nextitem().""" self.nl.lastitem() self.assertEqual(self.nl._idx, 4) self.assertEqual(self.nl.nextitem(), 1) @@ -300,7 +300,7 @@ class RaiseTests(unittest.TestCase): mode=usertypes.NeighborList.Modes.exception) def test_first(self): - """Test ouf of bounds previtem().""" + """Test out of bounds previtem().""" self.nl.firstitem() self.assertEqual(self.nl._idx, 0) with self.assertRaises(IndexError): @@ -308,7 +308,7 @@ class RaiseTests(unittest.TestCase): self.assertEqual(self.nl._idx, 0) def test_last(self): - """Test ouf of bounds nextitem().""" + """Test out of bounds nextitem().""" self.nl.lastitem() self.assertEqual(self.nl._idx, 4) with self.assertRaises(IndexError): diff --git a/qutebrowser/utils/jinja.py b/qutebrowser/utils/jinja.py index 3e2519ad2..549f13ea7 100644 --- a/qutebrowser/utils/jinja.py +++ b/qutebrowser/utils/jinja.py @@ -49,7 +49,7 @@ class Loader(jinja2.BaseLoader): def _guess_autoescape(template_name): - """Turn autoescape on/off based on the filetype. + """Turn auto-escape on/off based on the file type. Based on http://jinja.pocoo.org/docs/dev/api/#autoescaping """ diff --git a/qutebrowser/utils/standarddir.py b/qutebrowser/utils/standarddir.py index a3f608fa1..8eb86e0da 100644 --- a/qutebrowser/utils/standarddir.py +++ b/qutebrowser/utils/standarddir.py @@ -77,7 +77,7 @@ def _from_args(typ, args): Return: A (override, path) tuple. override: boolean, if the user did override the path - path: The overriden path, or None to turn off storage. + path: The overridden path, or None to turn off storage. """ typ_to_argparse_arg = { QStandardPaths.ConfigLocation: 'confdir' diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index 3efc91ad7..ba4ed1786 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -148,7 +148,7 @@ def fuzzy_url(urlstr, cwd=None, relative=False, do_search=True): do_search: Whether to perform a search on non-URLs. Return: - A target QUrl to a searchpage or the original URL. + A target QUrl to a search page or the original URL. """ expanded = os.path.expanduser(urlstr) if relative and cwd: diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 18f04b4d5..7371f3114 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Custom useful datatypes. +"""Custom useful data types. Module attributes: _UNSET: Used as default argument in the constructor so default can be None. @@ -40,7 +40,7 @@ def enum(name, items, start=1, is_int=False): Args: name: Name of the enum - items: Iterable of ttems to be sequentally enumerated. + items: Iterable of items to be sequentially enumerated. start: The number to use for the first value. We use 1 as default so enum members are always True. is_init: True if the enum should be a Python IntEnum @@ -309,7 +309,7 @@ class Question(QObject): @pyqtSlot() def done(self): - """Must be called when the queston was answered completely.""" + """Must be called when the question was answered completely.""" self.answered.emit(self.answer) if self.mode == PromptMode.yesno: if self.answer: diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py index e409f18ee..724707e8e 100644 --- a/qutebrowser/utils/utils.py +++ b/qutebrowser/utils/utils.py @@ -95,7 +95,7 @@ def read_file(filename, binary=False): def actute_warning(): """Display a warning about the dead_actute issue if needed.""" # WORKAROUND (remove this when we bump the requirements to 5.3.0) - # Non linux OS' aren't affected + # Non Linux OS' aren't affected if not sys.platform.startswith('linux'): return # If no compose file exists for some reason, we're not affected @@ -151,7 +151,7 @@ def interpolate_color(start, end, percent, colorspace=QColor.Rgb): start: The start color. end: The end color. percent: Which value to get (0 - 100) - colorspace: The desired interpolation colorsystem, + colorspace: The desired interpolation color system, QColor::{Rgb,Hsv,Hsl} (from QColor::Spec enum) Return: @@ -435,7 +435,7 @@ class prevent_exceptions: # pylint: disable=invalid-name silently ignores them. We used to re-raise the exception with a single-shot QTimer in a similar - case, but that lead to a strange proble with a KeyError with some random + case, but that lead to a strange problem with a KeyError with some random jinja template stuff as content. For now, we only log it, so it doesn't pass 100% silently. diff --git a/scripts/misc_checks.py b/scripts/misc_checks.py index 537f0b6f1..78c6d5b41 100644 --- a/scripts/misc_checks.py +++ b/scripts/misc_checks.py @@ -34,7 +34,7 @@ from scripts import utils def check_git(): - """Check for uncommited git files..""" + """Check for uncommitted git files..""" if not os.path.isdir(".git"): print("No .git dir, ignoring") print() diff --git a/scripts/segfault_test.py b/scripts/segfault_test.py index b47dfaeca..e2a374343 100755 --- a/scripts/segfault_test.py +++ b/scripts/segfault_test.py @@ -74,7 +74,7 @@ def main(): ('http://www.binpress.com/', False), ('http://david.li/flow/', False), ('https://imzdl.com/', False), - # not reproducable + # not reproducible # https://bugreports.qt-project.org/browse/QTBUG-39847 ('http://www.20min.ch/', True), # HarfBuzz, https://bugreports.qt-project.org/browse/QTBUG-39278 diff --git a/scripts/utils.py b/scripts/utils.py index d6d70a796..c6fdacd24 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -61,7 +61,7 @@ term_attributes = { def _esc(code): - """Get an ANSII color code based on a color number.""" + """Get an ANSI color code based on a color number.""" return '\033[{}m'.format(code) From 38c63ca2ea3b41314bfd600cc5758dbbae822e89 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 31 Mar 2015 22:12:38 +0200 Subject: [PATCH 03/69] Add a checker for words which I often misspell. --- scripts/misc_checks.py | 65 ++++++++++++++++++++++++++++++++++++------ tox.ini | 1 + 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/scripts/misc_checks.py b/scripts/misc_checks.py index 78c6d5b41..bea0a4628 100644 --- a/scripts/misc_checks.py +++ b/scripts/misc_checks.py @@ -21,18 +21,27 @@ """Various small code checkers.""" import os +import re import sys import os.path import argparse import subprocess import tokenize import traceback +import collections sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir)) from scripts import utils +def _py_files(target): + """Iterate over all python files and yield filenames.""" + for (dirpath, _dirnames, filenames) in os.walk(target): + for name in (e for e in filenames if e.endswith('.py')): + yield os.path.join(dirpath, name) + + def check_git(): """Check for uncommitted git files..""" if not os.path.isdir(".git"): @@ -55,18 +64,49 @@ def check_git(): return status +def check_spelling(target): + """Check commonly misspelled words.""" + # Words which I often misspell + words = {'behaviour', 'quitted', 'likelyhood', 'sucessfully', + 'occur[^r .]', 'seperator', 'explicitely', 'resetted', + 'auxillary', 'accidentaly', 'ambigious', 'loosly', + 'initialis', 'convienence', 'similiar', 'uncommited', + 'reproducable'} + + # Words which look better when splitted, but might need some fine tuning. + words |= {'keystrings', 'webelements', 'mouseevent', 'keysequence', + 'normalmode', 'eventloops', 'sizehint', 'statemachine', + 'metaobject', 'logrecord', 'monkeypatch', 'filetype'} + + seen = collections.defaultdict(list) + try: + ok = True + for fn in _py_files(target): + with tokenize.open(fn) as f: + if fn == os.path.join('scripts', 'misc_checks.py'): + continue + for line in f: + for w in words: + if re.search(w, line) and fn not in seen[w]: + print("Found '{}' in {}!".format(w, fn)) + seen[w].append(fn) + print() + return ok + except Exception: + traceback.print_exc() + return None + + def check_vcs_conflict(target): """Check VCS conflict markers.""" try: ok = True - for (dirpath, _dirnames, filenames) in os.walk(target): - for name in (e for e in filenames if e.endswith('.py')): - fn = os.path.join(dirpath, name) - with tokenize.open(fn) as f: - for line in f: - if any(line.startswith(c * 7) for c in '<>=|'): - print("Found conflict marker in {}".format(fn)) - ok = False + for fn in _py_files(target): + with tokenize.open(fn) as f: + for line in f: + if any(line.startswith(c * 7) for c in '<>=|'): + print("Found conflict marker in {}".format(fn)) + ok = False print() return ok except Exception: @@ -77,7 +117,7 @@ def check_vcs_conflict(target): def main(): """Main entry point.""" parser = argparse.ArgumentParser() - parser.add_argument('checker', choices=('git', 'vcs'), + parser.add_argument('checker', choices=('git', 'vcs', 'spelling'), help="Which checker to run.") parser.add_argument('target', help="What to check", nargs='*') args = parser.parse_args() @@ -91,6 +131,13 @@ def main(): if not ok: is_ok = False return 0 if is_ok else 1 + elif args.checker == 'spelling': + is_ok = True + for target in args.target: + ok = check_spelling(target) + if not ok: + is_ok = False + return 0 if is_ok else 1 if __name__ == '__main__': diff --git a/tox.ini b/tox.ini index 3743eae91..143d4f804 100644 --- a/tox.ini +++ b/tox.ini @@ -39,6 +39,7 @@ commands = commands = {envpython} scripts/misc_checks.py git {envpython} scripts/misc_checks.py vcs qutebrowser scripts + {envpython} scripts/misc_checks.py spelling qutebrowser scripts [testenv:pylint] skip_install = true From 16ffafb7696b6e9d45a43a72801790f80c3dc140 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 31 Mar 2015 22:14:35 +0200 Subject: [PATCH 04/69] Regenerate docs. --- doc/help/commands.asciidoc | 14 ++++++++++++-- doc/help/settings.asciidoc | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 3c45c56ff..70c707def 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -874,7 +874,8 @@ These commands are mainly intended for debugging. They are hidden if qutebrowser |<>|Print LRU cache stats. |<>|Show the debugging console. |<>|Crash for debugging purposes. -|<>|Evaluate a python string and display the results as a webpage. +|<>|Evaluate a python string and display the results as a web page. +|<>|Trace executed code via hunter. |============== [[debug-all-objects]] === debug-all-objects @@ -901,8 +902,17 @@ Crash for debugging purposes. === debug-pyeval Syntax: +:debug-pyeval 's'+ -Evaluate a python string and display the results as a webpage. +Evaluate a python string and display the results as a web page. ==== positional arguments * +'s'+: The string to evaluate. +[[debug-trace]] +=== debug-trace +Syntax: +:debug-trace ['expr']+ + +Trace executed code via hunter. + +==== positional arguments +* +'expr'+: What to trace, passed to hunter. + diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 393738868..02d9bb5dc 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -95,8 +95,8 @@ |<>|How new tabs are positioned. |<>|How new tabs opened explicitly are positioned. |<>|Behaviour when the last tab is closed. -|<>|Hide the tabbar if only one tab is open. -|<>|Always hide the tabbar. +|<>|Hide the tab bar if only one tab is open. +|<>|Always hide the tab bar. |<>|Whether to wrap when changing tabs. |<>|Whether tabs should be movable. |<>|On which mouse button to close tabs. @@ -196,7 +196,7 @@ |<>|Background color of unselected odd tabs. |<>|Background color of unselected even tabs. |<>|Background color of selected tabs. -|<>|Background color of the tabbar. +|<>|Background color of the tab bar. |<>|Color gradient start for the tab indicator. |<>|Color gradient end for the tab indicator. |<>|Color for the tab indicator on errors.. @@ -218,7 +218,7 @@ |Setting|Description |<>|Default monospace fonts. |<>|Font used in the completion widget. -|<>|Font used in the tabbar. +|<>|Font used in the tab bar. |<>|Font used in the statusbar. |<>|Font used for the downloadbar. |<>|Font used for the hints. @@ -537,7 +537,7 @@ The format to use for the window title. The following placeholders are defined: * `{perc}`: The percentage as a string like `[10%]`. * `{perc_raw}`: The raw percentage, e.g. `10` -* `{title}`: The title of the current webpage +* `{title}`: The title of the current web page * `{title_sep}`: The string ` - ` if a title is set, empty otherwise. * `{id}`: The internal window ID of this window. @@ -859,7 +859,7 @@ Default: +pass:[ignore]+ [[tabs-hide-auto]] === hide-auto -Hide the tabbar if only one tab is open. +Hide the tab bar if only one tab is open. Valid values: @@ -870,7 +870,7 @@ Default: +pass:[false]+ [[tabs-hide-always]] === hide-always -Always hide the tabbar. +Always hide the tab bar. Valid values: @@ -972,7 +972,7 @@ The format to use for the tab title. The following placeholders are defined: * `{perc}`: The percentage as a string like `[10%]`. * `{perc_raw}`: The raw percentage, e.g. `10` -* `{title}`: The title of the current webpage +* `{title}`: The title of the current web page * `{title_sep}`: The string ` - ` if a title is set, empty otherwise. * `{index}`: The index of this tab. * `{id}`: The internal tab ID of this tab. @@ -1535,7 +1535,7 @@ Default: +pass:[black]+ [[colors-tabs.bg.bar]] === tabs.bg.bar -Background color of the tabbar. +Background color of the tab bar. Default: +pass:[#555555]+ @@ -1650,7 +1650,7 @@ Default: +pass:[8pt ${_monospace}]+ [[fonts-tabbar]] === tabbar -Font used in the tabbar. +Font used in the tab bar. Default: +pass:[8pt ${_monospace}]+ From 431257d3807446f264d6da204de4cbdcacef2611 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 31 Mar 2015 23:09:40 +0200 Subject: [PATCH 05/69] Fix handling of key release events. Fixes #593. It seems Qt "re-uses" existing keyevents, so we have to save and compare the data instead. --- qutebrowser/keyinput/modeman.py | 40 +++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py index 0d7fdd088..4699de8e9 100644 --- a/qutebrowser/keyinput/modeman.py +++ b/qutebrowser/keyinput/modeman.py @@ -32,6 +32,33 @@ from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.utils import usertypes, log, objreg, utils +class KeyEvent: + + """A small wrapper over a QKeyEvent storing its data. + + This is needed because Qt apparently mutates existing events with new data. + It doesn't store the modifiers because they can be different for a key + press/release. + + Attributes: + key: A Qt.Key member (QKeyEvent::key). + text: A string (QKeyEvent::text). + """ + + def __init__(self, keyevent): + self.key = keyevent.key() + self.text = keyevent.text() + + def __repr__(self): + return utils.get_repr(self, key=self.key, text=self.text) + + def __eq__(self, other): + return self.key == other.key and self.text == other.text + + def __hash__(self): + return hash((self.key, self.text)) + + class NotInModeError(Exception): """Exception raised when we want to leave a mode we're not in.""" @@ -143,7 +170,7 @@ class ModeManager(QObject): _win_id: The window ID of this ModeManager _handlers: A dictionary of modes and their handlers. _forward_unbound_keys: If we should forward unbound keys. - _releaseevents_to_pass: A list of keys where the keyPressEvent was + _releaseevents_to_pass: A set of KeyEvents where the keyPressEvent was passed through, so the release event should as well. @@ -166,7 +193,7 @@ class ModeManager(QObject): self._handlers = {} self.passthrough = [] self.mode = usertypes.KeyMode.normal - self._releaseevents_to_pass = [] + self._releaseevents_to_pass = set() self._forward_unbound_keys = config.get( 'input', 'forward-unbound-keys') objreg.get('config').changed.connect(self.set_forward_unbound_keys) @@ -207,7 +234,7 @@ class ModeManager(QObject): filter_this = True if not filter_this: - self._releaseevents_to_pass.append(event) + self._releaseevents_to_pass.add(KeyEvent(event)) if curmode != usertypes.KeyMode.insert: log.modes.debug("handled: {}, forward-unbound-keys: {}, " @@ -228,10 +255,9 @@ class ModeManager(QObject): True if event should be filtered, False otherwise. """ # handle like matching KeyPress - if event in self._releaseevents_to_pass: - # remove all occurrences - self._releaseevents_to_pass = [ - e for e in self._releaseevents_to_pass if e != event] + keyevent = KeyEvent(event) + if keyevent in self._releaseevents_to_pass: + self._releaseevents_to_pass.remove(keyevent) filter_this = False else: filter_this = True From eeb875d0982fb5813df3716ce0120b269acf5def Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 00:02:29 +0200 Subject: [PATCH 06/69] Handle unavailable registry in on_focus_changed. --- qutebrowser/utils/message.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py index e96597124..b8d23a845 100644 --- a/qutebrowser/utils/message.py +++ b/qutebrowser/utils/message.py @@ -97,7 +97,12 @@ def on_focus_changed(): delta = datetime.datetime.now() - msg.time log.misc.debug("Handling queued {} for window {}, delta {}".format( msg.method_name, msg.win_id, delta)) - bridge = _get_bridge(msg.win_id) + try: + bridge = _get_bridge(msg.win_id) + except objreg.RegistryUnavailableError: + # Non-mainwindow window focused. + _QUEUED.append(msg) + return if delta.total_seconds() < 1: text = msg.text else: From 6e435ad2157afc379fdeb883110e0950136d9cf8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 18:21:02 +0200 Subject: [PATCH 07/69] Add state config sections when initializing. --- qutebrowser/app.py | 12 ------------ qutebrowser/config/config.py | 5 +++++ qutebrowser/misc/sessions.py | 5 ----- qutebrowser/misc/utilcmds.py | 5 ----- 4 files changed, 5 insertions(+), 22 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index ffe515f4c..cf6ba5a72 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -437,10 +437,6 @@ class Application(QApplication): window='last-focused') tabbed_browser.tabopen( QUrl('http://www.qutebrowser.org/quickstart.html')) - try: - state_config.add_section('general') - except configparser.DuplicateSectionError: - pass state_config['general']['quickstart-done'] = '1' def _setup_signals(self): @@ -561,19 +557,11 @@ class Application(QApplication): if self.geometry is not None: state_config = objreg.get('state-config') geom = base64.b64encode(self.geometry).decode('ASCII') - try: - state_config.add_section('geometry') - except configparser.DuplicateSectionError: - pass state_config['geometry']['mainwindow'] = geom def _save_version(self): """Save the current version to the state config.""" state_config = objreg.get('state-config') - try: - state_config.add_section('general') - except configparser.DuplicateSectionError: - pass state_config['general']['version'] = qutebrowser.__version__ def _destroy_crashlogfile(self): diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 621eba4a8..6b7f1f8fb 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -179,6 +179,11 @@ def _init_misc(): """Initialize misc. config-related files.""" save_manager = objreg.get('save-manager') state_config = ini.ReadWriteConfigParser(standarddir.data(), 'state') + for sect in ('general', 'geometry'): + try: + state_config.add_section(sect) + except configparser.DuplicateSectionError: + pass objreg.register('state-config', state_config) save_manager.add_saveable('state-config', state_config.save) diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py index 45ddeabd2..0e0c22b9e 100644 --- a/qutebrowser/misc/sessions.py +++ b/qutebrowser/misc/sessions.py @@ -21,7 +21,6 @@ import os import os.path -import configparser from PyQt5.QtCore import pyqtSignal, QUrl, QObject, QPoint, QTimer from PyQt5.QtWidgets import QApplication @@ -185,10 +184,6 @@ class SessionManager(QObject): self.update_completion.emit() if load_next_time: state_config = objreg.get('state-config') - try: - state_config.add_section('general') - except configparser.DuplicateSectionError: - pass state_config['general']['session'] = name def save_last_window_session(self): diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index b5a8e7e03..826ea8fc0 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -19,7 +19,6 @@ """Misc. utility commands exposed to the user.""" -import configparser import functools import types @@ -144,9 +143,5 @@ def fooled(): """Turn off april's fools.""" from qutebrowser.config import websettings state_config = objreg.get('state-config') - try: - state_config.add_section('general') - except configparser.DuplicateSectionError: - pass state_config['general']['fooled'] = '1' websettings.update_settings('ui', 'user-stylesheet') From 8748420b1b78a703ea4188b63699df181acbee27 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 21:36:56 +0200 Subject: [PATCH 08/69] src2asciidoc: Skip suppressed arguments. --- scripts/src2asciidoc.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/src2asciidoc.py b/scripts/src2asciidoc.py index 451126284..80921fb4c 100755 --- a/scripts/src2asciidoc.py +++ b/scripts/src2asciidoc.py @@ -227,6 +227,8 @@ def _format_action_args(action): def _format_action(action): """Get an invocation string/help from an argparse action.""" + if action.help == argparse.SUPPRESS: + return None if not action.option_strings: invocation = '*{}*::'.format(_get_action_metavar(action)) else: @@ -396,7 +398,9 @@ def regenerate_manpage(filename): if group.description is not None: groupdata.append(group.description) for action in group._group_actions: - groupdata.append(_format_action(action)) + action_data = _format_action(action) + if action_data is not None: + groupdata.append(action_data) groups.append('\n'.join(groupdata)) options = '\n'.join(groups) # epilog From 11bd4a13f6677d9b4951d50a252e222fa8b6fca1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 21:28:56 +0200 Subject: [PATCH 09/69] Serialize arguments via json on restart. We want to ignore some positional arguments without ignoring flags/values - and since there's no easy way to "unparse" an argparse namespace, we instead pass it as json. Also note we can't pass it as a file easily, as args have to be available very early. Passing it as an argument shouldn't be an issue though. --- qutebrowser/app.py | 22 ++++++++++++++++------ qutebrowser/qutebrowser.py | 9 +++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index cf6ba5a72..862214450 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -31,6 +31,7 @@ import functools import traceback import faulthandler import datetime +import json from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon @@ -683,19 +684,28 @@ class Application(QApplication): # cwd=None and see if that works out. # See https://github.com/The-Compiler/qutebrowser/issues/323 cwd = None - for arg in sys.argv[1:]: - if arg.startswith('-'): - # We only want to preserve options on a restart. - args.append(arg) + # Add all open pages so they get reopened. page_args = [] for win in pages: page_args.extend(win) page_args.append('') - if page_args: - args.extend(page_args[:-1]) + + # Serialize the argparse namespace into json and pass that to the new + # process via --json-args. + # We do this as there's no way to "unparse" the namespace while + # ignoring some arguments. + argdict = vars(self._args) + argdict['session'] = None + argdict['url'] = [] + argdict['command'] = page_args[:-1] + argdict['json_args'] = None + data = json.dumps(argdict) + args += ['--json-args', data] + log.destroy.debug("args: {}".format(args)) log.destroy.debug("cwd: {}".format(cwd)) + return args, cwd @cmdutils.register(instance='app', ignore_args=True) diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py index 7961bdbbb..ee6663f0f 100644 --- a/qutebrowser/qutebrowser.py +++ b/qutebrowser/qutebrowser.py @@ -20,6 +20,7 @@ """Early initialization and main entry point.""" import sys +import json import qutebrowser try: @@ -58,6 +59,7 @@ def get_argparser(): parser.add_argument('-R', '--override-restore', help="Don't restore a " "session even if one would be restored.", action='store_true') + parser.add_argument('--json-args', help=argparse.SUPPRESS) debug = parser.add_argument_group('debug arguments') debug.add_argument('-l', '--loglevel', dest='loglevel', @@ -118,6 +120,13 @@ def main(): """Main entry point for qutebrowser.""" parser = get_argparser() args = parser.parse_args() + if args.json_args is not None: + # Restoring after a restart. + # When restarting, we serialize the argparse namespace into json, and + # construct a "fake" argparse.Namespace here based on the data loaded + # from json. + data = json.loads(args.json_args) + args = argparse.Namespace(**data) earlyinit.earlyinit(args) # We do this imports late as earlyinit needs to be run first (because of # the harfbuzz fix and version checking). From 371ec564e13f7ba08c318ea1b42f69ad20b73f9b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 21:38:18 +0200 Subject: [PATCH 10/69] Split restart() into :restart and _do_restart(). --- qutebrowser/app.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 862214450..18f3e4689 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -649,7 +649,8 @@ class Application(QApplication): self._args.debug, pages, cmd_history, exc, objects) ret = self._crashdlg.exec_() if ret == QDialog.Accepted: # restore - self.restart(shutdown=False, pages=pages) + self._do_restart(pages) + # We might risk a segfault here, but that's better than continuing to # run in some undefined state, so we only do the most needed shutdown # here. @@ -708,11 +709,23 @@ class Application(QApplication): return args, cwd - @cmdutils.register(instance='app', ignore_args=True) - def restart(self, shutdown=True, pages=None): + @cmdutils.register(instance='app') + def restart(self): """Restart qutebrowser while keeping existing tabs open.""" - if pages is None: - pages = self._recover_pages() + pages = self._recover_pages() + ok = self._do_restart(pages) + if ok: + self.shutdown() + + def _do_restart(self, pages): + """Inner logic to restart qutebrowser. + + Args: + pages: A list of URLs to open. + + Return: + True if the restart succeeded, False otherwise. + """ log.destroy.debug("sys.executable: {}".format(sys.executable)) log.destroy.debug("sys.path: {}".format(sys.path)) log.destroy.debug("sys.argv: {}".format(sys.argv)) @@ -726,9 +739,10 @@ class Application(QApplication): subprocess.Popen(args, cwd=cwd) except OSError: log.destroy.exception("Failed to restart") + return False else: - if shutdown: - self.shutdown() + return True + @cmdutils.register(instance='app', maxsplit=0, debug=True) def debug_pyeval(self, s): From 2ba28a59fe09c5c83eed73799640048231835cd6 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 21:42:02 +0200 Subject: [PATCH 11/69] Prevent session from being loaded with :restart. --- qutebrowser/app.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 18f3e4689..a10fa1f4d 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -701,6 +701,10 @@ class Application(QApplication): argdict['url'] = [] argdict['command'] = page_args[:-1] argdict['json_args'] = None + # Ensure a session does never get opened. + argdict['session'] = None + argdict['override_restore'] = True + # Dump the data data = json.dumps(argdict) args += ['--json-args', data] From 840652f396be6d73b76008f6eb6b02ddc7ebf82a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 22:18:28 +0200 Subject: [PATCH 12/69] Use sessions for :restart. This saves a lot more state compared to just passing a list of pages. --- qutebrowser/app.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index a10fa1f4d..4fa429c89 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -317,6 +317,9 @@ class Application(QApplication): del state_config['general']['session'] except KeyError: pass + # If this was a _restart session, delete it. + if name == '_restart': + session_manager.delete('_restart') def _get_window(self, via_ipc, force_window=False, force_tab=False): """Helper function for process_pos_args to get a window id. @@ -658,11 +661,12 @@ class Application(QApplication): self._destroy_crashlogfile() sys.exit(1) - def _get_restart_args(self, pages): + def _get_restart_args(self, pages=(), session=None): """Get the current working directory and args to relaunch qutebrowser. Args: pages: The pages to re-open. + session: The session to load, or None. Return: An (args, cwd) tuple. @@ -701,9 +705,13 @@ class Application(QApplication): argdict['url'] = [] argdict['command'] = page_args[:-1] argdict['json_args'] = None - # Ensure a session does never get opened. - argdict['session'] = None - argdict['override_restore'] = True + # Ensure the given session (or none at all) gets opened. + if session is None: + argdict['session'] = None + argdict['override_restore'] = True + else: + argdict['session'] = session + argdict['override_restore'] = False # Dump the data data = json.dumps(argdict) args += ['--json-args', data] @@ -716,16 +724,23 @@ class Application(QApplication): @cmdutils.register(instance='app') def restart(self): """Restart qutebrowser while keeping existing tabs open.""" - pages = self._recover_pages() - ok = self._do_restart(pages) + ok = self._do_restart(session='_restart') if ok: self.shutdown() - def _do_restart(self, pages): + def _do_restart(self, pages=(), session=None): """Inner logic to restart qutebrowser. + The "better" way to restart is to pass a session (_restart usually) as + that'll save the complete state. + + However we don't do that (and pass a list of pages instead) when we + restart because of an exception, as that's a lot simpler and we don't + want to risk anything going wrong. + Args: pages: A list of URLs to open. + session: The session to load, or None. Return: True if the restart succeeded, False otherwise. @@ -734,9 +749,13 @@ class Application(QApplication): log.destroy.debug("sys.path: {}".format(sys.path)) log.destroy.debug("sys.argv: {}".format(sys.argv)) log.destroy.debug("frozen: {}".format(hasattr(sys, 'frozen'))) + # Save the session if one is given. + if session is not None: + session_manager = objreg.get('session-manager') + session_manager.save(session) # Open a new process and immediately shutdown the existing one try: - args, cwd = self._get_restart_args(pages) + args, cwd = self._get_restart_args(pages, session) if cwd is None: subprocess.Popen(args) else: @@ -747,7 +766,6 @@ class Application(QApplication): else: return True - @cmdutils.register(instance='app', maxsplit=0, debug=True) def debug_pyeval(self, s): """Evaluate a python string and display the results as a web page. From 1fb848249e0a652c549569815ea97c424585b42a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 22:30:46 +0200 Subject: [PATCH 13/69] Handle sessions starting with _ as internal. :session-{load,save,delete} now refuses to handle sessions starting with _, unless a new -f/--force parameter is given. --- doc/help/commands.asciidoc | 13 ++++++++++--- qutebrowser/misc/sessions.py | 21 ++++++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 70c707def..3aafacc74 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -406,16 +406,20 @@ Search for a text on the current page. [[session-delete]] === session-delete -Syntax: +:session-delete 'name'+ +Syntax: +:session-delete [*--force*] 'name'+ Delete a session. ==== positional arguments * +'name'+: The name of the session. +==== optional arguments +* +*-f*+, +*--force*+: Force deleting internal sessions (starting with an underline). + + [[session-load]] === session-load -Syntax: +:session-load [*--clear*] 'name'+ +Syntax: +:session-load [*--clear*] [*--force*] 'name'+ Load a session. @@ -424,10 +428,12 @@ Load a session. ==== optional arguments * +*-c*+, +*--clear*+: Close all existing windows. +* +*-f*+, +*--force*+: Force loading internal sessions (starting with an underline). + [[session-save]] === session-save -Syntax: +:session-save [*--quiet*] ['name']+ +Syntax: +:session-save [*--quiet*] [*--force*] ['name']+ Save a session. @@ -436,6 +442,7 @@ Save a session. ==== optional arguments * +*-q*+, +*--quiet*+: Don't show confirmation message. +* +*-f*+, +*--force*+: Force saving internal sessions (starting with an underline). [[set]] === set diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py index 0e0c22b9e..921c889e1 100644 --- a/qutebrowser/misc/sessions.py +++ b/qutebrowser/misc/sessions.py @@ -261,13 +261,18 @@ class SessionManager(QObject): @cmdutils.register(completion=[usertypes.Completion.sessions], instance='session-manager') - def session_load(self, name, clear=False): + def session_load(self, name, clear=False, force=False): """Load a session. Args: name: The name of the session. clear: Close all existing windows. + force: Force loading internal sessions (starting with an + underline). """ + if name.startswith('_') and not force: + raise cmdexc.CommandError("{!r} is an internal session, use " + "--force to load anyways.".format(name)) old_windows = list(objreg.window_registry.values()) try: self.load(name) @@ -285,14 +290,18 @@ class SessionManager(QObject): completion=[usertypes.Completion.sessions], instance='session-manager') def session_save(self, win_id: {'special': 'win_id'}, name='default', - quiet=False): + quiet=False, force=False): """Save a session. Args: win_id: The current window ID. name: The name of the session. quiet: Don't show confirmation message. + force: Force saving internal sessions (starting with an underline). """ + if name.startswith('_') and not force: + raise cmdexc.CommandError("{!r} is an internal session, use " + "--force to save anyways.".format(name)) try: self.save(name) except SessionError as e: @@ -305,12 +314,18 @@ class SessionManager(QObject): @cmdutils.register(completion=[usertypes.Completion.sessions], instance='session-manager') - def session_delete(self, name): + def session_delete(self, name, force=False): """Delete a session. Args: name: The name of the session. + force: Force deleting internal sessions (starting with an + underline). """ + if name.startswith('_') and not force: + raise cmdexc.CommandError("{!r} is an internal session, use " + "--force to delete anyways.".format( + name)) try: self.delete(name) except OSError as e: From 068e1c14b67eb524a6f71905c931d7dfa738da73 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 1 Apr 2015 22:32:41 +0200 Subject: [PATCH 14/69] Don't display internal sessions in completion. --- qutebrowser/completion/models/miscmodels.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/completion/models/miscmodels.py b/qutebrowser/completion/models/miscmodels.py index 6f3db764b..df8b2cdf9 100644 --- a/qutebrowser/completion/models/miscmodels.py +++ b/qutebrowser/completion/models/miscmodels.py @@ -121,4 +121,5 @@ class SessionCompletionModel(base.BaseCompletionModel): super().__init__(parent) cat = self.new_category("Sessions") for name in objreg.get('session-manager').list_sessions(): - self.new_item(cat, name) + if not name.startswith('_'): + self.new_item(cat, name) From 37ab5296a7c2bd9485f88ffec4f71169ab72ac4a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 2 Apr 2015 07:40:00 +0200 Subject: [PATCH 15/69] Adjust URL completion when quickmarks are changed. Fixes #590. --- qutebrowser/browser/quickmarks.py | 12 ++++++ qutebrowser/completion/models/urlmodel.py | 47 +++++++++++++++++++---- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/qutebrowser/browser/quickmarks.py b/qutebrowser/browser/quickmarks.py index b41c9888f..578738ceb 100644 --- a/qutebrowser/browser/quickmarks.py +++ b/qutebrowser/browser/quickmarks.py @@ -43,9 +43,19 @@ class QuickmarkManager(QObject): marks: An OrderedDict of all quickmarks. _lineparser: The LineParser used for the quickmarks, or None (when qutebrowser is started with -c ''). + + Signals: + changed: Emitted when anything changed. + added: Emitted when a new quickmark was added. + arg 0: The name of the quickmark. + arg 1: The URL of the quickmark, as string. + removed: Emitted when an existing quickmark was removed. + arg 0: The name of the quickmark. """ changed = pyqtSignal() + added = pyqtSignal(str, str) + removed = pyqtSignal(str) def __init__(self, parent=None): """Initialize and read quickmarks.""" @@ -117,6 +127,7 @@ class QuickmarkManager(QObject): """Really set the quickmark.""" self.marks[name] = url self.changed.emit() + self.added.emit(name, url) if name in self.marks: message.confirm_async( @@ -138,6 +149,7 @@ class QuickmarkManager(QObject): raise cmdexc.CommandError("Quickmark '{}' not found!".format(name)) else: self.changed.emit() + self.removed.emit(name) def get(self, name): """Get the URL of the quickmark named name as a QUrl.""" diff --git a/qutebrowser/completion/models/urlmodel.py b/qutebrowser/completion/models/urlmodel.py index 100defbf1..e8898ec85 100644 --- a/qutebrowser/completion/models/urlmodel.py +++ b/qutebrowser/completion/models/urlmodel.py @@ -21,7 +21,7 @@ import datetime -from PyQt5.QtCore import pyqtSlot +from PyQt5.QtCore import pyqtSlot, Qt from qutebrowser.utils import objreg, utils from qutebrowser.completion.models import base @@ -42,20 +42,21 @@ class UrlCompletionModel(base.BaseCompletionModel): self._quickmark_cat = self.new_category("Quickmarks") self._history_cat = self.new_category("History") - quickmarks = objreg.get('quickmark-manager').marks.items() - self._history = objreg.get('web-history') - + quickmark_manager = objreg.get('quickmark-manager') + quickmarks = quickmark_manager.marks.items() for qm_name, qm_url in quickmarks: - self.new_item(self._quickmark_cat, qm_url, qm_name) + self._add_quickmark_entry(qm_name, qm_url) + quickmark_manager.added.connect(self.on_quickmark_added) + quickmark_manager.removed.connect(self.on_quickmark_removed) + self._history = objreg.get('web-history') max_history = config.get('completion', 'web-history-max-items') history = utils.newest_slice(self._history, max_history) - for entry in history: self._add_history_entry(entry) - self._history.item_about_to_be_added.connect( self.on_history_item_added) + objreg.get('config').changed.connect(self.reformat_timestamps) def _fmt_atime(self, atime): @@ -71,6 +72,15 @@ class UrlCompletionModel(base.BaseCompletionModel): self._fmt_atime(entry.atime), sort=int(entry.atime), userdata=entry.url) + def _add_quickmark_entry(self, name, url): + """Add a new quickmark entry to the completion. + + Args: + name: The name of the new quickmark. + url: The URL of the new quickmark. + """ + self.new_item(self._quickmark_cat, url, name) + @config.change_filter('completion', 'timestamp-format') def reformat_timestamps(self): """Reformat the timestamps if the config option was changed.""" @@ -93,3 +103,26 @@ class UrlCompletionModel(base.BaseCompletionModel): break else: self._add_history_entry(entry) + + @pyqtSlot(str, str) + def on_quickmark_added(self, name, url): + """Called when a quickmark has been added by the user. + + Args: + name: The name of the new quickmark. + url: The url of the new quickmark, as string. + """ + self._add_quickmark_entry(name, url) + + @pyqtSlot(str) + def on_quickmark_removed(self, name): + """Called when a quickmark has been removed by the user. + + Args: + name: The name of the quickmark which has been removed. + """ + for i in range(self._quickmark_cat.rowCount()): + name_item = self._quickmark_cat.child(i, 1) + if name_item.data(Qt.DisplayRole) == name: + self._quickmark_cat.removeRow(i) + break From 214347497a8da6a7f72f9298eecb4d120283d49d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 2 Apr 2015 07:41:56 +0200 Subject: [PATCH 16/69] Fix handling of first :completion-item-prev call. Before, the first item was unconditionally selected when none was selected before. With :completion-item-prev (e.g. Shift-Tab), it makes more sense to select the *last* one. --- qutebrowser/completion/completionwidget.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qutebrowser/completion/completionwidget.py b/qutebrowser/completion/completionwidget.py index 2c7903509..aa2fd31da 100644 --- a/qutebrowser/completion/completionwidget.py +++ b/qutebrowser/completion/completionwidget.py @@ -151,7 +151,10 @@ class CompletionView(QTreeView): idx = self.selectionModel().currentIndex() if not idx.isValid(): # No item selected yet - return self.model().first_item() + if upwards: + return self.model().last_item() + else: + return self.model().first_item() while True: idx = self.indexAbove(idx) if upwards else self.indexBelow(idx) # wrap around if we arrived at beginning/end From 9f9996bc661a59e98d488068b2867027a2708a57 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 2 Apr 2015 09:09:17 +0200 Subject: [PATCH 17/69] Refuse to add empty URLs to history. --- qutebrowser/browser/history.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qutebrowser/browser/history.py b/qutebrowser/browser/history.py index ea5d6f616..e7be994da 100644 --- a/qutebrowser/browser/history.py +++ b/qutebrowser/browser/history.py @@ -132,6 +132,8 @@ class WebHistory(QWebHistoryInterface): Args: url_string: An url as string to add to the history. """ + if not url_string: + return if not config.get('general', 'private-browsing'): entry = HistoryEntry(time.time(), url_string) self.item_about_to_be_added.emit(entry) From 3d3324ccfaa6475bb5072b68e4000ec45ff3e3ac Mon Sep 17 00:00:00 2001 From: Franz Fellner Date: Thu, 2 Apr 2015 09:04:30 +0200 Subject: [PATCH 18/69] Add TabIndex label to the statusbar. It shows the current tab index and the number of tabs of the windows it sits in. --- qutebrowser/mainwindow/mainwindow.py | 2 ++ qutebrowser/mainwindow/statusbar/bar.py | 5 ++- qutebrowser/mainwindow/statusbar/tabindex.py | 34 ++++++++++++++++++++ qutebrowser/mainwindow/tabwidget.py | 18 +++++++++-- 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 qutebrowser/mainwindow/statusbar/tabindex.py diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py index 3c646e5cf..dbcead867 100644 --- a/qutebrowser/mainwindow/mainwindow.py +++ b/qutebrowser/mainwindow/mainwindow.py @@ -242,6 +242,8 @@ class MainWindow(QWidget): tabs.current_tab_changed.connect(status.percentage.on_tab_changed) tabs.cur_scroll_perc_changed.connect(status.percentage.set_perc) + tabs.tab_index_changed.connect(status.tabindex.on_tab_index_changed) + tabs.current_tab_changed.connect(status.txt.on_tab_changed) tabs.cur_statusbar_message.connect(status.txt.on_statusbar_message) tabs.cur_load_started.connect(status.txt.on_load_started) diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index 8e07db23c..e427de803 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -28,7 +28,7 @@ from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy from qutebrowser.config import config, style from qutebrowser.utils import usertypes, log, objreg, utils from qutebrowser.mainwindow.statusbar import (command, progress, keystring, - percentage, url, prompt) + percentage, url, prompt, tabindex) from qutebrowser.mainwindow.statusbar import text as textwidget @@ -174,6 +174,9 @@ class StatusBar(QWidget): self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) + self.tabindex = tabindex.TabIndex() + self._hbox.addWidget(self.tabindex) + # 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. diff --git a/qutebrowser/mainwindow/statusbar/tabindex.py b/qutebrowser/mainwindow/statusbar/tabindex.py new file mode 100644 index 000000000..519f522ed --- /dev/null +++ b/qutebrowser/mainwindow/statusbar/tabindex.py @@ -0,0 +1,34 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2015 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""TabIndex displayed in the statusbar.""" + +from PyQt5.QtCore import pyqtSlot + +from qutebrowser.mainwindow.statusbar import textbase + + +class TabIndex(textbase.TextBase): + + """Shows current tab index and number of tabs in the statusbar.""" + + @pyqtSlot(int, int) + def on_tab_index_changed(self, current, count): + """Update tab index when tab changed.""" + self.setText('[{}/{}]'.format(current + 1, count)) diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index 590f0e89a..9d4303735 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -26,7 +26,7 @@ Module attributes: import functools -from PyQt5.QtCore import pyqtSlot, Qt, QSize, QRect, QPoint, QTimer +from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QSize, QRect, QPoint, QTimer from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle, QStyle, QStylePainter, QStyleOptionTab) from PyQt5.QtGui import QIcon, QPalette, QColor @@ -41,7 +41,15 @@ PM_TabBarPadding = QStyle.PM_CustomBase class TabWidget(QTabWidget): - """The tab widget used for TabbedBrowser.""" + """The tab widget used for TabbedBrowser. + + Signals: + tab_index_changed: Emitted when the current tab was changed. + arg 0: The index of the tab which is now focused. + arg 1: The total count of tabs. + """ + + tab_index_changed = pyqtSignal(int, int) def __init__(self, win_id, parent=None): super().__init__(parent) @@ -50,6 +58,7 @@ class TabWidget(QTabWidget): bar.tabCloseRequested.connect(self.tabCloseRequested) bar.tabMoved.connect(functools.partial( QTimer.singleShot, 0, self.update_tab_titles)) + bar.currentChanged.connect(self.emit_tab_index_changed) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.setDocumentMode(True) self.setElideMode(Qt.ElideRight) @@ -184,6 +193,11 @@ class TabWidget(QTabWidget): self.set_page_title(new_idx, text) return new_idx + @pyqtSlot(int) + def emit_tab_index_changed(self, index): + """Emit the tab_index_changed signal if the current tab changed.""" + self.tab_index_changed.emit(index, self.count()) + class TabBar(QTabBar): From 84b9d34a7fa6caae54fff3c3697e44bc94d54e7f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 2 Apr 2015 11:57:56 +0200 Subject: [PATCH 19/69] Fix lint. --- qutebrowser/mainwindow/statusbar/bar.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index e427de803..a1c8aabd0 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -28,7 +28,8 @@ from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy from qutebrowser.config import config, style from qutebrowser.utils import usertypes, log, objreg, utils from qutebrowser.mainwindow.statusbar import (command, progress, keystring, - percentage, url, prompt, tabindex) + percentage, url, prompt, + tabindex) from qutebrowser.mainwindow.statusbar import text as textwidget From 009e595780de67f5a57bafef9929dad0339b7814 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 2 Apr 2015 11:58:09 +0200 Subject: [PATCH 20/69] Regenerate authors. --- README.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/README.asciidoc b/README.asciidoc index e7be9b6b1..f445a9c6f 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -157,6 +157,7 @@ Contributors, sorted by the number of commits in descending order: * Helen Sherwood-Taylor * HalosGhost * Gregor Pohl +* Franz Fellner * Eivind Uggedal * Andreas Fischer // QUTE_AUTHORS_END From 953119ef753707c674ecf19e5caa85055e4a1f71 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 2 Apr 2015 14:56:42 +0200 Subject: [PATCH 21/69] Revert "Minor QWebSettings fix." Happy April's fools! This reverts commit a98060e020a4ba83b663813a4b9404edb47f28ad. Conflicts: qutebrowser/app.py qutebrowser/misc/utilcmds.py --- doc/help/commands.asciidoc | 5 ---- qutebrowser/app.py | 10 -------- qutebrowser/config/websettings.py | 38 ++----------------------------- qutebrowser/misc/utilcmds.py | 9 -------- 4 files changed, 2 insertions(+), 60 deletions(-) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 3aafacc74..f75a01d07 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -650,7 +650,6 @@ How many steps to zoom out. |<>|Select the previous completion item. |<>|Enter a key mode. |<>|Follow the currently selected hint. -|<>|Turn off april's fools. |<>|Leave the mode we're currently in. |<>|Open an external editor with the currently selected form field. |<>|Accept the current prompt. @@ -708,10 +707,6 @@ Enter a key mode. === follow-hint Follow the currently selected hint. -[[fooled]] -=== fooled -Turn off april's fools. - [[leave-mode]] === leave-mode Leave the mode we're currently in. diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 4fa429c89..6da5cbe76 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -30,7 +30,6 @@ import base64 import functools import traceback import faulthandler -import datetime import json from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox @@ -162,15 +161,6 @@ class Application(QApplication): if self._crashdlg is not None: self._crashdlg.raise_() - state_config = objreg.get('state-config') - try: - fooled = state_config['general']['fooled'] - except KeyError: - fooled = False - if datetime.date.today() == datetime.date(2015, 4, 1) and not fooled: - message.info('current', "Happy April's fools! Use :fooled to turn " - "this off.") - def __repr__(self): return utils.get_repr(self) diff --git a/qutebrowser/config/websettings.py b/qutebrowser/config/websettings.py index e0d7b7860..61873bd01 100644 --- a/qutebrowser/config/websettings.py +++ b/qutebrowser/config/websettings.py @@ -24,12 +24,9 @@ Module attributes: constants. """ -import base64 -import datetime import os.path from PyQt5.QtWebKit import QWebSettings -from PyQt5.QtCore import QUrl from qutebrowser.config import config from qutebrowser.utils import standarddir, objreg, log, utils, debug @@ -194,22 +191,6 @@ class Setter(Base): self._setter(*args) -class AprilSetter(Setter): - - """Set something... unless it's the 1st of April.""" - - def _set(self, value, qws=None): - state_config = objreg.get('state-config') - try: - fooled = state_config['general']['fooled'] - except KeyError: - fooled = False - if datetime.date.today() == datetime.date(2015, 4, 1) and not fooled: - pass - else: - super()._set(value, qws) - - class NullStringSetter(Setter): """A setter for settings requiring a null QString as default. @@ -336,8 +317,8 @@ MAPPINGS = { 'frame-flattening': Attribute(QWebSettings.FrameFlatteningEnabled), 'user-stylesheet': - AprilSetter(getter=QWebSettings.userStyleSheetUrl, - setter=QWebSettings.setUserStyleSheetUrl), + Setter(getter=QWebSettings.userStyleSheetUrl, + setter=QWebSettings.setUserStyleSheetUrl), 'css-media-type': NullStringSetter(getter=QWebSettings.cssMediaType, setter=QWebSettings.setCSSMediaType), @@ -399,21 +380,6 @@ def init(): QWebSettings.setOfflineStoragePath( os.path.join(standarddir.data(), 'offline-storage')) - state_config = objreg.get('state-config') - try: - fooled = state_config['general']['fooled'] - except KeyError: - fooled = False - if datetime.date.today() == datetime.date(2015, 4, 1) and not fooled: - value = """ - html { - -webkit-transform:rotate(3deg) scale(0.99); - } - """ - data = base64.b64encode(value.encode('utf-8')).decode('ascii') - url = QUrl("data:text/css;charset=utf-8;base64,{}".format(data)) - QWebSettings.globalSettings().setUserStyleSheetUrl(url) - for sectname, section in MAPPINGS.items(): for optname, mapping in section.items(): default = mapping.save_default() diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index 826ea8fc0..5d34af984 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -136,12 +136,3 @@ def debug_trace(expr=""): eval('hunter.trace({})'.format(expr)) except Exception as e: raise cmdexc.CommandError("{}: {}".format(e.__class__.__name__, e)) - - -@cmdutils.register(hide=True) -def fooled(): - """Turn off april's fools.""" - from qutebrowser.config import websettings - state_config = objreg.get('state-config') - state_config['general']['fooled'] = '1' - websettings.update_settings('ui', 'user-stylesheet') From 18b5512fe9fb87f2f80f8b6f48f6f2c0354c1174 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 2 Apr 2015 14:58:34 +0200 Subject: [PATCH 22/69] Remove 'fooled' from state file. --- qutebrowser/config/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 6b7f1f8fb..8fede0160 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -184,6 +184,8 @@ def _init_misc(): state_config.add_section(sect) except configparser.DuplicateSectionError: pass + # See commit a98060e020a4ba83b663813a4b9404edb47f28ad. + state_config['general'].pop('fooled', None) objreg.register('state-config', state_config) save_manager.add_saveable('state-config', state_config.save) From 1dcc5a32d67fbab085c6f8d95c7deb2289c2bc83 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 14:14:20 +0200 Subject: [PATCH 23/69] Correct keybindings to deprecated commands. Needed for #564 (because of :search ""). Also see #525. --- qutebrowser/config/configdata.py | 11 +++++++++++ qutebrowser/config/parsers/keyconf.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 7a561bf93..21873116c 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1179,3 +1179,14 @@ KEY_DATA = collections.OrderedDict([ ('rl-backward-delete-char', ['']), ])), ]) + + +# A dict of {old_cmd: new_cmd} strings. + +CHANGED_KEY_COMMNADS = { + 'open -t about:blank': 'open -t', + 'open -b about:blank': 'open -b', + 'open -w about:blank': 'open -w', + 'download-page': 'download', + 'cancel-download': 'download-cancel', +} diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index 2a792fb89..006923bd8 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -255,7 +255,7 @@ class KeyConfigParser(QObject): command = line.split(maxsplit=1)[0] if command not in cmdutils.cmd_dict: raise KeyConfigError("Invalid command '{}'!".format(command)) - self._cur_command = line + self._cur_command = configdata.CHANGED_KEY_COMMNADS.get(line, line) def _read_keybinding(self, line): """Read a key binding from a line.""" From 4e0712622bcdcc30c5eb007760a5400675f3e0b2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 14:39:47 +0200 Subject: [PATCH 24/69] Clear search when :search without args is given. Needed for #564 because :search "" won't work anymore. --- doc/help/commands.asciidoc | 6 +++--- qutebrowser/commands/runners.py | 4 ++-- qutebrowser/config/configdata.py | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index f75a01d07..3ad152b21 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -35,7 +35,7 @@ |<>|Report a bug in qutebrowser. |<>|Restart qutebrowser while keeping existing tabs open. |<>|Save configs and state. -|<>|Search for a text on the current page. +|<>|Search for a text on the current page. With no text, clear results. |<>|Delete a session. |<>|Load a session. |<>|Save a session. @@ -394,9 +394,9 @@ Save configs and state. [[search]] === search -Syntax: +:search [*--reverse*] 'text'+ +Syntax: +:search [*--reverse*] ['text']+ -Search for a text on the current page. +Search for a text on the current page. With no text, clear results. ==== positional arguments * +'text'+: The text to search for. diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index e8f6917e4..ae5ad1ded 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -79,8 +79,8 @@ class SearchRunner(QObject): @pyqtSlot(str) @cmdutils.register(instance='search-runner', scope='window', maxsplit=0) - def search(self, text, reverse=False): - """Search for a text on the current page. + def search(self, text="", reverse=False): + """Search for a text on the current page. With no text, clear results. Args: text: The text to search for. diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 21873116c..d4580737c 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1189,4 +1189,5 @@ CHANGED_KEY_COMMNADS = { 'open -w about:blank': 'open -w', 'download-page': 'download', 'cancel-download': 'download-cancel', + 'search ""': 'search', } From 7e51addeb04e1d14c48917ebfb0fea90343a41fd Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 14:42:19 +0200 Subject: [PATCH 25/69] Fix :set-cmd-text with empty argument. --- qutebrowser/mainwindow/statusbar/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/mainwindow/statusbar/command.py b/qutebrowser/mainwindow/statusbar/command.py index d5d8e1196..38457b08b 100644 --- a/qutebrowser/mainwindow/statusbar/command.py +++ b/qutebrowser/mainwindow/statusbar/command.py @@ -127,7 +127,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit): # I'm not sure what's the best thing to do here # https://github.com/The-Compiler/qutebrowser/issues/123 text = text.replace('{url}', url) - if not text[0] in modeparsers.STARTCHARS: + if not text or text[0] not in modeparsers.STARTCHARS: raise cmdexc.CommandError( "Invalid command text '{}'.".format(text)) self.set_cmd_text(text) From 64b1b48be6c81c5911ce4b084641709a4ade586e Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 10:39:01 +0200 Subject: [PATCH 26/69] Extract test_no_metaobj to separate module --- qutebrowser/test/utils/test_debug.py | 9 ------ .../test/utils/test_debug/test_qenum_key.py | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 qutebrowser/test/utils/test_debug/test_qenum_key.py diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index b21db3fb0..a60f478ec 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -35,15 +35,6 @@ class QEnumKeyTests(unittest.TestCase): """Tests for qenum_key.""" - def test_no_metaobj(self): - """Test with an enum with no meta-object.""" - with self.assertRaises(AttributeError): - # Make sure it doesn't have a meta object - # pylint: disable=pointless-statement,no-member - QStyle.PrimitiveElement.staticMetaObject - key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand) - self.assertEqual(key, 'PE_PanelButtonCommand') - def test_metaobj(self): """Test with an enum with meta-object.""" # pylint: disable=pointless-statement diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/test_debug/test_qenum_key.py new file mode 100644 index 000000000..3af0c2c1b --- /dev/null +++ b/qutebrowser/test/utils/test_debug/test_qenum_key.py @@ -0,0 +1,30 @@ +# Copyright 2014-2015 Florian Bruhin (The Compiler) +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Tests for qutebrowser.utils.debug.""" + + +def test_no_metaobj(self): + """Test with an enum with no meta-object.""" + with self.assertRaises(AttributeError): + # Make sure it doesn't have a meta object + # pylint: disable=pointless-statement,no-member + QStyle.PrimitiveElement.staticMetaObject + key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand) + self.assertEqual(key, 'PE_PanelButtonCommand') From d4d14598ddb68fe5b89aa3ec67bb2e38455dc1cb Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 10:46:14 +0200 Subject: [PATCH 27/69] Convert test_no_metaobj --- .../test/utils/test_debug/test_qenum_key.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/test_debug/test_qenum_key.py index 3af0c2c1b..e488e06ad 100644 --- a/qutebrowser/test/utils/test_debug/test_qenum_key.py +++ b/qutebrowser/test/utils/test_debug/test_qenum_key.py @@ -19,12 +19,20 @@ """Tests for qutebrowser.utils.debug.""" +import pytest -def test_no_metaobj(self): +from PyQt5.QtWidgets import QStyle + +from qutebrowser.utils import debug + + +def test_no_metaobj(): """Test with an enum with no meta-object.""" - with self.assertRaises(AttributeError): + + with pytest.raises(AttributeError): # Make sure it doesn't have a meta object # pylint: disable=pointless-statement,no-member QStyle.PrimitiveElement.staticMetaObject + key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand) - self.assertEqual(key, 'PE_PanelButtonCommand') + assert key == 'PE_PanelButtonCommand' From 11ded52f06ddeb2b20c415b35f74ef6ebf3141ae Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 10:48:54 +0200 Subject: [PATCH 28/69] Convert test_metaobj --- qutebrowser/test/utils/test_debug.py | 7 ------- qutebrowser/test/utils/test_debug/test_qenum_key.py | 12 +++++++++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index a60f478ec..09eae4fdb 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -35,13 +35,6 @@ class QEnumKeyTests(unittest.TestCase): """Tests for qenum_key.""" - def test_metaobj(self): - """Test with an enum with meta-object.""" - # pylint: disable=pointless-statement - QFrame.staticMetaObject # make sure it has a meta-object - key = debug.qenum_key(QFrame, QFrame.Sunken) - self.assertEqual(key, 'Sunken') - def test_add_base(self): """Test with add_base=True.""" key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True) diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/test_debug/test_qenum_key.py index e488e06ad..183ec1622 100644 --- a/qutebrowser/test/utils/test_debug/test_qenum_key.py +++ b/qutebrowser/test/utils/test_debug/test_qenum_key.py @@ -21,7 +21,7 @@ import pytest -from PyQt5.QtWidgets import QStyle +from PyQt5.QtWidgets import QStyle, QFrame from qutebrowser.utils import debug @@ -36,3 +36,13 @@ def test_no_metaobj(): key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand) assert key == 'PE_PanelButtonCommand' + + +def test_metaobj(): + """Test with an enum with meta-object.""" + + # pylint: disable=pointless-statement + QFrame.staticMetaObject # make sure it has a meta-object + key = debug.qenum_key(QFrame, QFrame.Sunken) + + assert key == 'Sunken' From df3096fbb50deb05cdc1be13c0f2eddf3fc88370 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 10:56:24 +0200 Subject: [PATCH 29/69] Convert test_add_base --- qutebrowser/test/utils/test_debug.py | 5 ----- qutebrowser/test/utils/test_debug/test_qenum_key.py | 9 ++++++++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 09eae4fdb..4f1418405 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -35,11 +35,6 @@ class QEnumKeyTests(unittest.TestCase): """Tests for qenum_key.""" - def test_add_base(self): - """Test with add_base=True.""" - key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True) - self.assertEqual(key, 'QFrame.Sunken') - def test_int_noklass(self): """Test passing an int without explicit klass given.""" with self.assertRaises(TypeError): diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/test_debug/test_qenum_key.py index 183ec1622..00cc572a7 100644 --- a/qutebrowser/test/utils/test_debug/test_qenum_key.py +++ b/qutebrowser/test/utils/test_debug/test_qenum_key.py @@ -43,6 +43,13 @@ def test_metaobj(): # pylint: disable=pointless-statement QFrame.staticMetaObject # make sure it has a meta-object - key = debug.qenum_key(QFrame, QFrame.Sunken) + key = debug.qenum_key(QFrame, QFrame.Sunken) assert key == 'Sunken' + + +def test_add_base(): + """Test with add_base=True.""" + + key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True) + assert key == 'QFrame.Sunken' From 9e59108788529297e91164b2e2bbe9c0d67cc9a6 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 10:58:54 +0200 Subject: [PATCH 30/69] Convert test_int_noklass --- qutebrowser/test/utils/test_debug.py | 5 ----- qutebrowser/test/utils/test_debug/test_qenum_key.py | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 4f1418405..1a0561c65 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -35,11 +35,6 @@ class QEnumKeyTests(unittest.TestCase): """Tests for qenum_key.""" - def test_int_noklass(self): - """Test passing an int without explicit klass given.""" - with self.assertRaises(TypeError): - debug.qenum_key(QFrame, 42) - def test_int(self): """Test passing an int with explicit klass given.""" key = debug.qenum_key(QFrame, 0x0030, klass=QFrame.Shadow) diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/test_debug/test_qenum_key.py index 00cc572a7..3680f07c6 100644 --- a/qutebrowser/test/utils/test_debug/test_qenum_key.py +++ b/qutebrowser/test/utils/test_debug/test_qenum_key.py @@ -53,3 +53,10 @@ def test_add_base(): key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True) assert key == 'QFrame.Sunken' + + +def test_int_noklass(): + """Test passing an int without explicit klass given.""" + + with pytest.raises(TypeError): + debug.qenum_key(QFrame, 42) From 1b476d9af7efd6970d565b514f6a152d00e8055f Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 11:00:56 +0200 Subject: [PATCH 31/69] Convert test_int --- qutebrowser/test/utils/test_debug.py | 5 ----- qutebrowser/test/utils/test_debug/test_qenum_key.py | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 1a0561c65..e0a6fcd7f 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -35,11 +35,6 @@ class QEnumKeyTests(unittest.TestCase): """Tests for qenum_key.""" - def test_int(self): - """Test passing an int with explicit klass given.""" - key = debug.qenum_key(QFrame, 0x0030, klass=QFrame.Shadow) - self.assertEqual(key, 'Sunken') - def test_unknown(self): """Test passing an unknown value.""" key = debug.qenum_key(QFrame, 0x1337, klass=QFrame.Shadow) diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/test_debug/test_qenum_key.py index 3680f07c6..63379ee6c 100644 --- a/qutebrowser/test/utils/test_debug/test_qenum_key.py +++ b/qutebrowser/test/utils/test_debug/test_qenum_key.py @@ -60,3 +60,10 @@ def test_int_noklass(): with pytest.raises(TypeError): debug.qenum_key(QFrame, 42) + + +def test_int(): + """Test passing an int with explicit klass given.""" + + key = debug.qenum_key(QFrame, 0x0030, klass=QFrame.Shadow) + assert key == 'Sunken' From 6b7ae70e6d5e4911277decfd95cb6945a8efa801 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 11:04:30 +0200 Subject: [PATCH 32/69] Convert test_unknown --- qutebrowser/test/utils/test_debug.py | 5 ----- qutebrowser/test/utils/test_debug/test_qenum_key.py | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index e0a6fcd7f..daad21005 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -35,11 +35,6 @@ class QEnumKeyTests(unittest.TestCase): """Tests for qenum_key.""" - def test_unknown(self): - """Test passing an unknown value.""" - key = debug.qenum_key(QFrame, 0x1337, klass=QFrame.Shadow) - self.assertEqual(key, '0x1337') - def test_reconverted(self): """Test passing a flag value which was re-converted to an enum.""" # FIXME maybe this should return the right thing anyways? diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/test_debug/test_qenum_key.py index 63379ee6c..09711b7ea 100644 --- a/qutebrowser/test/utils/test_debug/test_qenum_key.py +++ b/qutebrowser/test/utils/test_debug/test_qenum_key.py @@ -67,3 +67,10 @@ def test_int(): key = debug.qenum_key(QFrame, 0x0030, klass=QFrame.Shadow) assert key == 'Sunken' + + +def test_unknown(): + """Test passing an unknown value.""" + + key = debug.qenum_key(QFrame, 0x1337, klass=QFrame.Shadow) + assert key == '0x1337' From b938318d5fdeb925c4903876f8ba9f80b7e9fae0 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 11:11:21 +0200 Subject: [PATCH 33/69] Remove former unittest class and skip test_reconverted --- qutebrowser/test/utils/test_debug.py | 10 ---------- qutebrowser/test/utils/test_debug/test_qenum_key.py | 12 +++++++++++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index daad21005..36d261297 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -31,16 +31,6 @@ from qutebrowser.utils import debug from qutebrowser.test import stubs -class QEnumKeyTests(unittest.TestCase): - - """Tests for qenum_key.""" - - def test_reconverted(self): - """Test passing a flag value which was re-converted to an enum.""" - # FIXME maybe this should return the right thing anyways? - debug.qenum_key(Qt, Qt.Alignment(int(Qt.AlignLeft))) - - class QFlagsKeyTests(unittest.TestCase): """Tests for qflags_key().""" diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/test_debug/test_qenum_key.py index 09711b7ea..f98c58c34 100644 --- a/qutebrowser/test/utils/test_debug/test_qenum_key.py +++ b/qutebrowser/test/utils/test_debug/test_qenum_key.py @@ -17,10 +17,11 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Tests for qutebrowser.utils.debug.""" +"""Tests for qutebrowser.utils.debug.qenum_key.""" import pytest +from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QStyle, QFrame from qutebrowser.utils import debug @@ -74,3 +75,12 @@ def test_unknown(): key = debug.qenum_key(QFrame, 0x1337, klass=QFrame.Shadow) assert key == '0x1337' + + +def test_reconverted(): + """Test passing a flag value which was re-converted to an enum.""" + + pytest.skip(msg="It is not clear what this test is supposed to do") + + # FIXME maybe this should return the right thing anyways? + debug.qenum_key(Qt, Qt.Alignment(int(Qt.AlignLeft))) From 96a600e9dc88cc10a92ee9c23944949c2c0288a0 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 16:37:31 +0200 Subject: [PATCH 34/69] Change containing directory name to debug --- qutebrowser/test/utils/{test_debug => debug}/test_qenum_key.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename qutebrowser/test/utils/{test_debug => debug}/test_qenum_key.py (100%) diff --git a/qutebrowser/test/utils/test_debug/test_qenum_key.py b/qutebrowser/test/utils/debug/test_qenum_key.py similarity index 100% rename from qutebrowser/test/utils/test_debug/test_qenum_key.py rename to qutebrowser/test/utils/debug/test_qenum_key.py From 9a478487940478edd6bc41034d88c02617c84ffe Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 18:22:13 +0200 Subject: [PATCH 35/69] Create a new module and convert test_single --- .../test/utils/debug/test_qflags_key.py | 33 +++++++++++++++++++ qutebrowser/test/utils/test_debug.py | 6 ---- 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 qutebrowser/test/utils/debug/test_qflags_key.py diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py new file mode 100644 index 000000000..8b0116812 --- /dev/null +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -0,0 +1,33 @@ +# Copyright 2014-2015 Florian Bruhin (The Compiler) +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Tests for qutebrowser.utils.debug.qflags_key.""" + +import pytest + +from PyQt5.QtCore import Qt +from qutebrowser.utils import debug + + +@pytest.mark.xfail(reason="Broken but shouldn't generate a failure") +def test_single(): + """Test with single value.""" + + flags = debug.qflags_key(Qt, Qt.AlignTop) + assert flags == 'AlignTop' diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 36d261297..4f1262caa 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -37,12 +37,6 @@ class QFlagsKeyTests(unittest.TestCase): # https://github.com/The-Compiler/qutebrowser/issues/42 - @unittest.skip('FIXME') - def test_single(self): - """Test with single value.""" - flags = debug.qflags_key(Qt, Qt.AlignTop) - self.assertEqual(flags, 'AlignTop') - @unittest.skip('FIXME') def test_multiple(self): """Test with multiple values.""" From f68cfc13e02632ad17b6e4b462497248893ea7bf Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 18:25:28 +0200 Subject: [PATCH 36/69] Convert test_multiple and use custom xfail marker --- qutebrowser/test/utils/debug/test_qflags_key.py | 13 ++++++++++++- qutebrowser/test/utils/test_debug.py | 6 ------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py index 8b0116812..f5214f3e0 100644 --- a/qutebrowser/test/utils/debug/test_qflags_key.py +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -25,9 +25,20 @@ from PyQt5.QtCore import Qt from qutebrowser.utils import debug -@pytest.mark.xfail(reason="Broken but shouldn't generate a failure") +fixme = pytest.mark.xfail(reason="Broken but shouldn't generate a failure") + + +@fixme def test_single(): """Test with single value.""" flags = debug.qflags_key(Qt, Qt.AlignTop) assert flags == 'AlignTop' + + +@fixme +def test_multiple(): + """Test with multiple values.""" + + flags = debug.qflags_key(Qt, Qt.AlignLeft | Qt.AlignTop) + assert flags == 'AlignLeft|AlignTop' diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 4f1262caa..05a8e1eb2 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -37,12 +37,6 @@ class QFlagsKeyTests(unittest.TestCase): # https://github.com/The-Compiler/qutebrowser/issues/42 - @unittest.skip('FIXME') - def test_multiple(self): - """Test with multiple values.""" - flags = debug.qflags_key(Qt, Qt.AlignLeft | Qt.AlignTop) - self.assertEqual(flags, 'AlignLeft|AlignTop') - def test_combined(self): """Test with a combined value.""" flags = debug.qflags_key(Qt, Qt.AlignCenter) From 6482025399062e68e77cae05afcec42816495478 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 18:29:33 +0200 Subject: [PATCH 37/69] Convert test_combined --- qutebrowser/test/utils/debug/test_qflags_key.py | 7 +++++++ qutebrowser/test/utils/test_debug.py | 5 ----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py index f5214f3e0..2007c85b0 100644 --- a/qutebrowser/test/utils/debug/test_qflags_key.py +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -42,3 +42,10 @@ def test_multiple(): flags = debug.qflags_key(Qt, Qt.AlignLeft | Qt.AlignTop) assert flags == 'AlignLeft|AlignTop' + + +def test_combined(): + """Test with a combined value.""" + + flags = debug.qflags_key(Qt, Qt.AlignCenter) + assert flags == 'AlignHCenter|AlignVCenter' diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 05a8e1eb2..078e83c07 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -37,11 +37,6 @@ class QFlagsKeyTests(unittest.TestCase): # https://github.com/The-Compiler/qutebrowser/issues/42 - def test_combined(self): - """Test with a combined value.""" - flags = debug.qflags_key(Qt, Qt.AlignCenter) - self.assertEqual(flags, 'AlignHCenter|AlignVCenter') - @unittest.skip('FIXME') def test_add_base(self): """Test with add_base=True.""" From 75e927f79ede6dc22170cf731bba321d0e0e8c29 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 18:33:22 +0200 Subject: [PATCH 38/69] Convert test_add_base --- qutebrowser/test/utils/debug/test_qflags_key.py | 8 ++++++++ qutebrowser/test/utils/test_debug.py | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py index 2007c85b0..3f69a1158 100644 --- a/qutebrowser/test/utils/debug/test_qflags_key.py +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -49,3 +49,11 @@ def test_combined(): flags = debug.qflags_key(Qt, Qt.AlignCenter) assert flags == 'AlignHCenter|AlignVCenter' + + +@fixme +def test_add_base(): + """Test with add_base=True.""" + + flags = debug.qflags_key(Qt, Qt.AlignTop, add_base=True) + assert flags == 'Qt.AlignTop' diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 078e83c07..beb6efd1c 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -37,12 +37,6 @@ class QFlagsKeyTests(unittest.TestCase): # https://github.com/The-Compiler/qutebrowser/issues/42 - @unittest.skip('FIXME') - def test_add_base(self): - """Test with add_base=True.""" - flags = debug.qflags_key(Qt, Qt.AlignTop, add_base=True) - self.assertEqual(flags, 'Qt.AlignTop') - def test_int_noklass(self): """Test passing an int without explicit klass given.""" with self.assertRaises(TypeError): From 086f12600c8f84be8b60358dae13cfedf34c4208 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 18:37:12 +0200 Subject: [PATCH 39/69] Convert test_int_noklass --- qutebrowser/test/utils/debug/test_qflags_key.py | 7 +++++++ qutebrowser/test/utils/test_debug.py | 5 ----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py index 3f69a1158..de1d0e49c 100644 --- a/qutebrowser/test/utils/debug/test_qflags_key.py +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -57,3 +57,10 @@ def test_add_base(): flags = debug.qflags_key(Qt, Qt.AlignTop, add_base=True) assert flags == 'Qt.AlignTop' + + +def test_int_noklass(): + """Test passing an int without explicit klass given.""" + + with pytest.raises(TypeError): + debug.qflags_key(Qt, 42) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index beb6efd1c..0f453f1c1 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -37,11 +37,6 @@ class QFlagsKeyTests(unittest.TestCase): # https://github.com/The-Compiler/qutebrowser/issues/42 - def test_int_noklass(self): - """Test passing an int without explicit klass given.""" - with self.assertRaises(TypeError): - debug.qflags_key(Qt, 42) - @unittest.skip('FIXME') def test_int(self): """Test passing an int with explicit klass given.""" From ff75d18e624844e0fcbc04d7e2332f30bb459990 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 18:40:41 +0200 Subject: [PATCH 40/69] Convert test_int --- qutebrowser/test/utils/debug/test_qflags_key.py | 7 +++++++ qutebrowser/test/utils/test_debug.py | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py index de1d0e49c..f2c4ecef3 100644 --- a/qutebrowser/test/utils/debug/test_qflags_key.py +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -64,3 +64,10 @@ def test_int_noklass(): with pytest.raises(TypeError): debug.qflags_key(Qt, 42) + +@fixme +def test_int(): + """Test passing an int with explicit klass given.""" + + flags = debug.qflags_key(Qt, 0x0021, klass=Qt.Alignment) + assert flags == 'AlignLeft|AlignTop' diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 0f453f1c1..23d05b8ee 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -37,12 +37,6 @@ class QFlagsKeyTests(unittest.TestCase): # https://github.com/The-Compiler/qutebrowser/issues/42 - @unittest.skip('FIXME') - def test_int(self): - """Test passing an int with explicit klass given.""" - flags = debug.qflags_key(Qt, 0x0021, klass=Qt.Alignment) - self.assertEqual(flags, 'AlignLeft|AlignTop') - def test_unknown(self): """Test passing an unknown value.""" flags = debug.qflags_key(Qt, 0x1100, klass=Qt.Alignment) From 0b063ab4b42837e561c2d498ba03741b6b14f42c Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 18:51:40 +0200 Subject: [PATCH 41/69] Convert test_unknown --- qutebrowser/test/utils/debug/test_qflags_key.py | 12 +++++++++++- qutebrowser/test/utils/test_debug.py | 12 ------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py index f2c4ecef3..fecc808ce 100644 --- a/qutebrowser/test/utils/debug/test_qflags_key.py +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -17,7 +17,10 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Tests for qutebrowser.utils.debug.qflags_key.""" +"""Tests for qutebrowser.utils.debug.qflags_key. + +https://github.com/The-Compiler/qutebrowser/issues/42 +""" import pytest @@ -65,9 +68,16 @@ def test_int_noklass(): with pytest.raises(TypeError): debug.qflags_key(Qt, 42) + @fixme def test_int(): """Test passing an int with explicit klass given.""" flags = debug.qflags_key(Qt, 0x0021, klass=Qt.Alignment) assert flags == 'AlignLeft|AlignTop' + + +def test_unknown(): + """Test passing an unknown value.""" + flags = debug.qflags_key(Qt, 0x1100, klass=Qt.Alignment) + assert flags == '0x0100|0x1000' diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 23d05b8ee..737763044 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -31,18 +31,6 @@ from qutebrowser.utils import debug from qutebrowser.test import stubs -class QFlagsKeyTests(unittest.TestCase): - - """Tests for qflags_key().""" - - # https://github.com/The-Compiler/qutebrowser/issues/42 - - def test_unknown(self): - """Test passing an unknown value.""" - flags = debug.qflags_key(Qt, 0x1100, klass=Qt.Alignment) - self.assertEqual(flags, '0x0100|0x1000') - - class TestDebug(unittest.TestCase): """Test signal debug output functions.""" From 5b372aeee0e81b94652702f08afb5d9dce1fe90f Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 18:55:24 +0200 Subject: [PATCH 42/69] Remove blank lines in test_qflags_key --- qutebrowser/test/utils/debug/test_qflags_key.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py index fecc808ce..371efdeff 100644 --- a/qutebrowser/test/utils/debug/test_qflags_key.py +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -34,7 +34,6 @@ fixme = pytest.mark.xfail(reason="Broken but shouldn't generate a failure") @fixme def test_single(): """Test with single value.""" - flags = debug.qflags_key(Qt, Qt.AlignTop) assert flags == 'AlignTop' @@ -42,14 +41,12 @@ def test_single(): @fixme def test_multiple(): """Test with multiple values.""" - flags = debug.qflags_key(Qt, Qt.AlignLeft | Qt.AlignTop) assert flags == 'AlignLeft|AlignTop' def test_combined(): """Test with a combined value.""" - flags = debug.qflags_key(Qt, Qt.AlignCenter) assert flags == 'AlignHCenter|AlignVCenter' @@ -57,14 +54,12 @@ def test_combined(): @fixme def test_add_base(): """Test with add_base=True.""" - flags = debug.qflags_key(Qt, Qt.AlignTop, add_base=True) assert flags == 'Qt.AlignTop' def test_int_noklass(): """Test passing an int without explicit klass given.""" - with pytest.raises(TypeError): debug.qflags_key(Qt, 42) @@ -72,7 +67,6 @@ def test_int_noklass(): @fixme def test_int(): """Test passing an int with explicit klass given.""" - flags = debug.qflags_key(Qt, 0x0021, klass=Qt.Alignment) assert flags == 'AlignLeft|AlignTop' From 0b26e295bc22644a0c25041bdc3f64721ee220a5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 14:44:44 +0200 Subject: [PATCH 43/69] Revert fixes for quotes/spaces in maxsplit cmds. Revert "Fix maxsplit-splitting with empty args (""/'')." This reverts commit 46396cce1e45001bfbb2aa81abafdcfed89af3f6. Revert "Remove quotes with split=False commands." This reverts commit 81bc5dae94adcc35eb9e9b979d710c4faf573d29. See #564 and #453. --- qutebrowser/commands/runners.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index ae5ad1ded..478bf87df 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -19,8 +19,6 @@ """Module containing command managers (SearchRunner and CommandRunner).""" -import re - from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QUrl from PyQt5.QtWebKitWidgets import QWebPage @@ -266,16 +264,8 @@ class CommandRunner(QObject): else: self._args = [] maxsplit = i + self._cmd.maxsplit + flag_arg_count - args = split.simple_split(argstr, keep=keep, - maxsplit=maxsplit) - for s in args: - # remove quotes and replace \" by " - if s == '""' or s == "''": - s = '' - else: - s = re.sub(r"""(^|[^\\])["']""", r'\1', s) - s = re.sub(r"""\\(["'])""", r'\1', s) - self._args.append(s) + self._args = split.simple_split(argstr, keep=keep, + maxsplit=maxsplit) break else: # If there are only flags, we got it right on the first try From a504bd14366c15b0c2b495cd9fde8fb4714303b8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 18:58:22 +0200 Subject: [PATCH 44/69] Don't quote completions for maxsplit-commands. Fixes #564. Obsoletes #313 and #453. --- qutebrowser/completion/completer.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py index 368026aba..169465cd3 100644 --- a/qutebrowser/completion/completer.py +++ b/qutebrowser/completion/completer.py @@ -196,7 +196,13 @@ class Completer(QObject): data = model.data(indexes[0]) if data is None: return - data = self._quote(data) + parts = self.split() + try: + needs_quoting = cmdutils.cmd_dict[parts[0]].maxsplit is None + except KeyError: + needs_quoting = True + if needs_quoting: + data = self._quote(data) if model.count() == 1 and config.get('completion', 'quick-complete'): # If we only have one item, we want to apply it immediately # and go on to the next part. From 630a827afcb4aaa077e986f0a583ba8308b7e33f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 16:12:33 +0200 Subject: [PATCH 45/69] Change CHANGED_KEY_COMMANDS to be regexes. Break after first regex --- qutebrowser/config/configdata.py | 17 ++++++++--------- qutebrowser/config/parsers/keyconf.py | 6 +++++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index d4580737c..be45e9782 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1181,13 +1181,12 @@ KEY_DATA = collections.OrderedDict([ ]) -# A dict of {old_cmd: new_cmd} strings. +# A list of (regex, replacement) tuples of changed key commands. -CHANGED_KEY_COMMNADS = { - 'open -t about:blank': 'open -t', - 'open -b about:blank': 'open -b', - 'open -w about:blank': 'open -w', - 'download-page': 'download', - 'cancel-download': 'download-cancel', - 'search ""': 'search', -} +CHANGED_KEY_COMMANDS = [ + (re.compile(r'^open -([twb]) about:blank$'), r'open -\1'), + (re.compile(r'^download-page$'), r'download'), + (re.compile(r'^cancel-download$'), r'download-cancel'), + (re.compile(r'^search ""$'), r'search'), + (re.compile(r"^search ''$"), r'search'), +] diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index 006923bd8..dd4fdf673 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -255,7 +255,11 @@ class KeyConfigParser(QObject): command = line.split(maxsplit=1)[0] if command not in cmdutils.cmd_dict: raise KeyConfigError("Invalid command '{}'!".format(command)) - self._cur_command = configdata.CHANGED_KEY_COMMNADS.get(line, line) + for rgx, repl in configdata.CHANGED_KEY_COMMANDS: + if rgx.match(line): + line = rgx.sub(repl, line) + break + self._cur_command = line def _read_keybinding(self, line): """Read a key binding from a line.""" From ac63fc073f3db9742095243d2e73a5887cf9bee6 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 16:57:42 +0200 Subject: [PATCH 46/69] save: Add possibility to mark things dirty on add. KeyConfig needs this feature, because it can fix some deprecated commands during __init__ and emit its dirty-signal, but that happens before the saveable is added. --- qutebrowser/misc/savemanager.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/qutebrowser/misc/savemanager.py b/qutebrowser/misc/savemanager.py index f55387542..3a7772b1c 100644 --- a/qutebrowser/misc/savemanager.py +++ b/qutebrowser/misc/savemanager.py @@ -22,7 +22,7 @@ import os.path import collections -from PyQt5.QtCore import pyqtSlot, QObject +from PyQt5.QtCore import pyqtSlot, QObject, QTimer from qutebrowser.config import config from qutebrowser.commands import cmdutils @@ -139,7 +139,7 @@ class SaveManager(QObject): self._save_timer.start() def add_saveable(self, name, save, changed=None, config_opt=None, - filename=None): + filename=None, dirty=False): """Add a new saveable. Args: @@ -150,11 +150,15 @@ class SaveManager(QObject): or not. filename: The filename of the underlying file, so we can force saving if it doesn't exist. + dirty: Whether the saveable is already dirty. """ if name in self.saveables: raise ValueError("Saveable {} already registered!".format(name)) - self.saveables[name] = Saveable(name, save, changed, config_opt, - filename) + saveable = Saveable(name, save, changed, config_opt, filename) + self.saveables[name] = saveable + if dirty: + saveable.mark_dirty() + QTimer.singleShot(0, saveable.save) def save(self, name, is_exit=False, explicit=False, silent=False, force=False): From 3b3b55234b0c6bf7f4d5e9a6fd7912a003dc1413 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 16:43:49 +0200 Subject: [PATCH 47/69] Add a signal to KeyConfigParser to save config. Before, we used the 'changed' signal for the SaveManager - however, that also was emitted when only the internal structure changed. Now we add a new signal for that. --- qutebrowser/config/config.py | 5 +++-- qutebrowser/config/parsers/keyconf.py | 14 +++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 8fede0160..d7716db97 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -171,8 +171,9 @@ def _init_key_config(): save_manager = objreg.get('save-manager') filename = os.path.join(standarddir.config(), 'keys.conf') save_manager.add_saveable( - 'key-config', key_config.save, key_config.changed, - config_opt=('general', 'auto-save-config'), filename=filename) + 'key-config', key_config.save, key_config.config_dirty, + config_opt=('general', 'auto-save-config'), filename=filename, + dirty=key_config.is_dirty) def _init_misc(): diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index dd4fdf673..5487afb11 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -55,13 +55,16 @@ class KeyConfigParser(QObject): _configfile: The filename of the config or None. _cur_section: The section currently being processed by _read(). _cur_command: The command currently being processed by _read(). + is_dirty: Whether the config is currently dirty. Signals: - changed: Emitted when the config has changed. + changed: Emitted when the internal data has changed. arg: Name of the mode which was changed. + config_dirty: Emitted when the config should be re-saved. """ changed = pyqtSignal(str) + config_dirty = pyqtSignal() def __init__(self, configdir, fname, parent=None): """Constructor. @@ -71,6 +74,7 @@ class KeyConfigParser(QObject): fname: The filename of the config. """ super().__init__(parent) + self.is_dirty = False self._cur_section = None self._cur_command = None # Mapping of section name(s) to key binding -> command dicts. @@ -165,6 +169,7 @@ class KeyConfigParser(QObject): raise cmdexc.CommandError(e) for m in mode.split(','): self.changed.emit(m) + self._mark_config_dirty() @cmdutils.register(instance='key-config') def unbind(self, key, mode=None): @@ -194,6 +199,7 @@ class KeyConfigParser(QObject): else: for m in mode.split(','): self.changed.emit(m) + self._mark_config_dirty() def _normalize_sectname(self, s): """Normalize a section string like 'foo, bar,baz' to 'bar,baz,foo'.""" @@ -246,6 +252,11 @@ class KeyConfigParser(QObject): for sectname in self.keybindings: self.changed.emit(sectname) + def _mark_config_dirty(self): + """Mark the config as dirty.""" + self.is_dirty = True + self.config_dirty.emit() + def _read_command(self, line): """Read a command from a line.""" if self._cur_section is None: @@ -258,6 +269,7 @@ class KeyConfigParser(QObject): for rgx, repl in configdata.CHANGED_KEY_COMMANDS: if rgx.match(line): line = rgx.sub(repl, line) + self._mark_config_dirty() break self._cur_command = line From 6917c3b32da179fd29ac374d4b3324e81193edc7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 17:10:14 +0200 Subject: [PATCH 48/69] set-cmd-text: Add -s/--space argument. We need this because quotes are ignored now, so there'd be no way to set the text to ":open -t " for example. --- doc/help/commands.asciidoc | 5 ++++- qutebrowser/config/configdata.py | 18 ++++++++++-------- qutebrowser/mainwindow/statusbar/command.py | 5 ++++- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 3ad152b21..1e592cb61 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -463,13 +463,16 @@ If the option name ends with '?', the value of the option is shown instead. If t [[set-cmd-text]] === set-cmd-text -Syntax: +:set-cmd-text 'text'+ +Syntax: +:set-cmd-text [*--space*] 'text'+ Preset the statusbar to some text. ==== positional arguments * +'text'+: The commandline to set. +==== optional arguments +* +*-s*+, +*--space*+: If given, a space is added to the end. + [[spawn]] === spawn Syntax: +:spawn [*--userscript*] 'args' ['args' ...]+ diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index be45e9782..6807447be 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1029,14 +1029,14 @@ KEY_DATA = collections.OrderedDict([ ('normal', collections.OrderedDict([ ('search ""', ['']), - ('set-cmd-text ":open "', ['o']), - ('set-cmd-text ":open {url}"', ['go']), - ('set-cmd-text ":open -t "', ['O']), - ('set-cmd-text ":open -t {url}"', ['gO']), - ('set-cmd-text ":open -b "', ['xo']), - ('set-cmd-text ":open -b {url}"', ['xO']), - ('set-cmd-text ":open -w "', ['wo']), - ('set-cmd-text ":open -w {url}"', ['wO']), + ('set-cmd-text -s :open', ['o']), + ('set-cmd-text :open {url}', ['go']), + ('set-cmd-text -s :open -t', ['O']), + ('set-cmd-text :open -t {url}', ['gO']), + ('set-cmd-text -s :open -b', ['xo']), + ('set-cmd-text :open -b {url}', ['xO']), + ('set-cmd-text -s :open -w', ['wo']), + ('set-cmd-text :open -w {url}', ['wO']), ('open -t', ['ga']), ('tab-close', ['d', '']), ('tab-close -o', ['D']), @@ -1189,4 +1189,6 @@ CHANGED_KEY_COMMANDS = [ (re.compile(r'^cancel-download$'), r'download-cancel'), (re.compile(r'^search ""$'), r'search'), (re.compile(r"^search ''$"), r'search'), + (re.compile(r"""^set-cmd-text ['"](.*) ['"]$"""), r'set-cmd-text -s \1'), + (re.compile(r"""^set-cmd-text ['"](.*)['"]$"""), r'set-cmd-text \1'), ] diff --git a/qutebrowser/mainwindow/statusbar/command.py b/qutebrowser/mainwindow/statusbar/command.py index 38457b08b..48a106793 100644 --- a/qutebrowser/mainwindow/statusbar/command.py +++ b/qutebrowser/mainwindow/statusbar/command.py @@ -98,7 +98,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit): @cmdutils.register(instance='status-command', name='set-cmd-text', scope='window', maxsplit=0) - def set_cmd_text_command(self, text): + def set_cmd_text_command(self, text, space=False): """Preset the statusbar to some text. // @@ -108,6 +108,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit): Args: text: The commandline to set. + space: If given, a space is added to the end. """ tabbed_browser = objreg.get('tabbed-browser', scope='window', window=self._win_id) @@ -127,6 +128,8 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit): # I'm not sure what's the best thing to do here # https://github.com/The-Compiler/qutebrowser/issues/123 text = text.replace('{url}', url) + if space: + text += ' ' if not text or text[0] not in modeparsers.STARTCHARS: raise cmdexc.CommandError( "Invalid command text '{}'.".format(text)) From 25fca03dca7c9dc0b1d530a507d074b6c90c71bf Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 2 Apr 2015 18:12:05 +0200 Subject: [PATCH 49/69] Don't double ampersands in window title. Fixes #599. --- qutebrowser/mainwindow/tabwidget.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index 9d4303735..df44ebbba 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -93,7 +93,7 @@ class TabWidget(QTabWidget): def set_page_title(self, idx, title): """Set the tab title user data.""" - self.tabBar().set_tab_data(idx, 'page-title', title.replace('&', '&&')) + self.tabBar().set_tab_data(idx, 'page-title', title) self.update_tab_title(idx) def page_title(self, idx): @@ -103,7 +103,7 @@ class TabWidget(QTabWidget): def update_tab_title(self, idx): """Update the tab text for the given tab.""" widget = self.widget(idx) - page_title = self.page_title(idx) + page_title = self.page_title(idx).replace('&', '&&') fields = {} if widget.load_status == webview.LoadStatus.loading: From 58a8a7e992779a367b8f3a39c58ba12cf1fc41db Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 20:10:41 +0200 Subject: [PATCH 50/69] Introduce pytest plugin capturelog and convert test_log_time --- qutebrowser/test/utils/debug/test_log_time.py | 45 +++++++++++++++++++ qutebrowser/test/utils/test_debug.py | 17 ------- tox.ini | 1 + 3 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 qutebrowser/test/utils/debug/test_log_time.py diff --git a/qutebrowser/test/utils/debug/test_log_time.py b/qutebrowser/test/utils/debug/test_log_time.py new file mode 100644 index 000000000..b5d1b97fe --- /dev/null +++ b/qutebrowser/test/utils/debug/test_log_time.py @@ -0,0 +1,45 @@ +# Copyright 2014-2015 Florian Bruhin (The Compiler) +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Tests for qutebrowser.utils.debug.log_time.""" + +import logging +import re +import time + +from qutebrowser.utils import debug + + +def test_log_time(caplog): + """Test if log_time logs properly.""" + logger = logging.getLogger('qt-tests') + + with caplog.atLevel(logging.DEBUG, logger='qt-tests'): + with debug.log_time(logger, action='foobar'): + time.sleep(0.1) + + records = caplog.records() + assert len(records) == 1 + + pattern = re.compile(r'^Foobar took ([\d.]*) seconds\.$') + match = pattern.match(records[0].msg) + assert match + + duration = float(match.group(1)) + assert abs(duration - 0.1) < 0.01 diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 737763044..7bd2d94c4 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -59,22 +59,5 @@ class TestDebug(unittest.TestCase): r"fake('foo\nbar')") -class TestLogTime(unittest.TestCase): - - """Test log_time.""" - - def test_log_time(self): - """Test if log_time logs properly.""" - logger = logging.getLogger('qt-tests') - with self.assertLogs(logger, logging.DEBUG) as logged: - with debug.log_time(logger, action='foobar'): - time.sleep(0.1) - self.assertEqual(len(logged.records), 1) - pattern = re.compile(r'^Foobar took ([\d.]*) seconds\.$') - match = pattern.match(logged.records[0].msg) - self.assertTrue(match) - duration = float(match.group(1)) - self.assertAlmostEqual(duration, 0.1, delta=0.01) - if __name__ == '__main__': unittest.main() diff --git a/tox.ini b/tox.ini index 143d4f804..502915d7f 100644 --- a/tox.ini +++ b/tox.ini @@ -19,6 +19,7 @@ setenv = QT_QPA_PLATFORM_PLUGIN_PATH={envsitepackagesdir}/PyQt5/plugins/platform deps = py==1.4.26 pytest==2.7.0 + pytest-capturelog==0.7 # We don't use {[testenv:mkvenv]commands} here because that seems to be broken # on Ubuntu Trusty. commands = From 6fb83aacae00c71cffda5fc824fd72cdc70c6c82 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 20:32:29 +0200 Subject: [PATCH 51/69] Add a local variable for the logger name --- qutebrowser/test/utils/debug/test_log_time.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_log_time.py b/qutebrowser/test/utils/debug/test_log_time.py index b5d1b97fe..5619174aa 100644 --- a/qutebrowser/test/utils/debug/test_log_time.py +++ b/qutebrowser/test/utils/debug/test_log_time.py @@ -28,10 +28,11 @@ from qutebrowser.utils import debug def test_log_time(caplog): """Test if log_time logs properly.""" - logger = logging.getLogger('qt-tests') - with caplog.atLevel(logging.DEBUG, logger='qt-tests'): - with debug.log_time(logger, action='foobar'): + logger_name = 'qt-tests' + + with caplog.atLevel(logging.DEBUG, logger=logger_name): + with debug.log_time(logging.getLogger(), action='foobar'): time.sleep(0.1) records = caplog.records() From 91a8b23aeb7d2b4d0ceedb6d2e0aa8c5db9ec158 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 20:40:37 +0200 Subject: [PATCH 52/69] Use actual unittest implementation of assertAlmostEqual --- qutebrowser/test/utils/debug/test_log_time.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qutebrowser/test/utils/debug/test_log_time.py b/qutebrowser/test/utils/debug/test_log_time.py index 5619174aa..f64f81ce1 100644 --- a/qutebrowser/test/utils/debug/test_log_time.py +++ b/qutebrowser/test/utils/debug/test_log_time.py @@ -43,4 +43,6 @@ def test_log_time(caplog): assert match duration = float(match.group(1)) - assert abs(duration - 0.1) < 0.01 + + # Imitate unittests assertAlmostEqual(duration, 0.1, delta=0.01) + assert round(duration - 0.1, 2) == 0 From 068947ba7eb000a868d6e6c52d355097842c1ec7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 20:54:27 +0200 Subject: [PATCH 53/69] Fix search engine syntax documentation. We changed the syntax in 68398035ef4178f676d31fb2996f8fbd6793262c but didn't adjust the documentation. See #14. --- doc/help/settings.asciidoc | 2 +- qutebrowser/config/configdata.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 02d9bb5dc..56cab15bb 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -1332,7 +1332,7 @@ Default: +pass:[\bprev(ious)?\b,\bback\b,\bolder\b,\b[<←≪]\b,\b(<<| == searchengines Definitions of search engines which can be used via the address bar. -The searchengine named `DEFAULT` is used when `general -> auto-search` is true and something else than a URL was entered to be opened. Other search engines can be used via the bang-syntax, e.g. `:open qutebrowser !google`. The string `{}` will be replaced by the search term, use `{{` and `}}` for literal `{`/`}` signs. +The searchengine named `DEFAULT` is used when `general -> auto-search` is true and something else than a URL was entered to be opened. Other search engines can be used by prepending the search engine name to the search term, e.g. `:open google qutebrowser`. The string `{}` will be replaced by the search term, use `{{` and `}}` for literal `{`/`}` signs. == aliases Aliases for commands. diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 6807447be..fea34ab91 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -80,10 +80,10 @@ SECTION_DESC = { "bar.\n" "The searchengine named `DEFAULT` is used when " "`general -> auto-search` is true and something else than a URL was " - "entered to be opened. Other search engines can be used via the " - "bang-syntax, e.g. `:open qutebrowser !google`. The string `{}` will " - "be replaced by the search term, use `{{` and `}}` for literal " - "`{`/`}` signs."), + "entered to be opened. Other search engines can be used by prepending " + "the search engine name to the search term, e.g. " + "`:open google qutebrowser`. The string `{}` will be replaced by the " + "search term, use `{{` and `}}` for literal `{`/`}` signs."), 'aliases': ( "Aliases for commands.\n" "By default, no aliases are defined. Example which adds a new command " From 45e95d497d9f7be39846724628f29d0b00fcdecb Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 21:41:41 +0200 Subject: [PATCH 54/69] Convert test_signal_name using a signal fixture --- qutebrowser/test/utils/debug/test_signal.py | 35 +++++++++++++++++++++ qutebrowser/test/utils/test_debug.py | 4 --- 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 qutebrowser/test/utils/debug/test_signal.py diff --git a/qutebrowser/test/utils/debug/test_signal.py b/qutebrowser/test/utils/debug/test_signal.py new file mode 100644 index 000000000..ff23680d0 --- /dev/null +++ b/qutebrowser/test/utils/debug/test_signal.py @@ -0,0 +1,35 @@ +# Copyright 2014-2015 Florian Bruhin (The Compiler) +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Test signal debug output functions.""" + +import pytest + +from qutebrowser.test import stubs +from qutebrowser.utils import debug + + +@pytest.fixture +def signal(): + return stubs.FakeSignal() + + +def test_signal_name(signal): + """Test signal_name().""" + assert debug.signal_name(signal) == 'fake' diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 7bd2d94c4..e08b2b943 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -38,10 +38,6 @@ class TestDebug(unittest.TestCase): def setUp(self): self.signal = stubs.FakeSignal() - def test_signal_name(self): - """Test signal_name().""" - self.assertEqual(debug.signal_name(self.signal), 'fake') - def test_dbg_signal(self): """Test dbg_signal().""" self.assertEqual(debug.dbg_signal(self.signal, [23, 42]), From 9d39fbd4e5a1bf2a4749317b556099ad217026da Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 21:45:10 +0200 Subject: [PATCH 55/69] Convert test_dbg_signal --- qutebrowser/test/utils/debug/test_signal.py | 5 +++++ qutebrowser/test/utils/test_debug.py | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_signal.py b/qutebrowser/test/utils/debug/test_signal.py index ff23680d0..b6126b22f 100644 --- a/qutebrowser/test/utils/debug/test_signal.py +++ b/qutebrowser/test/utils/debug/test_signal.py @@ -33,3 +33,8 @@ def signal(): def test_signal_name(signal): """Test signal_name().""" assert debug.signal_name(signal) == 'fake' + + +def test_dbg_signal(signal): + """Test dbg_signal().""" + assert debug.dbg_signal(signal, [23, 42]) == 'fake(23, 42)' diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index e08b2b943..f36d7f24b 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -38,11 +38,6 @@ class TestDebug(unittest.TestCase): def setUp(self): self.signal = stubs.FakeSignal() - def test_dbg_signal(self): - """Test dbg_signal().""" - self.assertEqual(debug.dbg_signal(self.signal, [23, 42]), - 'fake(23, 42)') - def test_dbg_signal_eliding(self): """Test eliding in dbg_signal().""" self.assertEqual(debug.dbg_signal(self.signal, From 22522406e13cb98ed26e544bd2e864d9273317af Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 21:50:32 +0200 Subject: [PATCH 56/69] Convert test_dbg_signal_eliding --- qutebrowser/test/utils/debug/test_signal.py | 6 ++++++ qutebrowser/test/utils/test_debug.py | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_signal.py b/qutebrowser/test/utils/debug/test_signal.py index b6126b22f..177a11c6b 100644 --- a/qutebrowser/test/utils/debug/test_signal.py +++ b/qutebrowser/test/utils/debug/test_signal.py @@ -38,3 +38,9 @@ def test_signal_name(signal): def test_dbg_signal(signal): """Test dbg_signal().""" assert debug.dbg_signal(signal, [23, 42]) == 'fake(23, 42)' + + +def test_dbg_signal_eliding(signal): + """Test eliding in dbg_signal().""" + dbg_signal = debug.dbg_signal(signal, ['x' * 201]) + assert dbg_signal == "fake('{}\u2026)".format('x' * 198) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index f36d7f24b..ee6ec30fe 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -38,12 +38,6 @@ class TestDebug(unittest.TestCase): def setUp(self): self.signal = stubs.FakeSignal() - def test_dbg_signal_eliding(self): - """Test eliding in dbg_signal().""" - self.assertEqual(debug.dbg_signal(self.signal, - ['x' * 201]), - "fake('{}\u2026)".format('x' * 198)) - def test_dbg_signal_newline(self): """Test dbg_signal() with a newline.""" self.assertEqual(debug.dbg_signal(self.signal, ['foo\nbar']), From 7540a5bbf4453fde3b307041a2be366db03a0649 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 21:54:24 +0200 Subject: [PATCH 57/69] Convert test_dbg_signal_newline --- qutebrowser/test/utils/debug/test_signal.py | 6 ++++++ qutebrowser/test/utils/test_debug.py | 13 ------------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_signal.py b/qutebrowser/test/utils/debug/test_signal.py index 177a11c6b..4bea5bf6d 100644 --- a/qutebrowser/test/utils/debug/test_signal.py +++ b/qutebrowser/test/utils/debug/test_signal.py @@ -44,3 +44,9 @@ def test_dbg_signal_eliding(signal): """Test eliding in dbg_signal().""" dbg_signal = debug.dbg_signal(signal, ['x' * 201]) assert dbg_signal == "fake('{}\u2026)".format('x' * 198) + + +def test_dbg_signal_newline(signal): + """Test dbg_signal() with a newline.""" + dbg_signal = debug.dbg_signal(signal, ['foo\nbar']) + assert dbg_signal == r"fake('foo\nbar')" diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index ee6ec30fe..13db4f1bd 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -31,18 +31,5 @@ from qutebrowser.utils import debug from qutebrowser.test import stubs -class TestDebug(unittest.TestCase): - - """Test signal debug output functions.""" - - def setUp(self): - self.signal = stubs.FakeSignal() - - def test_dbg_signal_newline(self): - """Test dbg_signal() with a newline.""" - self.assertEqual(debug.dbg_signal(self.signal, ['foo\nbar']), - r"fake('foo\nbar')") - - if __name__ == '__main__': unittest.main() From efbc8e0cbfb71442504500d029b676745e76dc55 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 21:55:19 +0200 Subject: [PATCH 58/69] Remove former unittest module test_debug.py --- qutebrowser/test/utils/test_debug.py | 35 ---------------------------- 1 file changed, 35 deletions(-) delete mode 100644 qutebrowser/test/utils/test_debug.py diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py deleted file mode 100644 index 13db4f1bd..000000000 --- a/qutebrowser/test/utils/test_debug.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2014-2015 Florian Bruhin (The Compiler) -# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: - -# -# This file is part of qutebrowser. -# -# qutebrowser is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# qutebrowser is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with qutebrowser. If not, see . - -"""Tests for qutebrowser.utils.debug.""" - -import re -import time -import unittest -import logging - -from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QStyle, QFrame - -from qutebrowser.utils import debug -from qutebrowser.test import stubs - - -if __name__ == '__main__': - unittest.main() From 231feda2c8fe1b3a7a80ce62ef3e3c7cc6e96868 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Fri, 3 Apr 2015 22:45:26 +0200 Subject: [PATCH 59/69] Use logger with name of local var logger_name --- qutebrowser/test/utils/debug/test_log_time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/test/utils/debug/test_log_time.py b/qutebrowser/test/utils/debug/test_log_time.py index f64f81ce1..008d726e7 100644 --- a/qutebrowser/test/utils/debug/test_log_time.py +++ b/qutebrowser/test/utils/debug/test_log_time.py @@ -32,7 +32,7 @@ def test_log_time(caplog): logger_name = 'qt-tests' with caplog.atLevel(logging.DEBUG, logger=logger_name): - with debug.log_time(logging.getLogger(), action='foobar'): + with debug.log_time(logging.getLogger(logger_name), action='foobar'): time.sleep(0.1) records = caplog.records() From fba0ae69ce0b59a49b2ebc81af2f5d60f8ec9bf5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 23:05:08 +0200 Subject: [PATCH 60/69] Remove test_reconverted from qenum_key tests. The test didn't really seem to test anything useful, and also uses a QFlags instead of a QEnum. --- qutebrowser/test/utils/debug/test_qenum_key.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qenum_key.py b/qutebrowser/test/utils/debug/test_qenum_key.py index f98c58c34..4361ba567 100644 --- a/qutebrowser/test/utils/debug/test_qenum_key.py +++ b/qutebrowser/test/utils/debug/test_qenum_key.py @@ -75,12 +75,3 @@ def test_unknown(): key = debug.qenum_key(QFrame, 0x1337, klass=QFrame.Shadow) assert key == '0x1337' - - -def test_reconverted(): - """Test passing a flag value which was re-converted to an enum.""" - - pytest.skip(msg="It is not clear what this test is supposed to do") - - # FIXME maybe this should return the right thing anyways? - debug.qenum_key(Qt, Qt.Alignment(int(Qt.AlignLeft))) From e94a8a80f17533b5bd660f1e6f8761cd9ed9ca0e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 23:18:56 +0200 Subject: [PATCH 61/69] test_qenum_key: Use hasattr() for attribute checks. --- qutebrowser/test/utils/debug/test_qenum_key.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qenum_key.py b/qutebrowser/test/utils/debug/test_qenum_key.py index 4361ba567..7b1e99bd4 100644 --- a/qutebrowser/test/utils/debug/test_qenum_key.py +++ b/qutebrowser/test/utils/debug/test_qenum_key.py @@ -30,10 +30,7 @@ from qutebrowser.utils import debug def test_no_metaobj(): """Test with an enum with no meta-object.""" - with pytest.raises(AttributeError): - # Make sure it doesn't have a meta object - # pylint: disable=pointless-statement,no-member - QStyle.PrimitiveElement.staticMetaObject + assert not hasattr(QStyle.PrimitiveElement, 'staticMetaObject') key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand) assert key == 'PE_PanelButtonCommand' @@ -42,8 +39,7 @@ def test_no_metaobj(): def test_metaobj(): """Test with an enum with meta-object.""" - # pylint: disable=pointless-statement - QFrame.staticMetaObject # make sure it has a meta-object + assert hasattr(QFrame, 'staticMetaObject') key = debug.qenum_key(QFrame, QFrame.Sunken) assert key == 'Sunken' From 0e76f9b1f12aee41a23437b35fc32461ab566978 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 23:19:49 +0200 Subject: [PATCH 62/69] Whitespace adjustments --- qutebrowser/test/utils/debug/test_qenum_key.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_qenum_key.py b/qutebrowser/test/utils/debug/test_qenum_key.py index 7b1e99bd4..c111ff311 100644 --- a/qutebrowser/test/utils/debug/test_qenum_key.py +++ b/qutebrowser/test/utils/debug/test_qenum_key.py @@ -29,45 +29,37 @@ from qutebrowser.utils import debug def test_no_metaobj(): """Test with an enum with no meta-object.""" - assert not hasattr(QStyle.PrimitiveElement, 'staticMetaObject') - key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand) assert key == 'PE_PanelButtonCommand' def test_metaobj(): """Test with an enum with meta-object.""" - assert hasattr(QFrame, 'staticMetaObject') - key = debug.qenum_key(QFrame, QFrame.Sunken) assert key == 'Sunken' def test_add_base(): """Test with add_base=True.""" - key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True) assert key == 'QFrame.Sunken' def test_int_noklass(): """Test passing an int without explicit klass given.""" - with pytest.raises(TypeError): debug.qenum_key(QFrame, 42) def test_int(): """Test passing an int with explicit klass given.""" - key = debug.qenum_key(QFrame, 0x0030, klass=QFrame.Shadow) assert key == 'Sunken' def test_unknown(): """Test passing an unknown value.""" - key = debug.qenum_key(QFrame, 0x1337, klass=QFrame.Shadow) assert key == '0x1337' From 544dc650e77379f592406cf6d237d4475e9c4104 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 23:23:31 +0200 Subject: [PATCH 63/69] Remove now unused imports from test_debug. --- qutebrowser/test/utils/test_debug.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 36d261297..203423cfe 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -25,7 +25,6 @@ import unittest import logging from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QStyle, QFrame from qutebrowser.utils import debug from qutebrowser.test import stubs From 05087b976a2d9ec5821e618dc9a142d8d0b04316 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 23:43:06 +0200 Subject: [PATCH 64/69] test_qflags_key: Improve xfail message. --- qutebrowser/test/utils/debug/test_qflags_key.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/test/utils/debug/test_qflags_key.py b/qutebrowser/test/utils/debug/test_qflags_key.py index 371efdeff..6a2a85069 100644 --- a/qutebrowser/test/utils/debug/test_qflags_key.py +++ b/qutebrowser/test/utils/debug/test_qflags_key.py @@ -28,7 +28,7 @@ from PyQt5.QtCore import Qt from qutebrowser.utils import debug -fixme = pytest.mark.xfail(reason="Broken but shouldn't generate a failure") +fixme = pytest.mark.xfail(reason="See issue #42", raises=AssertionError) @fixme From 2ac0c7b8f07844ecfbbf2be4356d0b0d5264afd9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Apr 2015 23:52:13 +0200 Subject: [PATCH 65/69] Remove now unused import from test_debug. --- qutebrowser/test/utils/test_debug.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qutebrowser/test/utils/test_debug.py b/qutebrowser/test/utils/test_debug.py index 737763044..107f06d32 100644 --- a/qutebrowser/test/utils/test_debug.py +++ b/qutebrowser/test/utils/test_debug.py @@ -24,7 +24,6 @@ import time import unittest import logging -from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QStyle, QFrame from qutebrowser.utils import debug From 80b069297190c6717cd310528f926dad93622b3f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 4 Apr 2015 01:11:57 +0200 Subject: [PATCH 66/69] Remove blank line to make pep257 happy. --- qutebrowser/test/utils/debug/test_log_time.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qutebrowser/test/utils/debug/test_log_time.py b/qutebrowser/test/utils/debug/test_log_time.py index 008d726e7..a83ce9f88 100644 --- a/qutebrowser/test/utils/debug/test_log_time.py +++ b/qutebrowser/test/utils/debug/test_log_time.py @@ -28,7 +28,6 @@ from qutebrowser.utils import debug def test_log_time(caplog): """Test if log_time logs properly.""" - logger_name = 'qt-tests' with caplog.atLevel(logging.DEBUG, logger=logger_name): From 8e9374704083adcd290d6abbc16a2a16450e6d67 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 4 Apr 2015 12:03:26 +0200 Subject: [PATCH 67/69] test_log_time: Fix/simplify duration assert. See #13. --- qutebrowser/test/utils/debug/test_log_time.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_log_time.py b/qutebrowser/test/utils/debug/test_log_time.py index a83ce9f88..72a8e8d4a 100644 --- a/qutebrowser/test/utils/debug/test_log_time.py +++ b/qutebrowser/test/utils/debug/test_log_time.py @@ -42,6 +42,5 @@ def test_log_time(caplog): assert match duration = float(match.group(1)) - - # Imitate unittests assertAlmostEqual(duration, 0.1, delta=0.01) - assert round(duration - 0.1, 2) == 0 + assert duration >= 0.09 + assert duration <= 0.11 From f1ebbda7a0e7cbfdc1e2738204b3400509ef42e0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 4 Apr 2015 12:08:22 +0200 Subject: [PATCH 68/69] test_signal: Add docstring for signal(). --- qutebrowser/test/utils/debug/test_signal.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qutebrowser/test/utils/debug/test_signal.py b/qutebrowser/test/utils/debug/test_signal.py index 4bea5bf6d..32d994e78 100644 --- a/qutebrowser/test/utils/debug/test_signal.py +++ b/qutebrowser/test/utils/debug/test_signal.py @@ -27,6 +27,7 @@ from qutebrowser.utils import debug @pytest.fixture def signal(): + """Fixture to provide a faked pyqtSignal.""" return stubs.FakeSignal() From cef88d6e19d09ee99f9d2d3884a052d444799d7f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 4 Apr 2015 16:33:10 +0200 Subject: [PATCH 69/69] test_log_time: Prettify duration assertion. As suggested by @nicoddemus in #13. --- qutebrowser/test/utils/debug/test_log_time.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qutebrowser/test/utils/debug/test_log_time.py b/qutebrowser/test/utils/debug/test_log_time.py index 72a8e8d4a..f7da1a220 100644 --- a/qutebrowser/test/utils/debug/test_log_time.py +++ b/qutebrowser/test/utils/debug/test_log_time.py @@ -42,5 +42,4 @@ def test_log_time(caplog): assert match duration = float(match.group(1)) - assert duration >= 0.09 - assert duration <= 0.11 + assert 0.09 <= duration <= 0.11