Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Raphael Pierzina 2015-04-10 08:40:17 +02:00
commit 0b2e39e4a4
18 changed files with 433 additions and 78 deletions

View File

@ -134,6 +134,7 @@ Contributors, sorted by the number of commits in descending order:
// QUTE_AUTHORS_START
* Florian Bruhin
* Bruno Oliveira
* Joel Torstensson
* Raphael Pierzina
* Claude

View File

@ -31,6 +31,7 @@
|Setting|Description
|<<ui-zoom-levels,zoom-levels>>|The available zoom levels, separated by commas.
|<<ui-default-zoom,default-zoom>>|The default zoom level.
|<<ui-downloads-position,downloads-position>>|Where to show the downloaded files.
|<<ui-message-timeout,message-timeout>>|Time (in ms) to show messages in the statusbar for.
|<<ui-message-unfocused,message-unfocused>>|Whether to show messages in unfocused windows.
|<<ui-confirm-quit,confirm-quit>>|Whether to confirm quitting the application.
@ -42,6 +43,7 @@
|<<ui-remove-finished-downloads,remove-finished-downloads>>|Whether to remove finished downloads automatically.
|<<ui-hide-statusbar,hide-statusbar>>|Whether to hide the statusbar unless a message is shown.
|<<ui-window-title-format,window-title-format>>|The format to use for the window title. The following placeholders are defined:
|<<ui-hide-mouse-cursor,hide-mouse-cursor>>|Whether to hide the mouse cursor.
|==============
.Quick reference for section ``network''
@ -441,6 +443,17 @@ The default zoom level.
Default: +pass:[100%]+
[[ui-downloads-position]]
=== downloads-position
Where to show the downloaded files.
Valid values:
* +north+
* +south+
Default: +pass:[north]+
[[ui-message-timeout]]
=== message-timeout
Time (in ms) to show messages in the statusbar for.
@ -552,6 +565,17 @@ The format to use for the window title. The following placeholders are defined:
Default: +pass:[{perc}{title}{title_sep}qutebrowser]+
[[ui-hide-mouse-cursor]]
=== hide-mouse-cursor
Whether to hide the mouse cursor.
Valid values:
* +true+
* +false+
Default: +pass:[false]+
== network
Settings related to the network.

View File

@ -21,6 +21,10 @@ on Python, PyQt5 and QtWebKit and free software, licensed under the GPL.
It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
Note the commands and settings of qutebrowser are not described in this
manpage, but in the help integrated in qutebrowser - use the ":help" command to
show it.
== OPTIONS
// QUTE_OPTIONS_START
=== positional arguments
@ -110,6 +114,11 @@ It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
- '~/.local/share/qutebrowser/': Various state information.
- '~/.cache/qutebrowser/': Temporary data.
Note qutebrowser conforms to the XDG basedir specification - if
'XDG_CONFIG_HOME', 'XDG_DATA_HOME' or 'XDG_CACHE_HOME' are set in the
environment, the directories configured there are used instead of the above
defaults.
== BUGS
Bugs are tracked in the Github issue tracker at
https://github.com/The-Compiler/qutebrowser/issues.

View File

@ -24,6 +24,8 @@ The following environment variables will be set when an userscript is launched:
command or key binding).
- `QUTE_USER_AGENT`: The currently set user agent.
- `QUTE_FIFO`: The FIFO or file to write commands to.
- `QUTE_HTML`: The HTML source of the current page.
- `QUTE_TEXT`: The plaintext of the current page.
In `command` mode:

View File

@ -33,9 +33,9 @@ import faulthandler
import json
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon
from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon, QCursor, QWindow
from PyQt5.QtCore import (pyqtSlot, qInstallMessageHandler, QTimer, QUrl,
QObject, Qt, QSocketNotifier)
QObject, Qt, QSocketNotifier, QEvent)
try:
import hunter
except ImportError:
@ -52,7 +52,6 @@ from qutebrowser.mainwindow import mainwindow
from qutebrowser.misc import (crashdialog, readline, ipc, earlyinit,
savemanager, sessions)
from qutebrowser.misc import utilcmds # pylint: disable=unused-import
from qutebrowser.keyinput import modeman
from qutebrowser.utils import (log, version, message, utils, qtutils, urlutils,
objreg, usertypes, standarddir)
# We import utilcmds to run the cmdutils.register decorators.
@ -143,7 +142,7 @@ class Application(QApplication):
QTimer.singleShot(0, self._process_args)
log.init.debug("Initializing eventfilter...")
self._event_filter = modeman.EventFilter(self)
self._event_filter = EventFilter(self)
self.installEventFilter(self._event_filter)
log.init.debug("Connecting signals...")
@ -210,6 +209,19 @@ class Application(QApplication):
objreg.register('cache', diskcache)
log.init.debug("Initializing completions...")
completionmodels.init()
log.init.debug("Misc initialization...")
self.maybe_hide_mouse_cursor()
objreg.get('config').changed.connect(self.maybe_hide_mouse_cursor)
@config.change_filter('ui', 'hide-mouse-cursor')
def maybe_hide_mouse_cursor(self):
"""Hide the mouse cursor if it isn't yet and it's configured."""
if config.get('ui', 'hide-mouse-cursor'):
if self.overrideCursor() is not None:
return
self.setOverrideCursor(QCursor(Qt.BlankCursor))
else:
self.restoreOverrideCursor()
def _init_icon(self):
"""Initialize the icon of qutebrowser."""
@ -940,8 +952,10 @@ class Application(QApplication):
objreg.delete('last-focused-main-window')
except KeyError:
pass
self.restoreOverrideCursor()
else:
objreg.register('last-focused-main-window', window, update=True)
self.maybe_hide_mouse_cursor()
@pyqtSlot(QUrl)
def open_desktopservices_url(self, url):
@ -962,3 +976,92 @@ class Application(QApplication):
print("Now logging late shutdown.", file=sys.stderr)
hunter.trace()
super().exit(status)
class EventFilter(QObject):
"""Global Qt event filter.
Attributes:
_activated: Whether the EventFilter is currently active.
_handlers; A {QEvent.Type: callable} dict with the handlers for an
event.
"""
def __init__(self, parent=None):
super().__init__(parent)
self._activated = True
self._handlers = {
QEvent.MouseButtonDblClick: self._handle_mouse_event,
QEvent.MouseButtonPress: self._handle_mouse_event,
QEvent.MouseButtonRelease: self._handle_mouse_event,
QEvent.MouseMove: self._handle_mouse_event,
QEvent.KeyPress: self._handle_key_event,
QEvent.KeyRelease: self._handle_key_event,
}
def _handle_key_event(self, event):
"""Handle a key press/release event.
Args:
event: The QEvent which is about to be delivered.
Return:
True if the event should be filtered, False if it's passed through.
"""
qapp = QApplication.instance()
if qapp.activeWindow() not in objreg.window_registry.values():
# Some other window (print dialog, etc.) is focused so we pass the
# event through.
return False
try:
man = objreg.get('mode-manager', scope='window', window='current')
return man.eventFilter(event)
except objreg.RegistryUnavailableError:
# No window available yet, or not a MainWindow
return False
def _handle_mouse_event(self, _event):
"""Handle a mouse event.
Args:
_event: The QEvent which is about to be delivered.
Return:
True if the event should be filtered, False if it's passed through.
"""
if QApplication.instance().overrideCursor() is None:
# Mouse cursor shown -> don't filter event
return False
else:
# Mouse cursor hidden -> filter event
return True
def eventFilter(self, obj, event):
"""Handle an event.
Args:
obj: The object which will get the event.
event: The QEvent which is about to be delivered.
Return:
True if the event should be filtered, False if it's passed through.
"""
try:
if not self._activated:
return False
if not isinstance(obj, QWindow):
# We already handled this same event at some point earlier, so
# we're not interested in it anymore.
return False
try:
handler = self._handlers[event.type()]
except KeyError:
return False
else:
return handler(event)
except:
# If there is an exception in here and we leave the eventfilter
# activated, we'll get an infinite loop and a stack overflow.
self._activated = False
raise

View File

@ -876,9 +876,14 @@ class CommandDispatcher:
env['QUTE_TITLE'] = tabbed_browser.page_title(idx)
webview = tabbed_browser.currentWidget()
if webview is not None and webview.hasSelection():
if webview is not None:
if webview.hasSelection():
env['QUTE_SELECTED_TEXT'] = webview.selectedText()
env['QUTE_SELECTED_HTML'] = webview.selectedHtml()
mainframe = webview.page().mainFrame()
if mainframe is not None:
env['QUTE_HTML'] = mainframe.toHtml()
env['QUTE_TEXT'] = mainframe.toPlainText()
try:
url = tabbed_browser.current_url()

View File

@ -518,10 +518,13 @@ class HintManager(QObject):
"""
cmd = context.args[0]
args = context.args[1:]
frame = context.mainframe
env = {
'QUTE_MODE': 'hints',
'QUTE_SELECTED_TEXT': str(elem),
'QUTE_SELECTED_HTML': elem.toOuterXml(),
'QUTE_HTML': frame.toHtml(),
'QUTE_TEXT': frame.toPlainText(),
}
url = self._resolve_url(elem, context.baseurl)
if url is not None:

View File

@ -25,7 +25,7 @@ import collections
from PyQt5.QtCore import pyqtSignal, QUrl
from PyQt5.QtWebKit import QWebHistoryInterface
from qutebrowser.utils import utils, objreg, standarddir
from qutebrowser.utils import utils, objreg, standarddir, log
from qutebrowser.config import config
from qutebrowser.misc import lineparser
@ -89,6 +89,11 @@ class WebHistory(QWebHistoryInterface):
if not data:
# empty line
continue
elif len(data) != 2:
# other malformed line
log.init.warning("Invalid history entry {!r}!".format(
line))
continue
atime, url = data
# This de-duplicates history entries; only the latest
# entry for each URL is kept. If you want to keep

View File

@ -235,6 +235,10 @@ def data(readonly=False):
SettingValue(typ.Perc(), '100%'),
"The default zoom level."),
('downloads-position',
SettingValue(typ.VerticalPosition(), 'north'),
"Where to show the downloaded files."),
('message-timeout',
SettingValue(typ.Int(), '2000'),
"Time (in ms) to show messages in the statusbar for."),
@ -293,6 +297,10 @@ def data(readonly=False):
"otherwise.\n"
"* `{id}`: The internal window ID of this window."),
('hide-mouse-cursor',
SettingValue(typ.Bool(), 'false'),
"Whether to hide the mouse cursor."),
readonly=readonly
)),
@ -1155,13 +1163,13 @@ KEY_DATA = collections.OrderedDict([
('paste -w', ['wp']),
('paste -ws', ['wP']),
('quickmark-save', ['m']),
('set-cmd-text ":quickmark-load "', ['b']),
('set-cmd-text ":quickmark-load -t "', ['B']),
('set-cmd-text ":quickmark-load -w"', ['wb']),
('set-cmd-text -s :quickmark-load', ['b']),
('set-cmd-text -s :quickmark-load -t', ['B']),
('set-cmd-text -s :quickmark-load -w', ['wb']),
('save', ['sf']),
('set-cmd-text ":set "', ['ss']),
('set-cmd-text ":set -t "', ['sl']),
('set-cmd-text ":set keybind "', ['sk']),
('set-cmd-text -s :set', ['ss']),
('set-cmd-text -s :set -t', ['sl']),
('set-cmd-text -s :set keybind', ['sk']),
('zoom-out', ['-']),
('zoom-in', ['+']),
('zoom', ['=']),

View File

@ -1264,6 +1264,13 @@ class Position(BaseType):
return self.MAPPING[value]
class VerticalPosition(BaseType):
"""The position of the download bar."""
valid_values = ValidValues('north', 'south')
class UrlList(List):
"""A list of URLs."""

View File

@ -21,7 +21,6 @@
import functools
from PyQt5.QtGui import QWindow
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QEvent
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebKitWidgets import QWebView
@ -120,46 +119,6 @@ def maybe_leave(win_id, mode, reason=None):
log.modes.debug("{} (leave reason: {})".format(e, reason))
class EventFilter(QObject):
"""Event filter which passes the event to the current ModeManager."""
def __init__(self, parent=None):
super().__init__(parent)
self._activated = True
def eventFilter(self, obj, event):
"""Forward events to the correct modeman."""
try:
if not self._activated:
return False
if event.type() not in [QEvent.KeyPress, QEvent.KeyRelease]:
# We're not interested in non-key-events so we pass them
# through.
return False
if not isinstance(obj, QWindow):
# We already handled this same event at some point earlier, so
# we're not interested in it anymore.
return False
if (QApplication.instance().activeWindow() not in
objreg.window_registry.values()):
# Some other window (print dialog, etc.) is focused so we pass
# the event through.
return False
try:
modeman = objreg.get('mode-manager', scope='window',
window='current')
return modeman.eventFilter(event)
except objreg.RegistryUnavailableError:
# No window available yet, or not a MainWindow
return False
except:
# If there is an exception in here and we leave the eventfilter
# activated, we'll get an infinite loop and a stack overflow.
self._activated = False
raise
class ModeManager(QObject):
"""Manager for keyboard modes.

View File

@ -96,19 +96,18 @@ class MainWindow(QWidget):
window=self.win_id)
self._downloadview = downloadview.DownloadView(self.win_id)
self._vbox.addWidget(self._downloadview)
self._downloadview.show()
self._tabbed_browser = tabbedbrowser.TabbedBrowser(self.win_id)
objreg.register('tabbed-browser', self._tabbed_browser, scope='window',
window=self.win_id)
self._vbox.addWidget(self._tabbed_browser)
# We need to set an explicit parent for StatusBar because it does some
# show/hide magic immediately which would mean it'd show up as a
# window.
self.status = bar.StatusBar(self.win_id, parent=self)
self._vbox.addWidget(self.status)
self._add_widgets()
self._completion = completionwidget.CompletionView(self.win_id, self)
@ -129,6 +128,10 @@ class MainWindow(QWidget):
# we defer this until everything else is initialized.
QTimer.singleShot(0, self._connect_resize_completion)
objreg.get('config').changed.connect(self.on_config_changed)
if config.get('ui', 'hide-mouse-cursor'):
self.setCursor(Qt.BlankCursor)
#self.retranslateUi(MainWindow)
#self.tabWidget.setCurrentIndex(0)
#QtCore.QMetaObject.connectSlotsByName(MainWindow)
@ -141,6 +144,24 @@ class MainWindow(QWidget):
"""Resize the completion if related config options changed."""
if section == 'completion' and option in ('height', 'shrink'):
self.resize_completion()
elif section == 'ui' and option == 'downloads-position':
self._add_widgets()
def _add_widgets(self):
"""Add or readd all widgets to the VBox."""
self._vbox.removeWidget(self._tabbed_browser)
self._vbox.removeWidget(self._downloadview)
self._vbox.removeWidget(self.status)
position = config.get('ui', 'downloads-position')
if position == 'north':
self._vbox.addWidget(self._downloadview)
self._vbox.addWidget(self._tabbed_browser)
elif position == 'south':
self._vbox.addWidget(self._tabbed_browser)
self._vbox.addWidget(self._downloadview)
else:
raise ValueError("Invalid position {}!".format(position))
self._vbox.addWidget(self.status)
def _load_state_geometry(self):
"""Load the geometry from the state file."""

View File

@ -0,0 +1,101 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# 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 <http://www.gnu.org/licenses/>.
"""Classes related to auto-updating and getting the latest version."""
import json
import functools
from PyQt5.QtCore import pyqtSignal, QObject, QUrl
from PyQt5.QtNetwork import (QNetworkAccessManager, QNetworkRequest,
QNetworkReply)
class PyPIVersionClient(QObject):
"""A client for the PyPI API using QNetworkAccessManager.
It gets the latest version of qutebrowser from PyPI.
Attributes:
_nam: The QNetworkAccessManager used.
Class attributes:
API_URL: The base API URL.
Signals:
success: Emitted when getting the version info succeeded.
arg: The newest version.
error: Emitted when getting the version info failed.
arg: The error message, as string.
"""
API_URL = 'https://pypi.python.org/pypi/{}/json'
success = pyqtSignal(str)
error = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
self._nam = QNetworkAccessManager(self)
def get_version(self, package='qutebrowser'):
"""Get the newest version of a given package.
Emits success/error when done.
Args:
package: The name of the package to check.
"""
url = QUrl(self.API_URL.format(package))
request = QNetworkRequest(url)
reply = self._nam.get(request)
if reply.isFinished():
self.on_reply_finished(reply)
else:
reply.finished.connect(functools.partial(
self.on_reply_finished, reply))
def on_reply_finished(self, reply):
"""When the reply finished, load and parse the json data.
Then emits error/success.
Args:
reply: The QNetworkReply which finished.
"""
if reply.error() != QNetworkReply.NoError:
self.error.emit(reply.errorString())
return
try:
data = bytes(reply.readAll()).decode('utf-8')
except UnicodeDecodeError as e:
self.error.emit("Invalid UTF-8 data received in reply: "
"{}!".format(e))
return
try:
json_data = json.loads(data)
except ValueError as e:
self.error.emit("Invalid JSON received in reply: {}!".format(e))
return
try:
self.success.emit(json_data['info']['version'])
except KeyError as e:
self.error.emit("Malformed data recieved in reply "
"({!r} not found)!".format(e))
return

View File

@ -24,6 +24,8 @@ import sys
import html
import getpass
import traceback
import distutils.version # pylint: disable=no-name-in-module,import-error
# https://bitbucket.org/logilab/pylint/issue/73/
from PyQt5.QtCore import pyqtSlot, Qt, QSize, qVersion
from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton,
@ -32,7 +34,7 @@ from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton,
import qutebrowser
from qutebrowser.utils import version, log, utils, objreg, qtutils
from qutebrowser.misc import miscwidgets
from qutebrowser.misc import miscwidgets, autoupdate, msgbox
from qutebrowser.browser.network import pastebin
from qutebrowser.config import config
@ -103,6 +105,7 @@ class _CrashDialog(QDialog):
_url: Pastebin URL QLabel.
_crash_info: A list of tuples with title and crash information.
_paste_client: A PastebinClient instance to use.
_pypi_client: A PyPIVersionClient instance to use.
_paste_text: The text to pastebin.
"""
@ -125,6 +128,7 @@ class _CrashDialog(QDialog):
self.resize(QSize(640, 600))
self._vbox = QVBoxLayout(self)
self._paste_client = pastebin.PastebinClient(self)
self._pypi_client = autoupdate.PyPIVersionClient(self)
self._init_text()
contact = QLabel("I'd like to be able to follow up with you, to keep "
@ -293,10 +297,17 @@ class _CrashDialog(QDialog):
self._btn_report.setEnabled(False)
self._btn_cancel.setEnabled(False)
self._btn_report.setText("Reporting...")
self._paste_client.success.connect(self.finish)
self._paste_client.success.connect(self.on_paste_success)
self._paste_client.error.connect(self.show_error)
self.report()
@pyqtSlot()
def on_paste_success(self):
"""Get the newest version from PyPI when the paste is done."""
self._pypi_client.success.connect(self.on_version_success)
self._pypi_client.error.connect(self.on_version_error)
self._pypi_client.get_version()
@pyqtSlot(str)
def show_error(self, text):
"""Show a paste error dialog.
@ -308,6 +319,44 @@ class _CrashDialog(QDialog):
error_dlg.finished.connect(self.finish)
error_dlg.show()
@pyqtSlot(str)
def on_version_success(self, newest):
"""Called when the version was obtained from self._pypi_client.
Args:
newest: The newest version as a string.
"""
# pylint: disable=no-member
# https://bitbucket.org/logilab/pylint/issue/73/
new_version = distutils.version.StrictVersion(newest)
cur_version = distutils.version.StrictVersion(qutebrowser.__version__)
lines = ['The report has been sent successfully. Thanks!']
if new_version > cur_version:
lines.append("<b>Note:</b> The newest available version is v{}, "
"but you're currently running v{} - please "
"update!".format(newest, qutebrowser.__version__))
text = '<br/><br/>'.join(lines)
self.hide()
msgbox.information(self, "Report successfully sent!", text,
on_finished=self.finish, plain_text=False)
@pyqtSlot(str)
def on_version_error(self, msg):
"""Called when the version was not obtained from self._pypi_client.
Args:
msg: The error message to show.
"""
lines = ['The report has been sent successfully. Thanks!']
lines.append("There was an error while getting the newest version: "
"{}. Please check for a new version on "
"<a href=http://www.qutebrowser.org/>qutebrowser.org</a> "
"by yourself.".format(msg))
text = '<br/><br/>'.join(lines)
self.hide()
msgbox.information(self, "Report successfully sent!", text,
on_finished=self.finish, plain_text=False)
@pyqtSlot()
def finish(self):
"""Save contact info and close the dialog."""

View File

@ -0,0 +1,68 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# 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 <http://www.gnu.org/licenses/>.
"""Convenience functions to show message boxes."""
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMessageBox
def msgbox(parent, title, text, *, icon, buttons=QMessageBox.Ok,
on_finished=None, plain_text=None):
"""Display an QMessageBox with the given icon.
Args:
parent: The parent to set for the message box.
title: The title to set.
text: The text to set.
buttons: The buttons to set (QMessageBox::StandardButtons)
on_finished: A slot to connect to the 'finished' signal.
plain_text: Whether to force plain text (True) or rich text (False).
None (the default) uses Qt's auto detection.
Return:
A new QMessageBox.
"""
box = QMessageBox(parent)
box.setIcon(icon)
box.setStandardButtons(buttons)
if on_finished is not None:
box.finished.connect(on_finished)
if plain_text:
box.setTextFormat(Qt.PlainText)
elif plain_text is not None:
box.setTextFormat(Qt.RichText)
box.setWindowTitle(title)
box.setText(text)
box.show()
return box
def information(*args, **kwargs):
"""Display an information box.
Args:
*args: Passed to msgbox.
**kwargs: Passed to msgbox.
Return:
A new QMessageBox.
"""
return msgbox(*args, icon=QMessageBox.Information, **kwargs)

View File

@ -46,8 +46,13 @@ def main():
for fn in filenames:
if os.path.splitext(fn)[1] == '.py':
files.append(os.path.join(dirpath, fn))
disabled = ['attribute-defined-outside-init', 'redefined-outer-name',
'unused-argument']
disabled = [
'attribute-defined-outside-init',
'redefined-outer-name',
'unused-argument',
# https://bitbucket.org/logilab/pylint/issue/511/
'undefined-variable',
]
no_docstring_rgx = ['^__.*__$', '^setup$']
args = (['--disable={}'.format(','.join(disabled)),
'--no-docstring-rgx=({})'.format('|'.join(no_docstring_rgx))] +

View File

@ -328,9 +328,6 @@ class TestBool:
"""Test Bool."""
# https://bitbucket.org/logilab/pylint/issue/511/
# pylint: disable=undefined-variable
TESTS = {True: ['1', 'yes', 'YES', 'true', 'TrUe', 'on'],
False: ['0', 'no', 'NO', 'false', 'FaLsE', 'off']}
@ -942,9 +939,6 @@ class TestColorSystem:
"""Test ColorSystem."""
# https://bitbucket.org/logilab/pylint/issue/511/
# pylint: disable=undefined-variable
TESTS = {
'RGB': QColor.Rgb,
'rgb': QColor.Rgb,
@ -1109,9 +1103,6 @@ class TestFont:
"""Test Font/QtFont."""
# https://bitbucket.org/logilab/pylint/issue/511/
# pylint: disable=undefined-variable
TESTS = {
# (style, weight, pointsize, pixelsize, family
'"Foobar Neue"':
@ -1960,9 +1951,6 @@ class TestAutoSearch:
"""Test AutoSearch."""
# https://bitbucket.org/logilab/pylint/issue/511/
# pylint: disable=undefined-variable
TESTS = {
'naive': ['naive', 'NAIVE'] + TestBool.TESTS[True],
'dns': ['dns', 'DNS'],
@ -2012,9 +2000,6 @@ class TestIgnoreCase:
"""Test IgnoreCase."""
# https://bitbucket.org/logilab/pylint/issue/511/
# pylint: disable=undefined-variable
TESTS = {
'smart': ['smart', 'SMART'],
True: TestBool.TESTS[True],

View File

@ -21,7 +21,7 @@ deps =
pytest==2.7.0
pytest-capturelog==0.7
pytest-qt==1.3.0
pytest-mock==0.4.2
pytest-mock==0.4.3
# We don't use {[testenv:mkvenv]commands} here because that seems to be broken
# on Ubuntu Trusty.
commands =