From 756f00289198496df794ff6ffec1bdf98d7e946e Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Tue, 11 Nov 2025 09:18:12 +0000 Subject: [PATCH 1/3] Refactor type hints and imports in history panel and views for improved clarity --- debug_toolbar/panels/history/panel.py | 31 ++++++++++++++------------- debug_toolbar/panels/history/views.py | 14 ++++++------ debug_toolbar/views.py | 13 ++++++----- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/debug_toolbar/panels/history/panel.py b/debug_toolbar/panels/history/panel.py index d2f3f8ab6..091f5728f 100644 --- a/debug_toolbar/panels/history/panel.py +++ b/debug_toolbar/panels/history/panel.py @@ -1,10 +1,11 @@ import contextlib import json -from django.http.request import RawPostDataException +from django.http import HttpResponse, QueryDict +from django.http.request import HttpRequest, RawPostDataException from django.template.loader import render_to_string from django.templatetags.static import static -from django.urls import path +from django.urls import URLPattern, path from django.utils import timezone from django.utils.translation import gettext_lazy as _ @@ -21,8 +22,8 @@ class HistoryPanel(Panel): nav_title = _("History") template = "debug_toolbar/panels/history.html" - def get_headers(self, request): - headers = super().get_headers(request) + def get_headers(self, request: HttpRequest) -> dict: + headers: dict = super().get_headers(request) observe_request = self.toolbar.get_observe_request() request_id = self.toolbar.request_id if request_id and observe_request(request): @@ -30,33 +31,33 @@ def get_headers(self, request): return headers @property - def enabled(self): + def enabled(self) -> bool: # Do not show the history panel if the panels are rendered on request # rather than loaded via ajax. return super().enabled and not self.toolbar.should_render_panels() @property - def is_historical(self): + def is_historical(self) -> bool: """The HistoryPanel should not be included in the historical panels.""" return False @classmethod - def get_urls(cls): + def get_urls(cls) -> list[URLPattern]: return [ path("history_sidebar/", views.history_sidebar, name="history_sidebar"), path("history_refresh/", views.history_refresh, name="history_refresh"), ] @property - def nav_subtitle(self): + def nav_subtitle(self) -> str: return self.get_stats().get("request_url", "") - def generate_stats(self, request, response): + def generate_stats(self, request: HttpRequest, response: HttpResponse) -> None: try: if request.method == "GET": - data = request.GET.copy() + data: QueryDict = request.GET.copy() else: - data = request.POST.copy() + data: QueryDict = request.POST.copy() # GraphQL tends to not be populated in POST. If the request seems # empty, check if it's a JSON request. if ( @@ -82,12 +83,12 @@ def generate_stats(self, request, response): ) @property - def content(self): + def content(self) -> str: """Content of the panel when it's displayed in full screen. Fetch every store for the toolbar and include it in the template. """ - toolbar_history = {} + toolbar_history: dict[str, dict] = {} for request_id in reversed(self.toolbar.store.request_ids()): toolbar_history[request_id] = { "history_stats": self.toolbar.store.panel( @@ -113,7 +114,7 @@ def content(self): ) @property - def scripts(self): - scripts = super().scripts + def scripts(self) -> list[str]: + scripts: list[str] = super().scripts scripts.append(static("debug_toolbar/js/history.js")) return scripts diff --git a/debug_toolbar/panels/history/views.py b/debug_toolbar/panels/history/views.py index 2dd6de820..b1106910a 100644 --- a/debug_toolbar/panels/history/views.py +++ b/debug_toolbar/panels/history/views.py @@ -1,4 +1,4 @@ -from django.http import HttpResponseBadRequest, JsonResponse +from django.http import HttpRequest, HttpResponseBadRequest, JsonResponse from django.template.loader import render_to_string from debug_toolbar._compat import login_not_required @@ -11,15 +11,15 @@ @login_not_required @require_show_toolbar @render_with_toolbar_language -def history_sidebar(request): +def history_sidebar(request: HttpRequest) -> HttpResponseBadRequest | JsonResponse: """Returns the selected debug toolbar history snapshot.""" form = HistoryStoreForm(request.GET) if form.is_valid(): - request_id = form.cleaned_data["request_id"] - toolbar = DebugToolbar.fetch(request_id) + request_id: str = form.cleaned_data["request_id"] + toolbar: DebugToolbar | None = DebugToolbar.fetch(request_id) exclude_history = form.cleaned_data["exclude_history"] - context = {} + context: dict[str, dict[str, str]] = {} if toolbar is None: # When the request_id has been popped already due to # RESULTS_CACHE_SIZE @@ -43,12 +43,12 @@ def history_sidebar(request): @login_not_required @require_show_toolbar @render_with_toolbar_language -def history_refresh(request): +def history_refresh(request: HttpRequest) -> HttpResponseBadRequest | JsonResponse: """Returns the refreshed list of table rows for the History Panel.""" form = HistoryStoreForm(request.GET) if form.is_valid(): - requests = [] + requests: list[dict[str, str]] = [] # Convert to list to handle mutations happening in parallel for request_id in get_store().request_ids(): toolbar = DebugToolbar.fetch(request_id) diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py index 279a6cb9a..739f2f314 100644 --- a/debug_toolbar/views.py +++ b/debug_toolbar/views.py @@ -1,18 +1,21 @@ -from django.http import JsonResponse +from django.http import HttpRequest, JsonResponse from django.utils.html import escape from django.utils.translation import gettext as _ from debug_toolbar._compat import login_not_required from debug_toolbar.decorators import render_with_toolbar_language, require_show_toolbar -from debug_toolbar.toolbar import DebugToolbar +from debug_toolbar.panels import Panel +from debug_toolbar.toolbar import DebugToolbar, StoredDebugToolbar @login_not_required @require_show_toolbar @render_with_toolbar_language -def render_panel(request): +def render_panel(request: HttpRequest) -> JsonResponse: """Render the contents of a panel""" - toolbar = DebugToolbar.fetch(request.GET["request_id"], request.GET["panel_id"]) + toolbar: StoredDebugToolbar | None = DebugToolbar.fetch( + request.GET["request_id"], request.GET["panel_id"] + ) if toolbar is None: content = _( "Data for this panel isn't available anymore. " @@ -21,7 +24,7 @@ def render_panel(request): content = f"

{escape(content)}

" scripts = [] else: - panel = toolbar.get_panel_by_id(request.GET["panel_id"]) + panel: Panel = toolbar.get_panel_by_id(request.GET["panel_id"]) content = panel.content scripts = panel.scripts return JsonResponse({"content": content, "scripts": scripts}) From 26c1c85aacba4c5eb1bc9234102a9baf21581e4e Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Tue, 11 Nov 2025 09:19:51 +0000 Subject: [PATCH 2/3] Add type hints for panel_id and __all__ in history panel for improved clarity --- debug_toolbar/panels/__init__.py | 2 +- debug_toolbar/panels/history/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py index a53ba6652..204b3d321 100644 --- a/debug_toolbar/panels/__init__.py +++ b/debug_toolbar/panels/__init__.py @@ -21,7 +21,7 @@ def __init__(self, toolbar, get_response): # Private panel properties @classproperty - def panel_id(cls): + def panel_id(cls) -> str: return cls.__name__ @property diff --git a/debug_toolbar/panels/history/__init__.py b/debug_toolbar/panels/history/__init__.py index 193ced242..1a8a8932b 100644 --- a/debug_toolbar/panels/history/__init__.py +++ b/debug_toolbar/panels/history/__init__.py @@ -1,3 +1,3 @@ from debug_toolbar.panels.history.panel import HistoryPanel -__all__ = [HistoryPanel.panel_id] +__all__: list[str] = [HistoryPanel.panel_id] From a23a3804f43fed636344f0e0922649a9c9b9d37b Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Tue, 11 Nov 2025 09:41:59 +0000 Subject: [PATCH 3/3] use Union instead of | --- debug_toolbar/panels/history/views.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/debug_toolbar/panels/history/views.py b/debug_toolbar/panels/history/views.py index b1106910a..b3e24df06 100644 --- a/debug_toolbar/panels/history/views.py +++ b/debug_toolbar/panels/history/views.py @@ -1,3 +1,5 @@ +from typing import Union + from django.http import HttpRequest, HttpResponseBadRequest, JsonResponse from django.template.loader import render_to_string @@ -11,13 +13,15 @@ @login_not_required @require_show_toolbar @render_with_toolbar_language -def history_sidebar(request: HttpRequest) -> HttpResponseBadRequest | JsonResponse: +def history_sidebar( + request: HttpRequest, +) -> Union[HttpResponseBadRequest, JsonResponse]: """Returns the selected debug toolbar history snapshot.""" form = HistoryStoreForm(request.GET) if form.is_valid(): request_id: str = form.cleaned_data["request_id"] - toolbar: DebugToolbar | None = DebugToolbar.fetch(request_id) + toolbar: Union[DebugToolbar, None] = DebugToolbar.fetch(request_id) exclude_history = form.cleaned_data["exclude_history"] context: dict[str, dict[str, str]] = {} if toolbar is None: @@ -43,7 +47,9 @@ def history_sidebar(request: HttpRequest) -> HttpResponseBadRequest | JsonRespon @login_not_required @require_show_toolbar @render_with_toolbar_language -def history_refresh(request: HttpRequest) -> HttpResponseBadRequest | JsonResponse: +def history_refresh( + request: HttpRequest, +) -> Union[HttpResponseBadRequest, JsonResponse]: """Returns the refreshed list of table rows for the History Panel.""" form = HistoryStoreForm(request.GET)