From 81222b86bc0905b639a7424331d4980c7d356e02 Mon Sep 17 00:00:00 2001 From: Patrick Hintermayer Date: Sat, 19 Aug 2023 00:05:28 +0200 Subject: [PATCH 01/28] docs(panels): remove very old / outdated third-party panels (#1825) * docs(panels): remove very old / outdated third-party panels --- docs/changes.rst | 2 ++ docs/panels.rst | 42 ------------------------------------------ 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index 89f5bdc7e..ad3cab34c 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -4,6 +4,8 @@ Change log Pending ------- +* Removed outdated third-party panels from the list. + 4.2.0 (2023-08-10) ------------------ diff --git a/docs/panels.rst b/docs/panels.rst index 61a23ce61..db4e9311f 100644 --- a/docs/panels.rst +++ b/docs/panels.rst @@ -152,27 +152,6 @@ using Brendan Gregg's `flamegraph.pl script `_ to perform the heavy lifting. -HTML Tidy/Validator -~~~~~~~~~~~~~~~~~~~ - -URL: https://github.com/joymax/django-dtpanel-htmltidy - -Path: ``debug_toolbar_htmltidy.panels.HTMLTidyDebugPanel`` - -HTML Tidy or HTML Validator is a custom panel that validates your HTML and -displays warnings and errors. - -Inspector -~~~~~~~~~ - -URL: https://github.com/santiagobasulto/debug-inspector-panel - -Path: ``inspector_panel.panels.inspector.InspectorPanel`` - -Retrieves and displays information you specify using the ``debug`` statement. -Inspector panel also logs to the console by default, but may be instructed not -to. - LDAP Tracing ~~~~~~~~~~~~ @@ -276,18 +255,6 @@ Path: ``requests_panel.panel.RequestsDebugPanel`` Lists HTTP requests made with the popular `requests `_ library. -Sites -~~~~~ - -URL: https://github.com/elvard/django-sites-toolbar - -Path: ``sites_toolbar.panels.SitesDebugPanel`` - -Browse Sites registered in ``django.contrib.sites`` and switch between them. -Useful to debug project when you use `django-dynamicsites -`_ which sets SITE_ID -dynamically. - Template Profiler ~~~~~~~~~~~~~~~~~ @@ -308,15 +275,6 @@ Path: ``template_timings_panel.panels.TemplateTimings.TemplateTimings`` Displays template rendering times for your Django application. -User -~~~~ - -URL: https://github.com/playfire/django-debug-toolbar-user-panel - -Path: ``debug_toolbar_user_panel.panels.UserPanel`` - -Easily switch between logged in users, see properties of current user. - VCS Info ~~~~~~~~ From c911d73b768d983a74c5b6405e23f997d343b8da Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:15:44 +0000 Subject: [PATCH 02/28] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-eslint: v8.46.0 → v8.47.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.46.0...v8.47.0) - [github.com/astral-sh/ruff-pre-commit: v0.0.282 → v0.0.284](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.282...v0.0.284) - [github.com/tox-dev/pyproject-fmt: 0.13.0 → 0.13.1](https://github.com/tox-dev/pyproject-fmt/compare/0.13.0...0.13.1) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 001b07e34..57772e4f4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.46.0 + rev: v8.47.0 hooks: - id: eslint files: \.js?$ @@ -39,7 +39,7 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.0.282' + rev: 'v0.0.284' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] @@ -50,7 +50,7 @@ repos: language_version: python3 entry: black --target-version=py38 - repo: https://github.com/tox-dev/pyproject-fmt - rev: 0.13.0 + rev: 0.13.1 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject From a344da1b4425f0563d32589445ffb092c1653077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Salomv=C3=A1ry?= Date: Wed, 30 Aug 2023 18:01:57 +0200 Subject: [PATCH 03/28] Add note on lack of async support to docs (#1829) * Add note on lack of async support to Installation docs * Add note on lack of async support to the Readme https://github.com/jazzband/django-debug-toolbar/issues/1828#issuecomment-1699339721 --- README.rst | 3 +++ docs/installation.rst | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/README.rst b/README.rst index b10a9ad91..0eaaa6bd3 100644 --- a/README.rst +++ b/README.rst @@ -47,6 +47,9 @@ contributed by the community. The current stable version of the Debug Toolbar is 4.1.0. It works on Django ≥ 3.2.4. +The Debug Toolbar does not currently support `Django's asynchronous views +`_. + Documentation, including installation and configuration instructions, is available at https://django-debug-toolbar.readthedocs.io/. diff --git a/docs/installation.rst b/docs/installation.rst index 3b65ff8e2..a350d9c3a 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -7,6 +7,10 @@ Process Each of the following steps needs to be configured for the Debug Toolbar to be fully functional. +.. warning:: + + The Debug Toolbar does not currently support `Django's asynchronous views `_. + 1. Install the Package ^^^^^^^^^^^^^^^^^^^^^^ From 199c2b3c6bc916d371bcfb11b0fcbbb690ee5e36 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 20:06:37 +0000 Subject: [PATCH 04/28] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/adamchainz/django-upgrade: 1.14.0 → 1.14.1](https://github.com/adamchainz/django-upgrade/compare/1.14.0...1.14.1) - [github.com/pre-commit/mirrors-prettier: v3.0.1 → v3.0.2](https://github.com/pre-commit/mirrors-prettier/compare/v3.0.1...v3.0.2) - [github.com/pre-commit/mirrors-eslint: v8.47.0 → v8.48.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.47.0...v8.48.0) - [github.com/astral-sh/ruff-pre-commit: v0.0.284 → v0.0.286](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.284...v0.0.286) - [github.com/tox-dev/pyproject-fmt: 0.13.1 → 1.1.0](https://github.com/tox-dev/pyproject-fmt/compare/0.13.1...1.1.0) - [github.com/abravalheri/validate-pyproject: v0.13 → v0.14](https://github.com/abravalheri/validate-pyproject/compare/v0.13...v0.14) --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 57772e4f4..fa7c34249 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: doc8 - repo: https://github.com/adamchainz/django-upgrade - rev: 1.14.0 + rev: 1.14.1 hooks: - id: django-upgrade args: [--target-version, "3.2"] @@ -24,14 +24,14 @@ repos: - id: rst-backticks - id: rst-directive-colons - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.1 + rev: v3.0.2 hooks: - id: prettier types_or: [javascript, css] args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.47.0 + rev: v8.48.0 hooks: - id: eslint files: \.js?$ @@ -39,7 +39,7 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.0.284' + rev: 'v0.0.286' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] @@ -50,10 +50,10 @@ repos: language_version: python3 entry: black --target-version=py38 - repo: https://github.com/tox-dev/pyproject-fmt - rev: 0.13.1 + rev: 1.1.0 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.13 + rev: v0.14 hooks: - id: validate-pyproject From 5d5d459b4bad6a4fa20f81558d3d46cc0e02566c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 07:17:58 +0200 Subject: [PATCH 05/28] [pre-commit.ci] pre-commit autoupdate (#1830) --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fa7c34249..f4796b196 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: doc8 - repo: https://github.com/adamchainz/django-upgrade - rev: 1.14.1 + rev: 1.15.0 hooks: - id: django-upgrade args: [--target-version, "3.2"] @@ -24,14 +24,14 @@ repos: - id: rst-backticks - id: rst-directive-colons - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.2 + rev: v3.0.3 hooks: - id: prettier types_or: [javascript, css] args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.48.0 + rev: v8.50.0 hooks: - id: eslint files: \.js?$ @@ -39,12 +39,12 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.0.286' + rev: 'v0.0.291' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 23.9.1 hooks: - id: black language_version: python3 From 06c42d9760438d693df0527ada7a547c1d0eaf88 Mon Sep 17 00:00:00 2001 From: tkoschnick Date: Tue, 26 Sep 2023 07:18:29 +0200 Subject: [PATCH 06/28] do not quote SQL params before passing them to mogrify (#1832) --- debug_toolbar/panels/sql/tracking.py | 19 +------------------ docs/changes.rst | 1 + 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/debug_toolbar/panels/sql/tracking.py b/debug_toolbar/panels/sql/tracking.py index 0c53dc2c5..b5fc81234 100644 --- a/debug_toolbar/panels/sql/tracking.py +++ b/debug_toolbar/panels/sql/tracking.py @@ -109,21 +109,6 @@ class NormalCursorMixin(DjDTCursorWrapperMixin): Wraps a cursor and logs queries. """ - def _quote_expr(self, element): - if isinstance(element, str): - return "'%s'" % element.replace("'", "''") - else: - return repr(element) - - def _quote_params(self, params): - if not params: - return params - if isinstance(params, dict): - return {key: self._quote_expr(value) for key, value in params.items()} - if isinstance(params, tuple): - return tuple(self._quote_expr(p) for p in params) - return [self._quote_expr(p) for p in params] - def _decode(self, param): if PostgresJson and isinstance(param, PostgresJson): # psycopg3 @@ -157,9 +142,7 @@ def _last_executed_query(self, sql, params): # process during the .last_executed_query() call. self.db._djdt_logger = None try: - return self.db.ops.last_executed_query( - self.cursor, sql, self._quote_params(params) - ) + return self.db.ops.last_executed_query(self.cursor, sql, params) finally: self.db._djdt_logger = self.logger diff --git a/docs/changes.rst b/docs/changes.rst index ad3cab34c..24679bfd1 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -5,6 +5,7 @@ Pending ------- * Removed outdated third-party panels from the list. +* Avoided the unnecessary work of recursively quoting SQL parameters. 4.2.0 (2023-08-10) ------------------ From 3ceb9655e216dd9fcf1222a09cc3199e22c30762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Tue, 26 Sep 2023 07:30:36 +0200 Subject: [PATCH 07/28] panels(templates): avoid evaluating LazyObject (#1833) * panels(templates): postpone context processing - this makes it show evaluated querysets which were used in the template - removes completely context processing when SHOW_TEMPLATE_CONTEXT is disabled * panels(templates): avoid evaluating LazyObject LazyObject is typically used for something expensive to evaluate, so avoid evaluating it just for showing it in the debug toolbar. --- debug_toolbar/panels/templates/panel.py | 122 +++++++++++++----------- docs/changes.rst | 4 + tests/panels/test_template.py | 25 ++++- 3 files changed, 95 insertions(+), 56 deletions(-) diff --git a/debug_toolbar/panels/templates/panel.py b/debug_toolbar/panels/templates/panel.py index 72565f016..e63417fa9 100644 --- a/debug_toolbar/panels/templates/panel.py +++ b/debug_toolbar/panels/templates/panel.py @@ -83,58 +83,11 @@ def _store_template_info(self, sender, **kwargs): if is_debug_toolbar_template: return - context_list = [] - for context_layer in context.dicts: - if hasattr(context_layer, "items") and context_layer: - # Check if the layer is in the cache. - pformatted = None - for key_values, _pformatted in self.pformat_layers: - if key_values == context_layer: - pformatted = _pformatted - break - - if pformatted is None: - temp_layer = {} - for key, value in context_layer.items(): - # Replace any request elements - they have a large - # Unicode representation and the request data is - # already made available from the Request panel. - if isinstance(value, http.HttpRequest): - temp_layer[key] = "<>" - # Replace the debugging sql_queries element. The SQL - # data is already made available from the SQL panel. - elif key == "sql_queries" and isinstance(value, list): - temp_layer[key] = "<>" - # Replace LANGUAGES, which is available in i18n context - # processor - elif key == "LANGUAGES" and isinstance(value, tuple): - temp_layer[key] = "<>" - # QuerySet would trigger the database: user can run the - # query from SQL Panel - elif isinstance(value, (QuerySet, RawQuerySet)): - temp_layer[key] = "<<{} of {}>>".format( - value.__class__.__name__.lower(), - value.model._meta.label, - ) - else: - token = allow_sql.set(False) # noqa: FBT003 - try: - saferepr(value) # this MAY trigger a db query - except SQLQueryTriggered: - temp_layer[key] = "<>" - except UnicodeEncodeError: - temp_layer[key] = "<>" - except Exception: - temp_layer[key] = "<>" - else: - temp_layer[key] = value - finally: - allow_sql.reset(token) - pformatted = pformat(temp_layer) - self.pformat_layers.append((context_layer, pformatted)) - context_list.append(pformatted) - - kwargs["context"] = context_list + kwargs["context"] = [ + context_layer + for context_layer in context.dicts + if hasattr(context_layer, "items") and context_layer + ] kwargs["context_processors"] = getattr(context, "context_processors", None) self.templates.append(kwargs) @@ -167,6 +120,64 @@ def enable_instrumentation(self): def disable_instrumentation(self): template_rendered.disconnect(self._store_template_info) + def process_context_list(self, context_layers): + context_list = [] + for context_layer in context_layers: + # Check if the layer is in the cache. + pformatted = None + for key_values, _pformatted in self.pformat_layers: + if key_values == context_layer: + pformatted = _pformatted + break + + if pformatted is None: + temp_layer = {} + for key, value in context_layer.items(): + # Do not force evaluating LazyObject + if hasattr(value, "_wrapped"): + # SimpleLazyObject has __repr__ which includes actual value + # if it has been already evaluated + temp_layer[key] = repr(value) + # Replace any request elements - they have a large + # Unicode representation and the request data is + # already made available from the Request panel. + elif isinstance(value, http.HttpRequest): + temp_layer[key] = "<>" + # Replace the debugging sql_queries element. The SQL + # data is already made available from the SQL panel. + elif key == "sql_queries" and isinstance(value, list): + temp_layer[key] = "<>" + # Replace LANGUAGES, which is available in i18n context + # processor + elif key == "LANGUAGES" and isinstance(value, tuple): + temp_layer[key] = "<>" + # QuerySet would trigger the database: user can run the + # query from SQL Panel + elif isinstance(value, (QuerySet, RawQuerySet)): + temp_layer[key] = "<<{} of {}>>".format( + value.__class__.__name__.lower(), + value.model._meta.label, + ) + else: + token = allow_sql.set(False) # noqa: FBT003 + try: + saferepr(value) # this MAY trigger a db query + except SQLQueryTriggered: + temp_layer[key] = "<>" + except UnicodeEncodeError: + temp_layer[key] = "<>" + except Exception: + temp_layer[key] = "<>" + else: + temp_layer[key] = value + finally: + allow_sql.reset(token) + pformatted = pformat(temp_layer) + self.pformat_layers.append((context_layer, pformatted)) + context_list.append(pformatted) + + return context_list + def generate_stats(self, request, response): template_context = [] for template_data in self.templates: @@ -182,8 +193,11 @@ def generate_stats(self, request, response): info["template"] = template # Clean up context for better readability if self.toolbar.config["SHOW_TEMPLATE_CONTEXT"]: - context_list = template_data.get("context", []) - info["context"] = "\n".join(context_list) + if "context_list" not in template_data: + template_data["context_list"] = self.process_context_list( + template_data.get("context", []) + ) + info["context"] = "\n".join(template_data["context_list"]) template_context.append(info) # Fetch context_processors/template_dirs from any template diff --git a/docs/changes.rst b/docs/changes.rst index 24679bfd1..ab774136d 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -6,6 +6,10 @@ Pending * Removed outdated third-party panels from the list. * Avoided the unnecessary work of recursively quoting SQL parameters. +* Postponed context process in templates panel to include lazy evaluated + content. +* Fixed template panel to avoid evaluating ``LazyObject`` when not already + evaluated. 4.2.0 (2023-08-10) ------------------ diff --git a/tests/panels/test_template.py b/tests/panels/test_template.py index 37e70cfa5..eb23cde31 100644 --- a/tests/panels/test_template.py +++ b/tests/panels/test_template.py @@ -2,6 +2,7 @@ from django.contrib.auth.models import User from django.template import Context, RequestContext, Template from django.test import override_settings +from django.utils.functional import SimpleLazyObject from ..base import BaseTestCase, IntegrationTestCase from ..forms import TemplateReprForm @@ -21,6 +22,7 @@ def tearDown(self): super().tearDown() def test_queryset_hook(self): + response = self.panel.process_request(self.request) t = Template("No context variables here!") c = Context( { @@ -29,12 +31,13 @@ def test_queryset_hook(self): } ) t.render(c) + self.panel.generate_stats(self.request, response) # ensure the query was NOT logged self.assertEqual(len(self.sql_panel._queries), 0) self.assertEqual( - self.panel.templates[0]["context"], + self.panel.templates[0]["context_list"], [ "{'False': False, 'None': None, 'True': True}", "{'deep_queryset': '<>',\n" @@ -99,16 +102,34 @@ def test_disabled(self): self.assertFalse(self.panel.enabled) def test_empty_context(self): + response = self.panel.process_request(self.request) t = Template("") c = Context({}) t.render(c) + self.panel.generate_stats(self.request, response) # Includes the builtin context but not the empty one. self.assertEqual( - self.panel.templates[0]["context"], + self.panel.templates[0]["context_list"], ["{'False': False, 'None': None, 'True': True}"], ) + def test_lazyobject(self): + response = self.panel.process_request(self.request) + t = Template("") + c = Context({"lazy": SimpleLazyObject(lambda: "lazy_value")}) + t.render(c) + self.panel.generate_stats(self.request, response) + self.assertNotIn("lazy_value", self.panel.content) + + def test_lazyobject_eval(self): + response = self.panel.process_request(self.request) + t = Template("{{lazy}}") + c = Context({"lazy": SimpleLazyObject(lambda: "lazy_value")}) + self.assertEqual(t.render(c), "lazy_value") + self.panel.generate_stats(self.request, response) + self.assertIn("lazy_value", self.panel.content) + @override_settings( DEBUG=True, DEBUG_TOOLBAR_PANELS=["debug_toolbar.panels.templates.TemplatesPanel"] From 58293b40252548abb9a1728a5f2fe301e6cf5b84 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 13 Oct 2023 22:53:05 +0100 Subject: [PATCH 08/28] Support Django 5.0 --- docs/changes.rst | 1 + pyproject.toml | 1 + tox.ini | 11 ++++++----- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index ab774136d..638d2d658 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -10,6 +10,7 @@ Pending content. * Fixed template panel to avoid evaluating ``LazyObject`` when not already evaluated. +* Added support for Django 5.0. 4.2.0 (2023-08-10) ------------------ diff --git a/pyproject.toml b/pyproject.toml index 637dada5e..a40af2769 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ classifiers = [ "Framework :: Django :: 4.0", "Framework :: Django :: 4.1", "Framework :: Django :: 4.2", + "Framework :: Django :: 5.0", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", diff --git a/tox.ini b/tox.ini index 5154d4907..1bbdef0e1 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,7 @@ envlist = py{38,39,310}-dj32-{sqlite,postgresql,postgis,mysql} py310-dj40-sqlite py{310,311}-dj41-{sqlite,postgresql,postgis,mysql} - py{310,311}-dj{42,main}-{sqlite,postgresql,psycopg3,postgis,mysql} + py{310,311}-dj{42,50,main}-{sqlite,postgresql,psycopg3,postgis,mysql} [testenv] deps = @@ -14,6 +14,7 @@ deps = dj40: django~=4.0.0 dj41: django~=4.1.3 dj42: django~=4.2.1 + dj50: django~=5.0a1 djmain: https://github.com/django/django/archive/main.tar.gz postgresql: psycopg2-binary psycopg3: psycopg[binary] @@ -49,25 +50,25 @@ allowlist_externals = make pip_pre = True commands = python -b -W always -m coverage run -m django test -v2 {posargs:tests} -[testenv:py{38,39,310,311}-dj{32,40,41,42,main}-{postgresql,psycopg3}] +[testenv:py{38,39,310,311}-dj{32,40,41,42,50,main}-{postgresql,psycopg3}] setenv = {[testenv]setenv} DB_BACKEND = postgresql DB_PORT = {env:DB_PORT:5432} -[testenv:py{38,39,310,311}-dj{32,40,41,42,main}-postgis] +[testenv:py{38,39,310,311}-dj{32,40,41,42,50,main}-postgis] setenv = {[testenv]setenv} DB_BACKEND = postgis DB_PORT = {env:DB_PORT:5432} -[testenv:py{38,39,310,311}-dj{32,40,41,42,main}-mysql] +[testenv:py{38,39,310,311}-dj{32,40,41,42,50,main}-mysql] setenv = {[testenv]setenv} DB_BACKEND = mysql DB_PORT = {env:DB_PORT:3306} -[testenv:py{38,39,310,311}-dj{32,40,41,42,main}-sqlite] +[testenv:py{38,39,310,311}-dj{32,40,41,42,50,main}-sqlite] setenv = {[testenv]setenv} DB_BACKEND = sqlite3 From 036e8db89350c4e72b4969ca7794328318f425c4 Mon Sep 17 00:00:00 2001 From: Tim Schilling Date: Sat, 14 Oct 2023 10:01:57 -0500 Subject: [PATCH 09/28] Add Python 3.12 to the test matrix. (#1816) * Add Python 3.12 to the test matrix. * Allow pre-releases for setup actions with GitHub actions. * Skip unnecessary test for python 3.12 * Update docs/changes.rst Co-authored-by: Matthias Kestenholz --------- Co-authored-by: Matthias Kestenholz --- .github/workflows/test.yml | 13 +++++++++---- docs/changes.rst | 1 + tests/panels/test_profiling.py | 7 +++++++ tox.ini | 15 ++++++++++----- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9dece68ef..5c8292ebd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false max-parallel: 5 matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] services: mariadb: @@ -36,6 +36,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Get pip cache dir id: pip-cache @@ -77,14 +78,16 @@ jobs: fail-fast: false max-parallel: 5 matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] database: [postgresql, postgis] - # Add psycopg3 to our matrix for 3.10 and 3.11 + # Add psycopg3 to our matrix for modern python versions include: - python-version: '3.10' database: psycopg3 - python-version: '3.11' database: psycopg3 + - python-version: '3.12' + database: psycopg3 services: postgres: @@ -108,6 +111,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Get pip cache dir id: pip-cache @@ -152,7 +156,7 @@ jobs: fail-fast: false max-parallel: 5 matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v3 @@ -161,6 +165,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Get pip cache dir id: pip-cache diff --git a/docs/changes.rst b/docs/changes.rst index 638d2d658..d4401dac8 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -4,6 +4,7 @@ Change log Pending ------- +* Added Python 3.12 to test matrix. * Removed outdated third-party panels from the list. * Avoided the unnecessary work of recursively quoting SQL parameters. * Postponed context process in templates panel to include lazy evaluated diff --git a/tests/panels/test_profiling.py b/tests/panels/test_profiling.py index ff613dfe1..88ec57dd6 100644 --- a/tests/panels/test_profiling.py +++ b/tests/panels/test_profiling.py @@ -1,3 +1,6 @@ +import sys +import unittest + from django.contrib.auth.models import User from django.db import IntegrityError, transaction from django.http import HttpResponse @@ -50,6 +53,10 @@ def test_cum_time_threshold(self): self.assertNotIn("render", content) self.assertValidHTML(content) + @unittest.skipUnless( + sys.version_info < (3, 12, 0), + "Python 3.12 no longer contains a frame for list comprehensions.", + ) def test_listcomp_escaped(self): self._get_response = lambda request: listcomp_view(request) response = self.panel.process_request(self.request) diff --git a/tox.ini b/tox.ini index 1bbdef0e1..5e3778329 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,7 @@ envlist = py{38,39,310}-dj32-{sqlite,postgresql,postgis,mysql} py310-dj40-sqlite py{310,311}-dj41-{sqlite,postgresql,postgis,mysql} - py{310,311}-dj{42,50,main}-{sqlite,postgresql,psycopg3,postgis,mysql} + py{310,311,312}-dj{42,50,main}-{sqlite,postgresql,psycopg3,postgis,mysql} [testenv] deps = @@ -50,25 +50,29 @@ allowlist_externals = make pip_pre = True commands = python -b -W always -m coverage run -m django test -v2 {posargs:tests} -[testenv:py{38,39,310,311}-dj{32,40,41,42,50,main}-{postgresql,psycopg3}] + +[testenv:py{38,39,310,311,312}-dj{32,40,41,42,50,main}-{postgresql,psycopg3}] setenv = {[testenv]setenv} DB_BACKEND = postgresql DB_PORT = {env:DB_PORT:5432} -[testenv:py{38,39,310,311}-dj{32,40,41,42,50,main}-postgis] + +[testenv:py{38,39,310,311,312}-dj{32,40,41,42,50,main}-postgis] setenv = {[testenv]setenv} DB_BACKEND = postgis DB_PORT = {env:DB_PORT:5432} -[testenv:py{38,39,310,311}-dj{32,40,41,42,50,main}-mysql] + +[testenv:py{38,39,310,311,312}-dj{32,40,41,42,50,main}-mysql] setenv = {[testenv]setenv} DB_BACKEND = mysql DB_PORT = {env:DB_PORT:3306} -[testenv:py{38,39,310,311}-dj{32,40,41,42,50,main}-sqlite] + +[testenv:py{38,39,310,311,312}-dj{32,40,41,42,50,main}-sqlite] setenv = {[testenv]setenv} DB_BACKEND = sqlite3 @@ -96,6 +100,7 @@ python = 3.9: py39 3.10: py310 3.11: py311 + 3.12: py312 [gh-actions:env] DB_BACKEND = From d4cfadcc57704fe97da344e85722f4a8a6d0f63a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 11:05:47 +0200 Subject: [PATCH 10/28] [pre-commit.ci] pre-commit autoupdate (#1838) --- .pre-commit-config.yaml | 10 +++++----- pyproject.toml | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f4796b196..6daf60317 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-toml - id: check-yaml @@ -31,7 +31,7 @@ repos: args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.50.0 + rev: v8.51.0 hooks: - id: eslint files: \.js?$ @@ -39,7 +39,7 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.0.291' + rev: 'v0.0.292' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] @@ -50,10 +50,10 @@ repos: language_version: python3 entry: black --target-version=py38 - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.1.0 + rev: 1.2.0 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.14 + rev: v0.15 hooks: - id: validate-pyproject diff --git a/pyproject.toml b/pyproject.toml index a40af2769..65a0bee1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Software Development :: Libraries :: Python Modules", ] dynamic = [ From e58e78bbffcf921241592e997f4b9730660791b3 Mon Sep 17 00:00:00 2001 From: Leandro de Souza <85115541+leandrodesouzadev@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:08:03 -0300 Subject: [PATCH 11/28] Fix `utils.get_name_from_obj` proper view names (#1846) --- debug_toolbar/utils.py | 16 +++++++++------- docs/changes.rst | 2 ++ tests/test_utils.py | 12 +++++++++--- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/debug_toolbar/utils.py b/debug_toolbar/utils.py index 7234f1f77..0b5d0e5b5 100644 --- a/debug_toolbar/utils.py +++ b/debug_toolbar/utils.py @@ -162,13 +162,15 @@ def get_template_source_from_exception_info( def get_name_from_obj(obj: Any) -> str: - name = obj.__name__ if hasattr(obj, "__name__") else obj.__class__.__name__ - - if hasattr(obj, "__module__"): - module = obj.__module__ - name = f"{module}.{name}" - - return name + """Get the best name as `str` from a view or a object.""" + # This is essentially a rewrite of the `django.contrib.admindocs.utils.get_view_name` + # https://github.com/django/django/blob/9a22d1769b042a88741f0ff3087f10d94f325d86/django/contrib/admindocs/utils.py#L26-L32 + if hasattr(obj, "view_class"): + klass = obj.view_class + return f"{klass.__module__}.{klass.__qualname__}" + mod_name = obj.__module__ + view_name = getattr(obj, "__qualname__", obj.__class__.__name__) + return mod_name + "." + view_name def getframeinfo(frame: Any, context: int = 1) -> inspect.Traceback: diff --git a/docs/changes.rst b/docs/changes.rst index d4401dac8..8985002e6 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -12,6 +12,8 @@ Pending * Fixed template panel to avoid evaluating ``LazyObject`` when not already evaluated. * Added support for Django 5.0. +* Refactor the ``utils.get_name_from_obj`` to simulate the behavior of + ``django.contrib.admindocs.utils.get_view_name``. 4.2.0 (2023-08-10) ------------------ diff --git a/tests/test_utils.py b/tests/test_utils.py index f8c47502a..26bfce005 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -18,18 +18,24 @@ def x(): return 1 res = get_name_from_obj(x) - self.assertEqual(res, "tests.test_utils.x") + self.assertEqual( + res, "tests.test_utils.GetNameFromObjTestCase.test_func..x" + ) def test_lambda(self): res = get_name_from_obj(lambda: 1) - self.assertEqual(res, "tests.test_utils.") + self.assertEqual( + res, "tests.test_utils.GetNameFromObjTestCase.test_lambda.." + ) def test_class(self): class A: pass res = get_name_from_obj(A) - self.assertEqual(res, "tests.test_utils.A") + self.assertEqual( + res, "tests.test_utils.GetNameFromObjTestCase.test_class..A" + ) class RenderStacktraceTestCase(unittest.TestCase): From 3bcae7386437e293d75a5aee532e4616095ecf38 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 16:31:56 +0200 Subject: [PATCH 12/28] [pre-commit.ci] pre-commit autoupdate (#1849) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6daf60317..14301dccf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.51.0 + rev: v8.52.0 hooks: - id: eslint files: \.js?$ @@ -39,12 +39,12 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.0.292' + rev: 'v0.1.1' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - rev: 23.9.1 + rev: 23.10.0 hooks: - id: black language_version: python3 From e1658db57ced40e20cf27062d9ab8505d199a893 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Fri, 27 Oct 2023 11:34:46 +0200 Subject: [PATCH 13/28] pyproject.toml: Work on the readability of ruff settings (#1850) --- debug_toolbar/panels/templates/panel.py | 7 ++- pyproject.toml | 64 +++++++++---------------- 2 files changed, 26 insertions(+), 45 deletions(-) diff --git a/debug_toolbar/panels/templates/panel.py b/debug_toolbar/panels/templates/panel.py index e63417fa9..f8c9242ca 100644 --- a/debug_toolbar/panels/templates/panel.py +++ b/debug_toolbar/panels/templates/panel.py @@ -154,10 +154,9 @@ def process_context_list(self, context_layers): # QuerySet would trigger the database: user can run the # query from SQL Panel elif isinstance(value, (QuerySet, RawQuerySet)): - temp_layer[key] = "<<{} of {}>>".format( - value.__class__.__name__.lower(), - value.model._meta.label, - ) + temp_layer[ + key + ] = f"<<{value.__class__.__name__.lower()} of {value.model._meta.label}>>" else: token = allow_sql.set(False) # noqa: FBT003 try: diff --git a/pyproject.toml b/pyproject.toml index 65a0bee1f..5f7abf41e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,44 +53,28 @@ path = "debug_toolbar/__init__.py" [tool.ruff] extend-select = [ - # pyflakes, pycodestyle - "F", "E", "W", - # mmcabe - # "C90", - # isort - "I", - # pep8-naming - # "N", - # pyupgrade - "UP", - # flake8-2020 - # "YTT", - # flake8-boolean-trap - "FBT", - # flake8-bugbear - "B", - # flake8-comprehensions - "C4", - # flake8-django - "DJ", - # flake8-pie - "PIE", - # flake8-simplify - "SIM", - # flake8-gettext - "INT", - # pygrep-hooks - "PGH", - # pylint - # "PL", - # unused noqa - "RUF100", + "ASYNC", # flake8-async + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "C90", # McCabe cyclomatic complexity + "DJ", # flake8-django + "E", # pycodestyle errors + "F", # Pyflakes + "FBT", # flake8-boolean-trap + "I", # isort + "INT", # flake8-gettext + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "RUF100", # Unused noqa directive + "SIM", # flake8-simplify + "SLOT", # flake8-slots + "UP", # pyupgrade + "W", # pycodestyle warnings ] extend-ignore = [ - # Allow zip() without strict= - "B905", - # No line length errors - "E501", + "B905", # Allow zip() without strict= + "E501", # Ignore line length violations + "SIM108", # Use ternary operator instead of if-else-block ] fix = true show-fixes = true @@ -100,14 +84,12 @@ target-version = "py38" combine-as-imports = true [tool.ruff.mccabe] -max-complexity = 15 +max-complexity = 16 [tool.ruff.per-file-ignores] "*/migrat*/*" = [ - # Allow using PascalCase model names in migrations - "N806", - # Ignore the fact that migration files are invalid module names - "N999", + "N806", # Allow using PascalCase model names in migrations + "N999", # Ignore the fact that migration files are invalid module names ] [tool.coverage.html] From 94c52190e8cc7399052f1d972d673a052fe01db5 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Fri, 27 Oct 2023 16:32:12 +0200 Subject: [PATCH 14/28] Switch to ruff format (#1852) --- .pre-commit-config.yaml | 11 +++-------- docs/changes.rst | 2 ++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 14301dccf..b88a5795e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,18 +39,13 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.1.1' + rev: 'v0.1.3' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] -- repo: https://github.com/psf/black - rev: 23.10.0 - hooks: - - id: black - language_version: python3 - entry: black --target-version=py38 + - id: ruff-format - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.2.0 + rev: 1.3.0 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject diff --git a/docs/changes.rst b/docs/changes.rst index 8985002e6..a13ca5b0f 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -14,6 +14,8 @@ Pending * Added support for Django 5.0. * Refactor the ``utils.get_name_from_obj`` to simulate the behavior of ``django.contrib.admindocs.utils.get_view_name``. +* Switched from black to the `ruff formatter + `__. 4.2.0 (2023-08-10) ------------------ From 473186d23e035173b0a3c7b919b902cee353cb43 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 18:54:49 +0100 Subject: [PATCH 15/28] [pre-commit.ci] pre-commit autoupdate (#1855) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b88a5795e..b8ac175ac 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.52.0 + rev: v8.53.0 hooks: - id: eslint files: \.js?$ @@ -39,13 +39,13 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.1.3' + rev: 'v0.1.4' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.3.0 + rev: 1.4.1 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject From eea643781c32f539fc15db4f99d660d67d258a3d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 18:33:56 +0100 Subject: [PATCH 16/28] [pre-commit.ci] pre-commit autoupdate (#1856) --- .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 b8ac175ac..4da8ba34f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,14 +24,14 @@ repos: - id: rst-backticks - id: rst-directive-colons - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.3 + rev: v3.1.0 hooks: - id: prettier types_or: [javascript, css] args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.53.0 + rev: v8.54.0 hooks: - id: eslint files: \.js?$ @@ -39,13 +39,13 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.1.4' + rev: 'v0.1.6' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.4.1 + rev: 1.5.1 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject From f0a04260eb7f3358e00e96dd66869bd4cb912a11 Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Tue, 28 Nov 2023 08:52:06 +0100 Subject: [PATCH 17/28] Fix #1858 -- Drop support for Django 4.0 (#1859) --- docs/changes.rst | 1 + pyproject.toml | 1 - tox.ini | 10 ++++------ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index a13ca5b0f..15c380ddd 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -4,6 +4,7 @@ Change log Pending ------- +* Dropped support for Django 4.0. * Added Python 3.12 to test matrix. * Removed outdated third-party panels from the list. * Avoided the unnecessary work of recursively quoting SQL parameters. diff --git a/pyproject.toml b/pyproject.toml index 5f7abf41e..e529808cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,6 @@ classifiers = [ "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 3.2", - "Framework :: Django :: 4.0", "Framework :: Django :: 4.1", "Framework :: Django :: 4.2", "Framework :: Django :: 5.0", diff --git a/tox.ini b/tox.ini index 5e3778329..254fb9b76 100644 --- a/tox.ini +++ b/tox.ini @@ -4,14 +4,12 @@ envlist = docs packaging py{38,39,310}-dj32-{sqlite,postgresql,postgis,mysql} - py310-dj40-sqlite py{310,311}-dj41-{sqlite,postgresql,postgis,mysql} py{310,311,312}-dj{42,50,main}-{sqlite,postgresql,psycopg3,postgis,mysql} [testenv] deps = dj32: django~=3.2.9 - dj40: django~=4.0.0 dj41: django~=4.1.3 dj42: django~=4.2.1 dj50: django~=5.0a1 @@ -51,28 +49,28 @@ pip_pre = True commands = python -b -W always -m coverage run -m django test -v2 {posargs:tests} -[testenv:py{38,39,310,311,312}-dj{32,40,41,42,50,main}-{postgresql,psycopg3}] +[testenv:py{38,39,310,311,312}-dj{32,41,42,50,main}-{postgresql,psycopg3}] setenv = {[testenv]setenv} DB_BACKEND = postgresql DB_PORT = {env:DB_PORT:5432} -[testenv:py{38,39,310,311,312}-dj{32,40,41,42,50,main}-postgis] +[testenv:py{38,39,310,311,312}-dj{32,41,42,50,main}-postgis] setenv = {[testenv]setenv} DB_BACKEND = postgis DB_PORT = {env:DB_PORT:5432} -[testenv:py{38,39,310,311,312}-dj{32,40,41,42,50,main}-mysql] +[testenv:py{38,39,310,311,312}-dj{32,41,42,50,main}-mysql] setenv = {[testenv]setenv} DB_BACKEND = mysql DB_PORT = {env:DB_PORT:3306} -[testenv:py{38,39,310,311,312}-dj{32,40,41,42,50,main}-sqlite] +[testenv:py{38,39,310,311,312}-dj{32,41,42,50,main}-sqlite] setenv = {[testenv]setenv} DB_BACKEND = sqlite3 From d6b8e22369a0f72ce9bf8c1a40075988852d216b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:30:01 +0000 Subject: [PATCH 18/28] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-prettier: v3.1.0 → v4.0.0-alpha.3](https://github.com/pre-commit/mirrors-prettier/compare/v3.1.0...v4.0.0-alpha.3) - [github.com/pre-commit/mirrors-eslint: v8.54.0 → v8.55.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.54.0...v8.55.0) - [github.com/tox-dev/pyproject-fmt: 1.5.1 → 1.5.3](https://github.com/tox-dev/pyproject-fmt/compare/1.5.1...1.5.3) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4da8ba34f..86aac8b3f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,14 +24,14 @@ repos: - id: rst-backticks - id: rst-directive-colons - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.1.0 + rev: v4.0.0-alpha.3 hooks: - id: prettier types_or: [javascript, css] args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.54.0 + rev: v8.55.0 hooks: - id: eslint files: \.js?$ @@ -45,7 +45,7 @@ repos: args: [--fix, --exit-non-zero-on-fix] - id: ruff-format - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.5.1 + rev: 1.5.3 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject From 6ff1dd16ec8c508c4be79431c54a073c8a931a40 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Mon, 4 Dec 2023 19:50:43 +0100 Subject: [PATCH 19/28] Enable the temporary workaround for https://github.com/prettier/prettier/issues/15742 --- .pre-commit-config.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 86aac8b3f..09e25551e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,9 +27,10 @@ repos: rev: v4.0.0-alpha.3 hooks: - id: prettier + entry: env PRETTIER_LEGACY_CLI=1 prettier types_or: [javascript, css] args: - - --trailing-comma=es5 + - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint rev: v8.55.0 hooks: From be989d278d6fd736344eee3bf85d2025d5a34645 Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Mon, 4 Dec 2023 19:55:19 +0100 Subject: [PATCH 20/28] Fix #1860 -- Update GitHub action versions (#1861) --- .github/workflows/release.yml | 4 ++-- .github/workflows/test.yml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c3cb00937..2059d37f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,12 +11,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.8 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c8292ebd..cb28e217e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: - 3306:3306 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 @@ -105,7 +105,7 @@ jobs: --health-retries 5 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 @@ -159,7 +159,7 @@ jobs: python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 @@ -203,7 +203,7 @@ jobs: runs-on: "ubuntu-latest" needs: [sqlite, mysql, postgres] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: # Use latest, so it understands all syntax. @@ -235,7 +235,7 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 From fb16de107350825a894b62f50803fd66466c90b0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 19:45:22 +0100 Subject: [PATCH 21/28] [pre-commit.ci] pre-commit autoupdate (#1864) --- .pre-commit-config.yaml | 6 +++--- debug_toolbar/utils.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 09e25551e..a97484b7e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: rst-backticks - id: rst-directive-colons - repo: https://github.com/pre-commit/mirrors-prettier - rev: v4.0.0-alpha.3 + rev: v4.0.0-alpha.7 hooks: - id: prettier entry: env PRETTIER_LEGACY_CLI=1 prettier @@ -32,7 +32,7 @@ repos: args: - --trailing-comma=es5 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.55.0 + rev: v8.56.0 hooks: - id: eslint files: \.js?$ @@ -40,7 +40,7 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.1.6' + rev: 'v0.1.8' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/debug_toolbar/utils.py b/debug_toolbar/utils.py index 0b5d0e5b5..3a9d0882e 100644 --- a/debug_toolbar/utils.py +++ b/debug_toolbar/utils.py @@ -213,7 +213,7 @@ def getframeinfo(frame: Any, context: int = 1) -> inspect.Traceback: def get_sorted_request_variable( - variable: Union[Dict[str, Any], QueryDict] + variable: Union[Dict[str, Any], QueryDict], ) -> Dict[str, Union[List[Tuple[str, Any]], Any]]: """ Get a data structure for showing a sorted list of variables from the From 6e9ce4890a22552b552ba95b5ef5684c579ca416 Mon Sep 17 00:00:00 2001 From: DraKen0009 <115104695+DraKen0009@users.noreply.github.com> Date: Tue, 19 Dec 2023 00:16:00 +0530 Subject: [PATCH 22/28] Refactor is_project_func method for Windows compatibility (#1857) --- debug_toolbar/panels/profiling.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py index 9d10229ad..2b7742400 100644 --- a/debug_toolbar/panels/profiling.py +++ b/debug_toolbar/panels/profiling.py @@ -42,10 +42,14 @@ def is_project_func(self): """ if hasattr(settings, "BASE_DIR"): file_name, _, _ = self.func - return ( - str(settings.BASE_DIR) in file_name - and "/site-packages/" not in file_name - and "/dist-packages/" not in file_name + base_dir = str(settings.BASE_DIR) + + file_name = os.path.normpath(file_name) + base_dir = os.path.normpath(base_dir) + + return file_name.startswith(base_dir) and not any( + directory in file_name.split(os.path.sep) + for directory in ["site-packages", "dist-packages"] ) return None From 075d38bd877f5fff3d73f29565edd726e444695b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 19:34:18 +0100 Subject: [PATCH 23/28] [pre-commit.ci] pre-commit autoupdate (#1866) --- .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 a97484b7e..7c2126145 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: rst-backticks - id: rst-directive-colons - repo: https://github.com/pre-commit/mirrors-prettier - rev: v4.0.0-alpha.7 + rev: v4.0.0-alpha.8 hooks: - id: prettier entry: env PRETTIER_LEGACY_CLI=1 prettier @@ -40,7 +40,7 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.1.8' + rev: 'v0.1.9' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 7731cd2135eb3277fd61d70d728b99a74407c0d4 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Wed, 3 Jan 2024 15:32:16 +0100 Subject: [PATCH 24/28] Configure ESLint using a JS file instead of JSON (#1868) The file is meant to be written by humans. --- .eslintrc.json => .eslintrc.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) rename .eslintrc.json => .eslintrc.js (83%) diff --git a/.eslintrc.json b/.eslintrc.js similarity index 83% rename from .eslintrc.json rename to .eslintrc.js index 8a2452b7a..b0c799d88 100644 --- a/.eslintrc.json +++ b/.eslintrc.js @@ -1,7 +1,9 @@ -{ +module.exports = { + root: true, "env": { "browser": true, - "es6": true + "es6": true, + node: true, }, "extends": "eslint:recommended", "parserOptions": { @@ -17,4 +19,4 @@ "prefer-const": "error", "semi": "error" } -} +}; From 77aa47a761da203c52e2328990123abb252d8dd5 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 9 Jan 2024 10:34:32 +0100 Subject: [PATCH 25/28] pre-commit-config: Upgrade ruff (#1869) This is the half of #1867 that passes. --- .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 7c2126145..c2f93ac73 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: args: - --fix - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.1.9' + rev: 'v0.1.11' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 22df01ca27f1c734d2a031f585affb131f9b5b0f Mon Sep 17 00:00:00 2001 From: Velda Kiara <32552296+VeldaKiara@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:01:49 +0300 Subject: [PATCH 26/28] The djdt handle shouldn't be stuck at the top of the browser window initially #1853 (#1871) * changing the default position of the toolbar to the top half instead of the top * updated the change to the changes.rst file --- debug_toolbar/static/debug_toolbar/js/toolbar.js | 2 +- docs/changes.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/debug_toolbar/static/debug_toolbar/js/toolbar.js b/debug_toolbar/static/debug_toolbar/js/toolbar.js index 9546ef27e..6648fb52b 100644 --- a/debug_toolbar/static/debug_toolbar/js/toolbar.js +++ b/debug_toolbar/static/debug_toolbar/js/toolbar.js @@ -226,7 +226,7 @@ const djdt = { const handle = document.getElementById("djDebugToolbarHandle"); // set handle position const handleTop = Math.min( - localStorage.getItem("djdt.top") || 0, + localStorage.getItem("djdt.top") || 265, window.innerHeight - handle.offsetWidth ); handle.style.top = handleTop + "px"; diff --git a/docs/changes.rst b/docs/changes.rst index 15c380ddd..82185d756 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -17,6 +17,8 @@ Pending ``django.contrib.admindocs.utils.get_view_name``. * Switched from black to the `ruff formatter `__. +* Changed the default position of the toolbar from top to the upper top + position. 4.2.0 (2023-08-10) ------------------ From 0e7711e033078a9bab5e936d1df38697b3f6f88e Mon Sep 17 00:00:00 2001 From: Elineda Date: Mon, 29 Jan 2024 13:20:57 +0100 Subject: [PATCH 27/28] 1843 new ajax request reset's whole view if history panel is enabled (#1872) New AJAX request reset's whole view if History Panel is enabled. [+] Create a setting which enable or disable the automatic refresh when an ajax request occurs. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Tim Schilling Co-authored-by: Tim Schilling --- debug_toolbar/settings.py | 1 + .../static/debug_toolbar/js/history.js | 3 +++ .../static/debug_toolbar/js/toolbar.js | 6 ++++- .../templates/debug_toolbar/base.html | 2 +- docs/changes.rst | 3 +++ docs/configuration.rst | 10 +++++++++ docs/spelling_wordlist.txt | 1 + tests/templates/ajax/ajax.html | 21 ++++++++++++++++++ tests/test_integration.py | 22 +++++++++++++++++++ tests/urls.py | 1 + tests/views.py | 4 ++++ 11 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 tests/templates/ajax/ajax.html diff --git a/debug_toolbar/settings.py b/debug_toolbar/settings.py index eb6b59209..1df24527d 100644 --- a/debug_toolbar/settings.py +++ b/debug_toolbar/settings.py @@ -42,6 +42,7 @@ "SQL_WARNING_THRESHOLD": 500, # milliseconds "OBSERVE_REQUEST_CALLBACK": "debug_toolbar.toolbar.observe_request", "TOOLBAR_LANGUAGE": None, + "UPDATE_ON_FETCH": False, } diff --git a/debug_toolbar/static/debug_toolbar/js/history.js b/debug_toolbar/static/debug_toolbar/js/history.js index b30fcabae..314ddb3ef 100644 --- a/debug_toolbar/static/debug_toolbar/js/history.js +++ b/debug_toolbar/static/debug_toolbar/js/history.js @@ -104,3 +104,6 @@ $$.on(djDebug, "click", ".refreshHistory", function (event) { event.preventDefault(); refreshHistory(); }); +// We don't refresh the whole toolbar each fetch or ajax request, +// so we need to refresh the history when we open the panel +$$.onPanelRender(djDebug, "HistoryPanel", refreshHistory); diff --git a/debug_toolbar/static/debug_toolbar/js/toolbar.js b/debug_toolbar/static/debug_toolbar/js/toolbar.js index 6648fb52b..199616336 100644 --- a/debug_toolbar/static/debug_toolbar/js/toolbar.js +++ b/debug_toolbar/static/debug_toolbar/js/toolbar.js @@ -17,8 +17,10 @@ function getDebugElement() { const djdt = { handleDragged: false, + needUpdateOnFetch: false, init() { const djDebug = getDebugElement(); + djdt.needUpdateOnFetch = djDebug.dataset.updateOnFetch === "True"; $$.on(djDebug, "click", "#djDebugPanelList li a", function (event) { event.preventDefault(); if (!this.className) { @@ -274,7 +276,9 @@ const djdt = { storeId = encodeURIComponent(storeId); const dest = `${sidebarUrl}?store_id=${storeId}`; slowjax(dest).then(function (data) { - replaceToolbarState(storeId, data); + if (djdt.needUpdateOnFetch){ + replaceToolbarState(storeId, data); + } }); } diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index 5447970af..6f4967f21 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -16,7 +16,7 @@ data-sidebar-url="{{ history_url }}" {% endif %} data-default-show="{% if toolbar.config.SHOW_COLLAPSED %}false{% else %}true{% endif %}" - {{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }}> + {{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }} data-update-on-fetch="{{ toolbar.config.UPDATE_ON_FETCH }}">
  • {% trans "Hide" %} »
  • diff --git a/docs/changes.rst b/docs/changes.rst index 82185d756..9ff88b2b8 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -19,6 +19,9 @@ Pending `__. * Changed the default position of the toolbar from top to the upper top position. +* Added the setting, ``UPDATE_ON_FETCH`` to control whether the + toolbar automatically updates to the latest AJAX request or not. + It defaults to ``False``. 4.2.0 (2023-08-10) ------------------ diff --git a/docs/configuration.rst b/docs/configuration.rst index 887608c6e..8271092ca 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -163,6 +163,16 @@ Toolbar options but want to render your application in French, you would set this to ``"en-us"`` and :setting:`LANGUAGE_CODE` to ``"fr"``. +.. _UPDATE_ON_FETCH: + +* ``UPDATE_ON_FETCH`` + + Default: ``False`` + + This controls whether the toolbar should update to the latest AJAX + request when it occurs. This is especially useful when using htmx + boosting or similar JavaScript techniques. + Panel options ~~~~~~~~~~~~~ diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 7a15d9aeb..436977bdc 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -6,6 +6,7 @@ Pympler Roboto Transifex Werkzeug +ajax async backend backends diff --git a/tests/templates/ajax/ajax.html b/tests/templates/ajax/ajax.html new file mode 100644 index 000000000..c9de3acb6 --- /dev/null +++ b/tests/templates/ajax/ajax.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% block content %} +
    click for ajax
    + + +{% endblock %} diff --git a/tests/test_integration.py b/tests/test_integration.py index b77b7cede..379fafaf4 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1,5 +1,6 @@ import os import re +import time import unittest import html5lib @@ -749,3 +750,24 @@ def test_toolbar_language_will_render_to_locale_when_set_both(self): ) self.assertIn("Query", table.text) self.assertIn("Action", table.text) + + def test_ajax_dont_refresh(self): + self.get("/ajax/") + make_ajax = self.selenium.find_element(By.ID, "click_for_ajax") + make_ajax.click() + history_panel = self.selenium.find_element(By.ID, "djdt-HistoryPanel") + self.assertIn("/ajax/", history_panel.text) + self.assertNotIn("/json_view/", history_panel.text) + + @override_settings(DEBUG_TOOLBAR_CONFIG={"UPDATE_ON_FETCH": True}) + def test_ajax_refresh(self): + self.get("/ajax/") + make_ajax = self.selenium.find_element(By.ID, "click_for_ajax") + make_ajax.click() + # Need to wait until the ajax request is over and json_view is displayed on the toolbar + time.sleep(2) + history_panel = self.wait.until( + lambda selenium: self.selenium.find_element(By.ID, "djdt-HistoryPanel") + ) + self.assertNotIn("/ajax/", history_panel.text) + self.assertIn("/json_view/", history_panel.text) diff --git a/tests/urls.py b/tests/urls.py index 6fc8811b7..f8929f1e8 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -21,6 +21,7 @@ path("cached_low_level_view/", views.cached_low_level_view), path("json_view/", views.json_view), path("redirect/", views.redirect_view), + path("ajax/", views.ajax_view), path("login_without_redirect/", LoginView.as_view(redirect_field_name=None)), path("admin/", admin.site.urls), path("__debug__/", include("debug_toolbar.urls")), diff --git a/tests/views.py b/tests/views.py index b2fd21c54..c7214029e 100644 --- a/tests/views.py +++ b/tests/views.py @@ -58,3 +58,7 @@ def listcomp_view(request): def redirect_view(request): return HttpResponseRedirect("/regular/redirect/") + + +def ajax_view(request): + return render(request, "ajax/ajax.html") From 0b59e2406348cf52710866e01328c037b5ea5177 Mon Sep 17 00:00:00 2001 From: Tim Schilling Date: Thu, 1 Feb 2024 13:23:11 -0600 Subject: [PATCH 28/28] Version 4.3.0 --- debug_toolbar/__init__.py | 2 +- docs/changes.rst | 3 +++ docs/conf.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/__init__.py b/debug_toolbar/__init__.py index dbe08451f..9a8c2b24f 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 = "4.2.0" +VERSION = "4.3.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 9ff88b2b8..e2a610991 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -4,6 +4,9 @@ Change log Pending ------- +4.3.0 (2024-02-01) +------------------ + * Dropped support for Django 4.0. * Added Python 3.12 to test matrix. * Removed outdated third-party panels from the list. diff --git a/docs/conf.py b/docs/conf.py index 7fa8e6fce..f87b8f19a 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 = "4.2.0" +release = "4.3.0" # -- General configuration ---------------------------------------------------