From eeaa37dce91fd8e61a5b3c7800526a89db5ff171 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Tue, 28 Jun 2022 19:40:49 +0200 Subject: [PATCH 01/20] Raise the minimum Django version requirement to 3.2.4 Refs #1645 --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 2fe12e38d..3017b5e74 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,7 +31,7 @@ classifiers = [options] python_requires = >=3.7 install_requires = - Django >= 3.2 + Django >= 3.2.4 sqlparse >= 0.2.0 packages = find: include_package_data = true From 6e00fde309069f3f331ab17c6422748799ed0019 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Jul 2022 13:17:19 +0200 Subject: [PATCH 02/20] [pre-commit.ci] pre-commit autoupdate (#1646) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-eslint: v8.18.0 → v8.19.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.18.0...v8.19.0) - [github.com/psf/black: 22.3.0 → 22.6.0](https://github.com/psf/black/compare/22.3.0...22.6.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2a0e179ad..0169d64ca 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,7 +43,7 @@ repos: - id: prettier types_or: [javascript, css] - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.18.0 + rev: v8.19.0 hooks: - id: eslint files: \.js?$ @@ -51,7 +51,7 @@ repos: args: - --fix - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 22.6.0 hooks: - id: black language_version: python3 From 9721efe4f9c15d07110044129af3697530f0035e Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Mon, 11 Jul 2022 13:18:52 +0200 Subject: [PATCH 03/20] Make the README mention our Django>=3.2.4 requirement --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 2c1ba9730..9c22acdcc 100644 --- a/README.rst +++ b/README.rst @@ -45,7 +45,7 @@ In addition to the built-in panels, a number of third-party panels are contributed by the community. The current stable version of the Debug Toolbar is 3.5.0. It works on -Django ≥ 3.2. +Django ≥ 3.2.4. Documentation, including installation and configuration instructions, is available at https://django-debug-toolbar.readthedocs.io/. From 97a916558d361e0b2d25f49bf087d07f9e3482ed Mon Sep 17 00:00:00 2001 From: jonatron Date: Mon, 11 Jul 2022 17:34:30 +0100 Subject: [PATCH 04/20] Remove unused import from installation.rst (#1648) --- docs/installation.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/installation.rst b/docs/installation.rst index ad36fc2c8..d343849e4 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -138,7 +138,6 @@ option. If using Docker the following will set your ``INTERNAL_IPS`` correctly in Debug mode:: if DEBUG: - import os # only if you haven't already imported this import socket # only if you haven't already imported this hostname, _, ips = socket.gethostbyname_ex(socket.gethostname()) INTERNAL_IPS = [ip[: ip.rfind(".")] + ".1" for ip in ips] + ["127.0.0.1", "10.0.2.2"] From 48b75b9036d9338ffaa2ca495f7f713792206ac1 Mon Sep 17 00:00:00 2001 From: Tim Schilling Date: Tue, 12 Jul 2022 09:36:51 -0500 Subject: [PATCH 05/20] Check if djdt-store-id is in all headers before usage. Chromium throws an uncatchable warning when a header that can't be accessed is used. While it's not problematic, it's worrisome to developers. This avoids that by first checking that it exists. Fixes #1647 --- debug_toolbar/static/debug_toolbar/js/toolbar.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/static/debug_toolbar/js/toolbar.js b/debug_toolbar/static/debug_toolbar/js/toolbar.js index 860c72110..1c06be7fa 100644 --- a/debug_toolbar/static/debug_toolbar/js/toolbar.js +++ b/debug_toolbar/static/debug_toolbar/js/toolbar.js @@ -264,8 +264,13 @@ const djdt = { const origOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function () { this.addEventListener("load", function () { - let store_id = this.getResponseHeader("djdt-store-id"); - if (store_id !== null) { + // Chromium emits a "Refused to get unsafe header" uncatchable warning + // when the header can't be fetched. While it doesn't impede execution + // it's worrisome to developers. + if ( + this.getAllResponseHeaders().indexOf("djdt-store-id") >= 0 + ) { + let store_id = this.getResponseHeader("djdt-store-id"); store_id = encodeURIComponent(store_id); const dest = `${sidebar_url}?store_id=${store_id}`; slowjax(dest).then(function (data) { From 1b0d50d22c4f62e0f0fc23086776578e0ab0bbdb Mon Sep 17 00:00:00 2001 From: Tim Schilling Date: Tue, 12 Jul 2022 09:37:40 -0500 Subject: [PATCH 06/20] Change header to djdt-store-id. Includes some tests to validate the HistoryPanel.get_headers method. --- debug_toolbar/panels/history/panel.py | 2 +- tests/panels/test_history.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/debug_toolbar/panels/history/panel.py b/debug_toolbar/panels/history/panel.py index 596bcfb4a..2e637083a 100644 --- a/debug_toolbar/panels/history/panel.py +++ b/debug_toolbar/panels/history/panel.py @@ -24,7 +24,7 @@ def get_headers(self, request): observe_request = self.toolbar.get_observe_request() store_id = getattr(self.toolbar, "store_id") if store_id and observe_request(request): - headers["DJDT-STORE-ID"] = store_id + headers["djdt-store-id"] = store_id return headers @property diff --git a/tests/panels/test_history.py b/tests/panels/test_history.py index 9f1457049..326fb55b6 100644 --- a/tests/panels/test_history.py +++ b/tests/panels/test_history.py @@ -99,6 +99,20 @@ def test_history_sidebar_invalid(self): response = self.client.get(reverse("djdt:history_sidebar")) self.assertEqual(response.status_code, 400) + def test_history_headers(self): + """Validate the headers injected from the history panel.""" + response = self.client.get("/json_view/") + store_id = list(DebugToolbar._store)[0] + self.assertEqual(response.headers["djdt-store-id"], store_id) + + @override_settings( + DEBUG_TOOLBAR_CONFIG={"OBSERVE_REQUEST_CALLBACK": lambda request: False} + ) + def test_history_headers_unobserved(self): + """Validate the headers aren't injected from the history panel.""" + response = self.client.get("/json_view/") + self.assertNotIn("djdt-store-id", response.headers) + def test_history_sidebar(self): """Validate the history sidebar view.""" self.client.get("/json_view/") From e0417ef7161441d7e5faa81760f994f64ece88b5 Mon Sep 17 00:00:00 2001 From: Tim Schilling Date: Tue, 12 Jul 2022 09:38:14 -0500 Subject: [PATCH 07/20] Correct OBSERVE_REQUEST_CALLBACK default value in docs. --- docs/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 7577be62d..6f4084ad5 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -142,7 +142,7 @@ Toolbar options * ``OBSERVE_REQUEST_CALLBACK`` - Default: ``'debug_toolbar.middleware.observe_request'`` + Default: ``'debug_toolbar.toolbar.observe_request'`` This is the dotted path to a function used for determining whether the toolbar should update on AJAX requests or not. The default checks are that From 597cb080895eb478c33f5e282c51fd4a08c2bb77 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 12 Jul 2022 18:29:00 +0200 Subject: [PATCH 08/20] [pre-commit.ci] pre-commit autoupdate (#1649) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.34.0 → v2.37.1](https://github.com/asottile/pyupgrade/compare/v2.34.0...v2.37.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0169d64ca..bd2c48ddd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: hooks: - id: doc8 - repo: https://github.com/asottile/pyupgrade - rev: v2.34.0 + rev: v2.37.1 hooks: - id: pyupgrade args: [--py37-plus] From 964bcf1b85261c1381cde69ef490ad9b8b1cab27 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Wed, 13 Jul 2022 20:38:54 +1000 Subject: [PATCH 09/20] docs: Fix a few typos There are small typos in: - debug_toolbar/panels/sql/utils.py - tests/panels/test_sql.py Fixes: - Should read `prettify` rather than `prettyify`. - Should read `contrasting` rather than `constrasting`. --- debug_toolbar/panels/sql/utils.py | 2 +- tests/panels/test_sql.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/debug_toolbar/panels/sql/utils.py b/debug_toolbar/panels/sql/utils.py index be607cec6..0fbba3e90 100644 --- a/debug_toolbar/panels/sql/utils.py +++ b/debug_toolbar/panels/sql/utils.py @@ -69,7 +69,7 @@ def simplify(sql): def contrasting_color_generator(): """ - Generate constrasting colors by varying most significant bit of RGB first, + Generate contrasting colors by varying most significant bit of RGB first, and then vary subsequent bits systematically. """ diff --git a/tests/panels/test_sql.py b/tests/panels/test_sql.py index f078820c8..575661df1 100644 --- a/tests/panels/test_sql.py +++ b/tests/panels/test_sql.py @@ -444,7 +444,7 @@ def test_prettify_sql(self): # Reset the queries self.panel._queries = [] - # Run it again, but with prettyify off. Verify that it's different. + # Run it again, but with prettify off. Verify that it's different. dt_settings.get_config()["PRETTIFY_SQL"] = False list(User.objects.filter(username__istartswith="spam")) response = self.panel.process_request(self.request) @@ -453,7 +453,7 @@ def test_prettify_sql(self): self.assertNotEqual(pretty_sql, self.panel._queries[-1]["sql"]) self.panel._queries = [] - # Run it again, but with prettyify back on. + # Run it again, but with prettify back on. # This is so we don't have to check what PRETTIFY_SQL does exactly, # but we know it's doing something. dt_settings.get_config()["PRETTIFY_SQL"] = True From d4347db7644d61bb574a4dd8659f29af66b09ed8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Aug 2022 15:33:54 +0200 Subject: [PATCH 10/20] [pre-commit.ci] pre-commit autoupdate (#1653) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.37.1 → v2.37.2](https://github.com/asottile/pyupgrade/compare/v2.37.1...v2.37.2) - [github.com/pre-commit/mirrors-eslint: v8.19.0 → v8.20.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.19.0...v8.20.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd2c48ddd..0d8504748 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: hooks: - id: doc8 - repo: https://github.com/asottile/pyupgrade - rev: v2.37.1 + rev: v2.37.2 hooks: - id: pyupgrade args: [--py37-plus] @@ -43,7 +43,7 @@ repos: - id: prettier types_or: [javascript, css] - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.19.0 + rev: v8.20.0 hooks: - id: eslint files: \.js?$ From 06b4b4abb35b4e560dbfa385008c2aba7db270c2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Aug 2022 21:28:39 +0200 Subject: [PATCH 11/20] [pre-commit.ci] pre-commit autoupdate (#1654) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pycqa/flake8: 4.0.1 → 5.0.2](https://github.com/pycqa/flake8/compare/4.0.1...5.0.2) - [github.com/pycqa/doc8: 0.11.2 → v1.0.0](https://github.com/pycqa/doc8/compare/0.11.2...v1.0.0) - [github.com/asottile/pyupgrade: v2.37.2 → v2.37.3](https://github.com/asottile/pyupgrade/compare/v2.37.2...v2.37.3) - [github.com/pre-commit/mirrors-eslint: v8.20.0 → v8.21.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.20.0...v8.21.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0d8504748..a9f8410f2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,15 +7,15 @@ repos: - id: trailing-whitespace - id: mixed-line-ending - repo: https://github.com/pycqa/flake8 - rev: 4.0.1 + rev: 5.0.2 hooks: - id: flake8 - repo: https://github.com/pycqa/doc8 - rev: 0.11.2 + rev: v1.0.0 hooks: - id: doc8 - repo: https://github.com/asottile/pyupgrade - rev: v2.37.2 + rev: v2.37.3 hooks: - id: pyupgrade args: [--py37-plus] @@ -43,7 +43,7 @@ repos: - id: prettier types_or: [javascript, css] - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.20.0 + rev: v8.21.0 hooks: - id: eslint files: \.js?$ From 9014b68bc98114801f1b0687a0dc9905ccaa057f Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Tue, 2 Aug 2022 19:47:28 +0200 Subject: [PATCH 12/20] Run selenium tests too for py310-dj40-postgresql --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 5485a2742..d5e2d669b 100644 --- a/tox.ini +++ b/tox.ini @@ -33,6 +33,7 @@ setenv = PYTHONPATH = {toxinidir} PYTHONWARNINGS = d py39-dj32-postgresql: DJANGO_SELENIUM_TESTS = true + py310-dj40-postgresql: DJANGO_SELENIUM_TESTS = true DB_NAME = {env:DB_NAME:debug_toolbar} DB_USER = {env:DB_USER:debug_toolbar} DB_HOST = {env:DB_HOST:localhost} From d447c0e9c1295bccd13eba89a4ab73a730b1deb1 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Tue, 2 Aug 2022 19:56:03 +0200 Subject: [PATCH 13/20] Replace all uses of deprecated find_elements?_* selenium methods --- example/screenshot.py | 9 ++++--- tests/test_integration.py | 54 ++++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/example/screenshot.py b/example/screenshot.py index 8c1135eb2..129465d79 100644 --- a/example/screenshot.py +++ b/example/screenshot.py @@ -5,6 +5,7 @@ import subprocess from time import sleep +from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait @@ -54,7 +55,7 @@ def set_viewport_size(selenium, width, height): def submit_form(selenium, data): url = selenium.current_url for name, value in data.items(): - el = selenium.find_element_by_name(name) + el = selenium.find_element(By.NAME, name) el.send_keys(value) el.send_keys(Keys.RETURN) WebDriverWait(selenium, timeout=5).until(EC.url_changes(url)) @@ -72,12 +73,12 @@ def main(): selenium.get("http://localhost:8000/admin/auth/user/") # Check if SQL Panel is already visible: - sql_panel = selenium.find_element_by_id("djdt-SQLPanel") + sql_panel = selenium.find_element(By.ID, "djdt-SQLPanel") if not sql_panel: # Open the admin sidebar. - el = selenium.find_element_by_id("djDebugToolbarHandle") + el = selenium.find_element(By.ID, "djDebugToolbarHandle") el.click() - sql_panel = selenium.find_element_by_id("djdt-SQLPanel") + sql_panel = selenium.find_element(By.ID, "djdt-SQLPanel") # Open the SQL panel. sql_panel.click() diff --git a/tests/test_integration.py b/tests/test_integration.py index 016b52217..e9962b32b 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -482,18 +482,18 @@ def wait(self): def test_basic(self): self.get("/regular/basic/") - version_panel = self.selenium.find_element_by_id("VersionsPanel") + version_panel = self.selenium.find_element(By.ID, "VersionsPanel") # Versions panel isn't loaded with self.assertRaises(NoSuchElementException): - version_panel.find_element_by_tag_name("table") + version_panel.find_element(By.TAG_NAME, "table") # Click to show the versions panel - self.selenium.find_element_by_class_name("VersionsPanel").click() + self.selenium.find_element(By.CLASS_NAME, "VersionsPanel").click() # Version panel loads table = self.wait.until( - lambda selenium: version_panel.find_element_by_tag_name("table") + lambda selenium: version_panel.find_element(By.TAG_NAME, "table") ) self.assertIn("Name", table.text) self.assertIn("Version", table.text) @@ -505,10 +505,10 @@ def test_basic(self): ) def test_basic_jinja(self): self.get("/regular_jinja/basic") - template_panel = self.selenium.find_element_by_id("TemplatesPanel") + template_panel = self.selenium.find_element(By.ID, "TemplatesPanel") # Click to show the template panel - self.selenium.find_element_by_class_name("TemplatesPanel").click() + self.selenium.find_element(By.CLASS_NAME, "TemplatesPanel").click() self.assertIn("Templates (2 rendered)", template_panel.text) self.assertIn("base.html", template_panel.text) @@ -523,18 +523,20 @@ def test_rerender_on_history_switch(self): self.get("/regular_jinja/basic") # Make a new request so the history panel has more than one option. self.get("/execute_sql/") - template_panel = self.selenium.find_element_by_id("HistoryPanel") + template_panel = self.selenium.find_element(By.ID, "HistoryPanel") # Record the current side panel of buttons for later comparison. - previous_button_panel = self.selenium.find_element_by_id( - "djDebugPanelList" + previous_button_panel = self.selenium.find_element( + By.ID, "djDebugPanelList" ).text # Click to show the history panel - self.selenium.find_element_by_class_name("HistoryPanel").click() + self.selenium.find_element(By.CLASS_NAME, "HistoryPanel").click() # Click to switch back to the jinja page view snapshot - list(template_panel.find_elements_by_css_selector("button"))[-1].click() + list(template_panel.find_elements(By.CSS_SELECTOR, "button"))[-1].click() - current_button_panel = self.selenium.find_element_by_id("djDebugPanelList").text + current_button_panel = self.selenium.find_element( + By.ID, "djDebugPanelList" + ).text # Verify the button side panels have updated. self.assertNotEqual(previous_button_panel, current_button_panel) self.assertNotIn("1 query", current_button_panel) @@ -543,14 +545,14 @@ def test_rerender_on_history_switch(self): @override_settings(DEBUG_TOOLBAR_CONFIG={"RESULTS_CACHE_SIZE": 0}) def test_expired_store(self): self.get("/regular/basic/") - version_panel = self.selenium.find_element_by_id("VersionsPanel") + version_panel = self.selenium.find_element(By.ID, "VersionsPanel") # Click to show the version panel - self.selenium.find_element_by_class_name("VersionsPanel").click() + self.selenium.find_element(By.CLASS_NAME, "VersionsPanel").click() # Version panel doesn't loads error = self.wait.until( - lambda selenium: version_panel.find_element_by_tag_name("p") + lambda selenium: version_panel.find_element(By.TAG_NAME, "p") ) self.assertIn("Data for this panel isn't available anymore.", error.text) @@ -574,31 +576,31 @@ def test_expired_store(self): ) def test_django_cached_template_loader(self): self.get("/regular/basic/") - version_panel = self.selenium.find_element_by_id("TemplatesPanel") + version_panel = self.selenium.find_element(By.ID, "TemplatesPanel") # Click to show the templates panel - self.selenium.find_element_by_class_name("TemplatesPanel").click() + self.selenium.find_element(By.CLASS_NAME, "TemplatesPanel").click() # Templates panel loads trigger = self.wait.until( - lambda selenium: version_panel.find_element_by_css_selector(".remoteCall") + lambda selenium: version_panel.find_element(By.CSS_SELECTOR, ".remoteCall") ) trigger.click() # Verify the code is displayed self.wait.until( - lambda selenium: self.selenium.find_element_by_css_selector( - "#djDebugWindow code" + lambda selenium: self.selenium.find_element( + By.CSS_SELECTOR, "#djDebugWindow code" ) ) def test_sql_action_and_go_back(self): self.get("/execute_sql/") - sql_panel = self.selenium.find_element_by_id("SQLPanel") - debug_window = self.selenium.find_element_by_id("djDebugWindow") + sql_panel = self.selenium.find_element(By.ID, "SQLPanel") + debug_window = self.selenium.find_element(By.ID, "djDebugWindow") # Click to show the SQL panel - self.selenium.find_element_by_class_name("SQLPanel").click() + self.selenium.find_element(By.CLASS_NAME, "SQLPanel").click() # SQL panel loads button = self.wait.until( @@ -611,7 +613,7 @@ def test_sql_action_and_go_back(self): self.assertIn("SQL selected", debug_window.text) # Close the SQL selected window - debug_window.find_element_by_class_name("djDebugClose").click() + debug_window.find_element(By.CLASS_NAME, "djDebugClose").click() self.wait.until(EC.invisibility_of_element(debug_window)) # SQL panel is still visible @@ -620,7 +622,7 @@ def test_sql_action_and_go_back(self): @override_settings(DEBUG_TOOLBAR_PANELS=["tests.test_integration.BuggyPanel"]) def test_displays_server_error(self): self.get("/regular/basic/") - debug_window = self.selenium.find_element_by_id("djDebugWindow") - self.selenium.find_element_by_class_name("BuggyPanel").click() + debug_window = self.selenium.find_element(By.ID, "djDebugWindow") + self.selenium.find_element(By.CLASS_NAME, "BuggyPanel").click() self.wait.until(EC.visibility_of(debug_window)) self.assertEqual(debug_window.text, "»\n500: Internal Server Error") From 80d606307d95995156b59c47bd5895d09492d8b3 Mon Sep 17 00:00:00 2001 From: Hasan Ramezani Date: Wed, 3 Aug 2022 16:01:12 +0200 Subject: [PATCH 14/20] Add Django 4.1 to classifiers (#1656) --- setup.cfg | 1 + tox.ini | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 3017b5e74..a5f1a19b8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,6 +16,7 @@ classifiers = Framework :: Django Framework :: Django :: 3.2 Framework :: Django :: 4.0 + Framework :: Django :: 4.1 Intended Audience :: Developers License :: OSI Approved :: BSD License Operating System :: OS Independent diff --git a/tox.ini b/tox.ini index d5e2d669b..ae3936228 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ envlist = deps = dj32: django~=3.2.9 dj40: django~=4.0.0 - dj41: django>=4.1b1,<4.2 + dj41: django~=4.1.0 postgresql: psycopg2-binary postgis: psycopg2-binary mysql: mysqlclient From a44c91d72eea3739e0c7bd464cd20ecd18d6808a Mon Sep 17 00:00:00 2001 From: Tim Schilling Date: Thu, 4 Aug 2022 13:45:18 -0500 Subject: [PATCH 15/20] Remove signed_data_view decorator to support url type checking. (#1658) * Remove signed_data_view decorator to support url type checking. The package django-urlconfchecks was erroring on the toolbar's URLs because signed_data_view was injecting an extra parameter for the views. The alternative to the decorator isn't terrible so let's use that instead. Eventually this can be shortened with the walrus operator when py37 support is dropped. * Use django-urlconfchecks in a URL to avoid adding it to docs' words list. --- debug_toolbar/decorators.py | 20 +------------------- debug_toolbar/forms.py | 1 - debug_toolbar/panels/sql/views.py | 30 +++++++++++++++++++++++------- docs/changes.rst | 6 ++++++ 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/debug_toolbar/decorators.py b/debug_toolbar/decorators.py index 2abfb22f9..8114b05d7 100644 --- a/debug_toolbar/decorators.py +++ b/debug_toolbar/decorators.py @@ -1,6 +1,6 @@ import functools -from django.http import Http404, HttpResponseBadRequest +from django.http import Http404 def require_show_toolbar(view): @@ -15,21 +15,3 @@ def inner(request, *args, **kwargs): return view(request, *args, **kwargs) return inner - - -def signed_data_view(view): - """Decorator that handles unpacking a signed data form""" - - @functools.wraps(view) - def inner(request, *args, **kwargs): - from debug_toolbar.forms import SignedDataForm - - data = request.GET if request.method == "GET" else request.POST - signed_form = SignedDataForm(data) - if signed_form.is_valid(): - return view( - request, *args, verified_data=signed_form.verified_data(), **kwargs - ) - return HttpResponseBadRequest("Invalid signature") - - return inner diff --git a/debug_toolbar/forms.py b/debug_toolbar/forms.py index 3c7a45a07..1263c3aff 100644 --- a/debug_toolbar/forms.py +++ b/debug_toolbar/forms.py @@ -21,7 +21,6 @@ class PanelForm(forms.Form): panel_form = PanelForm(signed_form.verified_data) if panel_form.is_valid(): # Success - Or wrap the FBV with ``debug_toolbar.decorators.signed_data_view`` """ salt = "django_debug_toolbar" diff --git a/debug_toolbar/panels/sql/views.py b/debug_toolbar/panels/sql/views.py index 49ffee515..fabca7a57 100644 --- a/debug_toolbar/panels/sql/views.py +++ b/debug_toolbar/panels/sql/views.py @@ -2,15 +2,27 @@ from django.template.loader import render_to_string from django.views.decorators.csrf import csrf_exempt -from debug_toolbar.decorators import require_show_toolbar, signed_data_view +from debug_toolbar.decorators import require_show_toolbar +from debug_toolbar.forms import SignedDataForm from debug_toolbar.panels.sql.forms import SQLSelectForm +def get_signed_data(request): + """Unpack a signed data form, if invalid returns None""" + data = request.GET if request.method == "GET" else request.POST + signed_form = SignedDataForm(data) + if signed_form.is_valid(): + return signed_form.verified_data() + return None + + @csrf_exempt @require_show_toolbar -@signed_data_view -def sql_select(request, verified_data): +def sql_select(request): """Returns the output of the SQL SELECT statement""" + verified_data = get_signed_data(request) + if not verified_data: + return HttpResponseBadRequest("Invalid signature") form = SQLSelectForm(verified_data) if form.is_valid(): @@ -35,9 +47,11 @@ def sql_select(request, verified_data): @csrf_exempt @require_show_toolbar -@signed_data_view -def sql_explain(request, verified_data): +def sql_explain(request): """Returns the output of the SQL EXPLAIN on the given query""" + verified_data = get_signed_data(request) + if not verified_data: + return HttpResponseBadRequest("Invalid signature") form = SQLSelectForm(verified_data) if form.is_valid(): @@ -71,9 +85,11 @@ def sql_explain(request, verified_data): @csrf_exempt @require_show_toolbar -@signed_data_view -def sql_profile(request, verified_data): +def sql_profile(request): """Returns the output of running the SQL and getting the profiling statistics""" + verified_data = get_signed_data(request) + if not verified_data: + return HttpResponseBadRequest("Invalid signature") form = SQLSelectForm(verified_data) if form.is_valid(): diff --git a/docs/changes.rst b/docs/changes.rst index 25ef409fc..a7335e531 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -1,6 +1,12 @@ Change log ========== +Pending +------- + +* Remove decorator ``signed_data_view`` as it was causing issues with + `django-urlconfchecks `__. + 3.5.0 (2022-06-23) ------------------ From 28c0a9321728ea0f8d24c7498a5da0a981709247 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 8 Aug 2022 18:17:59 +0000 Subject: [PATCH 16/20] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pycqa/flake8: 5.0.2 → 5.0.4](https://github.com/pycqa/flake8/compare/5.0.2...5.0.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a9f8410f2..a0f8b551d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: - id: trailing-whitespace - id: mixed-line-ending - repo: https://github.com/pycqa/flake8 - rev: 5.0.2 + rev: 5.0.4 hooks: - id: flake8 - repo: https://github.com/pycqa/doc8 From 0310296082d4d0a210345e2c88ff2683d188ccd9 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 10 Aug 2022 14:47:45 +0200 Subject: [PATCH 17/20] Upgrade GitHub Actions --- .github/workflows/test.yml | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 73733c293..7dd8409a8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,10 +30,10 @@ jobs: - 3306:3306 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -43,7 +43,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: @@ -71,7 +71,7 @@ jobs: DB_PORT: 3306 - name: Upload coverage data - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: coverage-data path: ".coverage.*" @@ -101,10 +101,10 @@ jobs: --health-retries 5 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -114,7 +114,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: @@ -140,7 +140,7 @@ jobs: DB_PORT: 5432 - name: Upload coverage data - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: coverage-data path: ".coverage.*" @@ -154,10 +154,10 @@ jobs: python-version: ['3.7', '3.8', '3.9', '3.10'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -167,7 +167,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: @@ -187,7 +187,7 @@ jobs: DB_NAME: ":memory:" - name: Upload coverage data - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: coverage-data path: ".coverage.*" @@ -197,8 +197,8 @@ jobs: runs-on: "ubuntu-latest" needs: [sqlite, mysql, postgres] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: # Use latest, so it understands all syntax. python-version: "3.10" @@ -206,7 +206,7 @@ jobs: - run: python -m pip install --upgrade coverage - name: Download coverage data. - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: coverage-data @@ -217,7 +217,7 @@ jobs: python -m coverage report - name: Upload HTML report if check failed. - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: html-report path: htmlcov @@ -229,10 +229,10 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.8 @@ -242,7 +242,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: From fa2774eb6cbd2f7e9c2a0f0f27a899a9018af55f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 16 Aug 2022 16:06:29 +0200 Subject: [PATCH 18/20] [pre-commit.ci] pre-commit autoupdate (#1661) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/adamchainz/django-upgrade: 1.7.0 → 1.8.0](https://github.com/adamchainz/django-upgrade/compare/1.7.0...1.8.0) - [github.com/pre-commit/mirrors-eslint: v8.21.0 → v8.22.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.21.0...v8.22.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a0f8b551d..36baad66d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/adamchainz/django-upgrade - rev: 1.7.0 + rev: 1.8.0 hooks: - id: django-upgrade args: [--target-version, "3.2"] @@ -43,7 +43,7 @@ repos: - id: prettier types_or: [javascript, css] - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.21.0 + rev: v8.22.0 hooks: - id: eslint files: \.js?$ From f1c03eb8e5990d846db14994c209eb9668cb3cee Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Wed, 17 Aug 2022 19:36:24 +0200 Subject: [PATCH 19/20] Fix #1662: Avoid assigning arbitrary attributes to SafeString instances (#1663) --- debug_toolbar/panels/templates/views.py | 9 ++++----- .../templates/debug_toolbar/panels/template_source.html | 6 +----- tox.ini | 1 + 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/debug_toolbar/panels/templates/views.py b/debug_toolbar/panels/templates/views.py index 8d6d634d3..134b3d476 100644 --- a/debug_toolbar/panels/templates/views.py +++ b/debug_toolbar/panels/templates/views.py @@ -3,7 +3,7 @@ from django.template import Origin, TemplateDoesNotExist from django.template.engine import Engine from django.template.loader import render_to_string -from django.utils.safestring import mark_safe +from django.utils.html import format_html, mark_safe from debug_toolbar.decorators import require_show_toolbar @@ -50,12 +50,11 @@ def template_source(request): from pygments import highlight from pygments.formatters import HtmlFormatter from pygments.lexers import HtmlDjangoLexer - + except ModuleNotFoundError: + source = format_html("{}", source) + else: source = highlight(source, HtmlDjangoLexer(), HtmlFormatter()) source = mark_safe(source) - source.pygmentized = True - except ImportError: - pass content = render_to_string( "debug_toolbar/panels/template_source.html", diff --git a/debug_toolbar/templates/debug_toolbar/panels/template_source.html b/debug_toolbar/templates/debug_toolbar/panels/template_source.html index 229ea83e4..397c44b24 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/template_source.html +++ b/debug_toolbar/templates/debug_toolbar/panels/template_source.html @@ -5,10 +5,6 @@

{% trans "Template source:" %} {{ template_name }}

- {% if not source.pygmentized %} - {{ source }} - {% else %} - {{ source }} - {% endif %} + {{ source }}
diff --git a/tox.ini b/tox.ini index ae3936228..ad2e6c090 100644 --- a/tox.ini +++ b/tox.ini @@ -17,6 +17,7 @@ deps = coverage Jinja2 html5lib + pygments selenium sqlparse passenv= From eb7c4cd50e341650765577b2b5a5a5531254be29 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Wed, 17 Aug 2022 22:14:11 +0200 Subject: [PATCH 20/20] django-debug-toolbar 3.6 --- README.rst | 2 +- debug_toolbar/__init__.py | 2 +- docs/changes.rst | 11 +++++++++++ docs/conf.py | 2 +- docs/spelling_wordlist.txt | 4 ++++ setup.cfg | 2 +- 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 9c22acdcc..c7ea51bd6 100644 --- a/README.rst +++ b/README.rst @@ -44,7 +44,7 @@ Here's a screenshot of the toolbar in action: In addition to the built-in panels, a number of third-party panels are contributed by the community. -The current stable version of the Debug Toolbar is 3.5.0. It works on +The current stable version of the Debug Toolbar is 3.6.0. It works on Django ≥ 3.2.4. Documentation, including installation and configuration instructions, is diff --git a/debug_toolbar/__init__.py b/debug_toolbar/__init__.py index c9834b8e3..17f1f9e69 100644 --- a/debug_toolbar/__init__.py +++ b/debug_toolbar/__init__.py @@ -4,7 +4,7 @@ # Do not use pkg_resources to find the version but set it here directly! # see issue #1446 -VERSION = "3.5.0" +VERSION = "3.6.0" # Code that discovers files or modules in INSTALLED_APPS imports this module. urls = "debug_toolbar.urls", APP_NAME diff --git a/docs/changes.rst b/docs/changes.rst index a7335e531..df6be99f2 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -4,8 +4,19 @@ Change log Pending ------- +3.6.0 (2022-08-17) +------------------ + * Remove decorator ``signed_data_view`` as it was causing issues with `django-urlconfchecks `__. +* Added pygments to the test environment and fixed a crash when using the + template panel with Django 4.1 and pygments installed. +* Stayed on top of pre-commit hook and GitHub actions updates. +* Added some workarounds to avoid a Chromium warning which was worrisome to + developers. +* Avoided using deprecated Selenium methods to find elements. +* Raised the minimum Django version from 3.2 to 3.2.4 so that we can take + advantage of backported improvements to the cache connection handler. 3.5.0 (2022-06-23) ------------------ diff --git a/docs/conf.py b/docs/conf.py index 374acd1d2..476a055de 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -25,7 +25,7 @@ copyright = copyright.format(datetime.date.today().year) # The full version, including alpha/beta/rc tags -release = "3.5.0" +release = "3.6.0" # -- General configuration --------------------------------------------------- diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 0ca7eb8b0..ee911963f 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -1,5 +1,6 @@ backend backends +backported checkbox contrib django @@ -30,9 +31,12 @@ pylibmc Pympler querysets refactoring +resizing +spellchecking spooler stacktrace stacktraces +startup timeline tox Transifex diff --git a/setup.cfg b/setup.cfg index a5f1a19b8..5daaee0bd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = django-debug-toolbar -version = 3.5.0 +version = 3.6.0 description = A configurable set of panels that display various debug information about the current request/response. long_description = file: README.rst long_description_content_type = text/x-rst