Skip to content

Commit dba0050

Browse files
authored
Merge branch 'main' into mk/remove-py37
2 parents 3bc78d9 + c919827 commit dba0050

File tree

7 files changed

+99
-19
lines changed

7 files changed

+99
-19
lines changed

.pre-commit-config.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ repos:
1212
hooks:
1313
- id: flake8
1414
- repo: https://github.com/pycqa/doc8
15-
rev: v1.0.0
15+
rev: v1.1.1
1616
hooks:
1717
- id: doc8
1818
- repo: https://github.com/asottile/pyupgrade
19-
rev: v3.3.0
19+
rev: v3.3.1
2020
hooks:
2121
- id: pyupgrade
2222
args: [--py38-plus]
@@ -26,7 +26,7 @@ repos:
2626
- id: django-upgrade
2727
args: [--target-version, "3.2"]
2828
- repo: https://github.com/pycqa/isort
29-
rev: 5.10.1
29+
rev: 5.11.4
3030
hooks:
3131
- id: isort
3232
- repo: https://github.com/pre-commit/pygrep-hooks
@@ -46,15 +46,15 @@ repos:
4646
args:
4747
- --trailing-comma=es5
4848
- repo: https://github.com/pre-commit/mirrors-eslint
49-
rev: v8.29.0
49+
rev: v8.30.0
5050
hooks:
5151
- id: eslint
5252
files: \.js?$
5353
types: [file]
5454
args:
5555
- --fix
5656
- repo: https://github.com/psf/black
57-
rev: 22.10.0
57+
rev: 22.12.0
5858
hooks:
5959
- id: black
6060
language_version: python3

.readthedocs.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# .readthedocs.yaml
2+
# Read the Docs configuration file
3+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4+
5+
version: 2
6+
7+
build:
8+
os: ubuntu-22.04
9+
tools:
10+
python: "3.10"
11+
12+
sphinx:
13+
configuration: docs/conf.py
14+
15+
python:
16+
install:
17+
- requirements: requirements_dev.txt
18+
- method: pip
19+
path: .

debug_toolbar/_stubs.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from typing import Any, List, NamedTuple, Optional, Tuple
2+
3+
from django import template as dj_template
4+
5+
6+
class InspectStack(NamedTuple):
7+
frame: Any
8+
filename: str
9+
lineno: int
10+
function: str
11+
code_context: str
12+
index: int
13+
14+
15+
TidyStackTrace = List[Tuple[str, int, str, str, Optional[Any]]]
16+
17+
18+
class RenderContext(dj_template.context.RenderContext):
19+
template: dj_template.Template
20+
21+
22+
class RequestContext(dj_template.RequestContext):
23+
template: dj_template.Template
24+
render_context: RenderContext

debug_toolbar/panels/sql/tracking.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ def _quote_params(self, params):
120120
return params
121121
if isinstance(params, dict):
122122
return {key: self._quote_expr(value) for key, value in params.items()}
123+
if isinstance(params, tuple):
124+
return tuple(self._quote_expr(p) for p in params)
123125
return [self._quote_expr(p) for p in params]
124126

125127
def _decode(self, param):

debug_toolbar/utils.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import sys
55
import warnings
66
from pprint import pformat
7+
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
78

89
from asgiref.local import Local
10+
from django.http import QueryDict
911
from django.template import Node
1012
from django.utils.html import format_html
11-
from django.utils.safestring import mark_safe
13+
from django.utils.safestring import SafeString, mark_safe
1214

13-
from debug_toolbar import settings as dt_settings
15+
from debug_toolbar import _stubs as stubs, settings as dt_settings
1416

1517
try:
1618
import threading
@@ -21,7 +23,7 @@
2123
_local_data = Local()
2224

2325

24-
def _is_excluded_frame(frame, excluded_modules):
26+
def _is_excluded_frame(frame: Any, excluded_modules: Optional[Sequence[str]]) -> bool:
2527
if not excluded_modules:
2628
return False
2729
frame_module = frame.f_globals.get("__name__")
@@ -34,7 +36,7 @@ def _is_excluded_frame(frame, excluded_modules):
3436
)
3537

3638

37-
def _stack_trace_deprecation_warning():
39+
def _stack_trace_deprecation_warning() -> None:
3840
warnings.warn(
3941
"get_stack() and tidy_stacktrace() are deprecated in favor of"
4042
" get_stack_trace()",
@@ -43,7 +45,7 @@ def _stack_trace_deprecation_warning():
4345
)
4446

4547

46-
def tidy_stacktrace(stack):
48+
def tidy_stacktrace(stack: List[stubs.InspectStack]) -> stubs.TidyStackTrace:
4749
"""
4850
Clean up stacktrace and remove all entries that are excluded by the
4951
HIDE_IN_STACKTRACES setting.
@@ -68,7 +70,7 @@ def tidy_stacktrace(stack):
6870
return trace
6971

7072

71-
def render_stacktrace(trace):
73+
def render_stacktrace(trace: stubs.TidyStackTrace) -> SafeString:
7274
show_locals = dt_settings.get_config()["ENABLE_STACKTRACES_LOCALS"]
7375
html = ""
7476
for abspath, lineno, func, code, locals_ in trace:
@@ -103,7 +105,7 @@ def render_stacktrace(trace):
103105
return mark_safe(html)
104106

105107

106-
def get_template_info():
108+
def get_template_info() -> Optional[Dict[str, Any]]:
107109
template_info = None
108110
cur_frame = sys._getframe().f_back
109111
try:
@@ -131,7 +133,9 @@ def get_template_info():
131133
return template_info
132134

133135

134-
def get_template_context(node, context, context_lines=3):
136+
def get_template_context(
137+
node: Node, context: stubs.RequestContext, context_lines: int = 3
138+
) -> Dict[str, Any]:
135139
line, source_lines, name = get_template_source_from_exception_info(node, context)
136140
debug_context = []
137141
start = max(1, line - context_lines)
@@ -146,7 +150,9 @@ def get_template_context(node, context, context_lines=3):
146150
return {"name": name, "context": debug_context}
147151

148152

149-
def get_template_source_from_exception_info(node, context):
153+
def get_template_source_from_exception_info(
154+
node: Node, context: stubs.RequestContext
155+
) -> Tuple[int, List[Tuple[int, str]], str]:
150156
if context.template.origin == node.origin:
151157
exception_info = context.template.get_exception_info(
152158
Exception("DDT"), node.token
@@ -161,7 +167,7 @@ def get_template_source_from_exception_info(node, context):
161167
return line, source_lines, name
162168

163169

164-
def get_name_from_obj(obj):
170+
def get_name_from_obj(obj: Any) -> str:
165171
if hasattr(obj, "__name__"):
166172
name = obj.__name__
167173
else:
@@ -174,7 +180,7 @@ def get_name_from_obj(obj):
174180
return name
175181

176182

177-
def getframeinfo(frame, context=1):
183+
def getframeinfo(frame: Any, context: int = 1) -> inspect.Traceback:
178184
"""
179185
Get information about a frame or traceback object.
180186
@@ -213,7 +219,9 @@ def getframeinfo(frame, context=1):
213219
return inspect.Traceback(filename, lineno, frame.f_code.co_name, lines, index)
214220

215221

216-
def get_sorted_request_variable(variable):
222+
def get_sorted_request_variable(
223+
variable: Union[Dict[str, Any], QueryDict]
224+
) -> Dict[str, Union[List[Tuple[str, Any]], Any]]:
217225
"""
218226
Get a data structure for showing a sorted list of variables from the
219227
request data.
@@ -227,7 +235,7 @@ def get_sorted_request_variable(variable):
227235
return {"raw": variable}
228236

229237

230-
def get_stack(context=1):
238+
def get_stack(context=1) -> List[stubs.InspectStack]:
231239
"""
232240
Get a list of records for a frame and all higher (calling) frames.
233241
@@ -280,7 +288,13 @@ def get_source_file(self, frame):
280288

281289
return value
282290

283-
def get_stack_trace(self, *, excluded_modules=None, include_locals=False, skip=0):
291+
def get_stack_trace(
292+
self,
293+
*,
294+
excluded_modules: Optional[Sequence[str]] = None,
295+
include_locals: bool = False,
296+
skip: int = 0,
297+
):
284298
trace = []
285299
skip += 1 # Skip the frame for this method.
286300
for frame in _stack_frames(skip=skip):

docs/changes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Change log
44
Pending
55
-------
66

7+
* Fixed PostgreSQL raw query with a tuple parameter during on explain.
78
* Dropped support for Python 3.7.
89

910
3.8.1 (2022-12-03)

tests/panels/test_sql.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,26 @@ def test_json_param_conversion(self):
221221
'["{\\"foo\\": \\"bar\\"}"]',
222222
)
223223

224+
@unittest.skipUnless(
225+
connection.vendor == "postgresql", "Test valid only on PostgreSQL"
226+
)
227+
def test_tuple_param_conversion(self):
228+
self.assertEqual(len(self.panel._queries), 0)
229+
230+
list(
231+
PostgresJSON.objects.raw(
232+
"SELECT * FROM tests_postgresjson WHERE field ->> 'key' IN %s",
233+
[("a", "b'")],
234+
)
235+
)
236+
237+
response = self.panel.process_request(self.request)
238+
self.panel.generate_stats(self.request, response)
239+
240+
# ensure query was logged
241+
self.assertEqual(len(self.panel._queries), 1)
242+
self.assertEqual(self.panel._queries[0]["params"], '[["a", "b\'"]]')
243+
224244
def test_binary_param_force_text(self):
225245
self.assertEqual(len(self.panel._queries), 0)
226246

0 commit comments

Comments
 (0)