summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2019-07-04 10:28:26 +0200
committerFlorian Bruhin <me@the-compiler.org>2019-07-04 10:28:26 +0200
commit6ba6314f716ac8d35116b93a16139fadda627c30 (patch)
tree4b4fd4dda863b6a106c243182dee71a94cde28cb
parent70d27ce7fd644e8588fb481ff62798024d888ad1 (diff)
parent564a69e507c5c0cf54f34fe1dd1cf0fd7880f181 (diff)
downloadqutebrowser-6ba6314f716ac8d35116b93a16139fadda627c30.tar.gz
qutebrowser-6ba6314f716ac8d35116b93a16139fadda627c30.zip
Merge remote-tracking branch 'origin/pr/4819'
-rw-r--r--qutebrowser/browser/webkit/webkithistory.py2
-rw-r--r--qutebrowser/config/config.py3
-rw-r--r--qutebrowser/config/configdata.py2
-rw-r--r--qutebrowser/config/configtypes.py3
-rw-r--r--qutebrowser/mainwindow/tabwidget.py3
-rw-r--r--qutebrowser/misc/debugcachestats.py49
-rw-r--r--qutebrowser/misc/utilcmds.py33
-rw-r--r--scripts/dev/check_coverage.py1
8 files changed, 62 insertions, 34 deletions
diff --git a/qutebrowser/browser/webkit/webkithistory.py b/qutebrowser/browser/webkit/webkithistory.py
index a0d41088d..aafa45f9a 100644
--- a/qutebrowser/browser/webkit/webkithistory.py
+++ b/qutebrowser/browser/webkit/webkithistory.py
@@ -24,6 +24,7 @@ import functools
from PyQt5.QtWebKit import QWebHistoryInterface
from qutebrowser.utils import debug
+from qutebrowser.misc import debugcachestats
class WebHistoryInterface(QWebHistoryInterface):
@@ -42,6 +43,7 @@ class WebHistoryInterface(QWebHistoryInterface):
def addHistoryEntry(self, url_string):
"""Required for a QWebHistoryInterface impl, obsoleted by add_url."""
+ @debugcachestats.register(name='history')
@functools.lru_cache(maxsize=32768)
def historyContains(self, url_string):
"""Called by WebKit to determine if a URL is contained in the history.
diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py
index a51126c1b..4eb6f2a1f 100644
--- a/qutebrowser/config/config.py
+++ b/qutebrowser/config/config.py
@@ -29,7 +29,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
from qutebrowser.config import configdata, configexc, configutils
from qutebrowser.utils import utils, log, jinja, urlmatch
-from qutebrowser.misc import objects
+from qutebrowser.misc import objects, debugcachestats
from qutebrowser.keyinput import keyutils
MYPY = False
@@ -625,6 +625,7 @@ def set_register_stylesheet(obj: QObject, *,
observer.register()
+@debugcachestats.register()
@functools.lru_cache()
def _render_stylesheet(stylesheet: str) -> str:
"""Render the given stylesheet jinja template."""
diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py
index 71ce74a47..b500fcb2e 100644
--- a/qutebrowser/config/configdata.py
+++ b/qutebrowser/config/configdata.py
@@ -31,6 +31,7 @@ import functools
import attr
from qutebrowser.config import configtypes
from qutebrowser.utils import usertypes, qtutils, utils
+from qutebrowser.misc import debugcachestats
DATA = typing.cast(typing.Mapping[str, 'Option'], None)
MIGRATIONS = typing.cast('Migrations', None)
@@ -267,6 +268,7 @@ def _read_yaml(
return parsed, migrations
+@debugcachestats.register()
@functools.lru_cache(maxsize=256)
def is_valid_prefix(prefix: str) -> bool:
"""Check whether the given prefix is a valid prefix for some option."""
diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py
index 0cb51f756..e43871ca6 100644
--- a/qutebrowser/config/configtypes.py
+++ b/qutebrowser/config/configtypes.py
@@ -60,7 +60,7 @@ from PyQt5.QtGui import QColor, QFont
from PyQt5.QtWidgets import QTabWidget, QTabBar
from PyQt5.QtNetwork import QNetworkProxy
-from qutebrowser.misc import objects
+from qutebrowser.misc import objects, debugcachestats
from qutebrowser.config import configexc, configutils
from qutebrowser.utils import (standarddir, utils, qtutils, urlutils, urlmatch,
usertypes)
@@ -205,6 +205,7 @@ class BaseType:
BaseType._basic_str_validation_cache(value)
@staticmethod
+ @debugcachestats.register(name='str validation cache')
@functools.lru_cache(maxsize=2**9)
def _basic_str_validation_cache(value: str) -> None:
"""Cache validation result to prevent looping over strings."""
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
index b90bc22ad..7f6201f88 100644
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -32,7 +32,7 @@ from PyQt5.QtGui import QIcon, QPalette, QColor
from qutebrowser.utils import qtutils, objreg, utils, usertypes, log
from qutebrowser.config import config
-from qutebrowser.misc import objects
+from qutebrowser.misc import objects, debugcachestats
from qutebrowser.browser import browsertab
@@ -569,6 +569,7 @@ class TabBar(QTabBar):
icon_width, ellipsis,
pinned)
+ @debugcachestats.register(name='tab width cache')
@functools.lru_cache(maxsize=2**9)
def _minimum_tab_size_hint_helper(self, tab_text: str,
icon_width: int,
diff --git a/qutebrowser/misc/debugcachestats.py b/qutebrowser/misc/debugcachestats.py
new file mode 100644
index 000000000..d77f3dade
--- /dev/null
+++ b/qutebrowser/misc/debugcachestats.py
@@ -0,0 +1,49 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+
+# Copyright 2019 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/>.
+
+"""Implementation of the command debug-cache-stats.
+
+Because many modules depend on this command, this needs to have as few
+dependencies as possible to avoid cyclic dependencies.
+"""
+
+import typing
+from typing import TypeVar, Callable
+
+
+# The second element of each tuple should be a lru_cache wrapped function
+_CACHE_FUNCTIONS = [] # type: typing.List[typing.Tuple[str, typing.Any]]
+
+
+_T = TypeVar('_T', bound=Callable)
+
+
+def register(name: typing.Optional[str] = None) -> Callable[[_T], _T]:
+ """Register a lru_cache wrapped function for debug_cache_stats."""
+ def wrapper(fn: _T) -> _T:
+ _CACHE_FUNCTIONS.append((fn.__name__ if name is None else name, fn))
+ return fn
+ return wrapper
+
+
+def debug_cache_stats() -> None:
+ """Print LRU cache stats."""
+ from qutebrowser.utils import log
+ for name, fn in _CACHE_FUNCTIONS:
+ log.misc.info('{}: {}'.format(name, fn.cache_info()))
diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py
index 6f9bf5bd6..a76826d80 100644
--- a/qutebrowser/misc/utilcmds.py
+++ b/qutebrowser/misc/utilcmds.py
@@ -31,8 +31,7 @@ from qutebrowser.browser import qutescheme
from qutebrowser.utils import log, objreg, usertypes, message, debug, utils
from qutebrowser.commands import runners
from qutebrowser.api import cmdutils
-from qutebrowser.config import config, configdata, configtypes
-from qutebrowser.misc import consolewidget
+from qutebrowser.misc import consolewidget, debugcachestats
from qutebrowser.utils.version import pastebin_version
from qutebrowser.qt import sip
@@ -121,35 +120,7 @@ def debug_all_objects():
@cmdutils.register(debug=True)
def debug_cache_stats():
"""Print LRU cache stats."""
- prefix_info = configdata.is_valid_prefix.cache_info()
- # pylint: disable=protected-access
- render_stylesheet_info = config._render_stylesheet.cache_info()
- # pylint: enable=protected-access
-
- history_info = None
- try:
- from PyQt5.QtWebKit import QWebHistoryInterface
- interface = QWebHistoryInterface.defaultInterface()
- if interface is not None:
- history_info = interface.historyContains.cache_info()
- except ImportError:
- pass
-
- tabbed_browser = objreg.get('tabbed-browser', scope='window',
- window='last-focused')
- # pylint: disable=protected-access
- tab_bar = tabbed_browser.widget.tabBar()
- tabbed_browser_info = tab_bar._minimum_tab_size_hint_helper.cache_info()
-
- str_validation_info = (configtypes.BaseType.
- _basic_str_validation_cache.cache_info())
- # pylint: enable=protected-access
-
- log.misc.info('is_valid_prefix: {}'.format(prefix_info))
- log.misc.info('_render_stylesheet: {}'.format(render_stylesheet_info))
- log.misc.info('history: {}'.format(history_info))
- log.misc.info('tab width cache: {}'.format(tabbed_browser_info))
- log.misc.info('str validation cache: {}'.format(str_validation_info))
+ debugcachestats.debug_cache_stats()
@cmdutils.register(debug=True)
diff --git a/scripts/dev/check_coverage.py b/scripts/dev/check_coverage.py
index fdbbce71a..6c770adfa 100644
--- a/scripts/dev/check_coverage.py
+++ b/scripts/dev/check_coverage.py
@@ -202,6 +202,7 @@ PERFECT_FILES = [
# 100% coverage because of end2end tests, but no perfect unit tests yet.
WHITELISTED_FILES = [
'browser/webkit/webkitinspector.py',
+ 'misc/debugcachestats.py',
'keyinput/macros.py',
'browser/webkit/webkitelem.py',
'api/interceptor.py',