Skip to content

Commit d3289f8

Browse files
committed
Drop Django < 3.2, modernize the code
Add pyupgrade and django-upgrade to automatically take advantage of new features of Python and Django.
1 parent 1964826 commit d3289f8

File tree

20 files changed

+69
-142
lines changed

20 files changed

+69
-142
lines changed

.pre-commit-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ repos:
1414
rev: 0.10.1
1515
hooks:
1616
- id: doc8
17+
- repo: https://github.com/asottile/pyupgrade
18+
rev: v2.29.1
19+
hooks:
20+
- id: pyupgrade
21+
args: [--py36-plus]
22+
- repo: https://github.com/adamchainz/django-upgrade
23+
rev: 1.4.0
24+
hooks:
25+
- id: django-upgrade
26+
args: [--target-version, "3.2"]
1727
- repo: https://github.com/pycqa/isort
1828
rev: 5.10.1
1929
hooks:

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ In addition to the built-in panels, a number of third-party panels are
4545
contributed by the community.
4646

4747
The current stable version of the Debug Toolbar is 3.2.4. It works on
48-
Django ≥ 2.2.
48+
Django ≥ 3.2.
4949

5050
Documentation, including installation and configuration instructions, is
5151
available at https://django-debug-toolbar.readthedocs.io/.

debug_toolbar/__init__.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import django
2-
31
from debug_toolbar.urls import app_name
42

53
__all__ = ["VERSION"]
@@ -12,6 +10,3 @@
1210
# Code that discovers files or modules in INSTALLED_APPS imports this module.
1311

1412
urls = "debug_toolbar.urls", app_name
15-
16-
if django.VERSION < (3, 2):
17-
default_app_config = "debug_toolbar.apps.DebugToolbarConfig"

debug_toolbar/management/commands/debugsqlshell.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from time import time
22

3-
import django
43
import sqlparse
54
from django.core.management.commands.shell import Command
65
from django.db import connection
76

8-
if connection.vendor == "postgresql" and django.VERSION >= (3, 0, 0):
7+
if connection.vendor == "postgresql":
98
from django.db.backends.postgresql import base as base_module
109
else:
1110
from django.db.backends import utils as base_module
@@ -28,7 +27,7 @@ def execute(self, sql, params=()):
2827
end_time = time()
2928
duration = (end_time - start_time) * 1000
3029
formatted_sql = sqlparse.format(raw_sql, reindent=True)
31-
print("{} [{:.2f}ms]".format(formatted_sql, duration))
30+
print(f"{formatted_sql} [{duration:.2f}ms]")
3231

3332

3433
base_module.CursorDebugWrapper = PrintQueryWrapper

debug_toolbar/panels/cache.py

Lines changed: 24 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,9 @@
88
except ImportError:
99
ConnectionProxy = None
1010

11-
import django
1211
from django.conf import settings
1312
from django.core import cache
14-
from django.core.cache import (
15-
DEFAULT_CACHE_ALIAS,
16-
CacheHandler,
17-
cache as original_cache,
18-
caches as original_caches,
19-
)
13+
from django.core.cache import DEFAULT_CACHE_ALIAS, CacheHandler
2014
from django.core.cache.backends.base import BaseCache
2115
from django.dispatch import Signal
2216
from django.middleware import cache as middleware_cache
@@ -69,7 +63,7 @@ def __init__(self, cache):
6963
self.cache = cache
7064

7165
def __repr__(self):
72-
return str("<CacheStatTracker for %s>") % repr(self.cache)
66+
return "<CacheStatTracker for %s>" % repr(self.cache)
7367

7468
def _get_func_info(self):
7569
frame = sys._getframe(3)
@@ -141,26 +135,17 @@ def decr_version(self, *args, **kwargs):
141135
return self.cache.decr_version(*args, **kwargs)
142136

143137

144-
if django.VERSION < (3, 2):
138+
class CacheHandlerPatch(CacheHandler):
139+
def __init__(self, settings=None):
140+
self._djdt_wrap = True
141+
super().__init__(settings=settings)
145142

146-
class CacheHandlerPatch(CacheHandler):
147-
def __getitem__(self, alias):
148-
actual_cache = super().__getitem__(alias)
143+
def create_connection(self, alias):
144+
actual_cache = super().create_connection(alias)
145+
if self._djdt_wrap:
149146
return CacheStatTracker(actual_cache)
150-
151-
else:
152-
153-
class CacheHandlerPatch(CacheHandler):
154-
def __init__(self, settings=None):
155-
self._djdt_wrap = True
156-
super().__init__(settings=settings)
157-
158-
def create_connection(self, alias):
159-
actual_cache = super().create_connection(alias)
160-
if self._djdt_wrap:
161-
return CacheStatTracker(actual_cache)
162-
else:
163-
return actual_cache
147+
else:
148+
return actual_cache
164149

165150

166151
middleware_cache.caches = CacheHandlerPatch()
@@ -268,40 +253,26 @@ def title(self):
268253
)
269254

270255
def enable_instrumentation(self):
271-
if django.VERSION < (3, 2):
272-
if isinstance(middleware_cache.caches, CacheHandlerPatch):
273-
cache.caches = middleware_cache.caches
274-
else:
275-
cache.caches = CacheHandlerPatch()
276-
else:
277-
for alias in cache.caches:
278-
if not isinstance(cache.caches[alias], CacheStatTracker):
279-
cache.caches[alias] = CacheStatTracker(cache.caches[alias])
256+
for alias in cache.caches:
257+
if not isinstance(cache.caches[alias], CacheStatTracker):
258+
cache.caches[alias] = CacheStatTracker(cache.caches[alias])
280259

281-
if not isinstance(middleware_cache.caches, CacheHandlerPatch):
282-
middleware_cache.caches = cache.caches
260+
if not isinstance(middleware_cache.caches, CacheHandlerPatch):
261+
middleware_cache.caches = cache.caches
283262

284263
# Wrap the patched cache inside Django's ConnectionProxy
285264
if ConnectionProxy:
286265
cache.cache = ConnectionProxy(cache.caches, DEFAULT_CACHE_ALIAS)
287266

288267
def disable_instrumentation(self):
289-
if django.VERSION < (3, 2):
290-
cache.caches = original_caches
291-
cache.cache = original_cache
292-
# While it can be restored to the original, any views that were
293-
# wrapped with the cache_page decorator will continue to use a
294-
# monkey patched cache.
295-
middleware_cache.caches = original_caches
296-
else:
297-
for alias in cache.caches:
298-
if isinstance(cache.caches[alias], CacheStatTracker):
299-
cache.caches[alias] = cache.caches[alias].cache
300-
if ConnectionProxy:
301-
cache.cache = ConnectionProxy(cache.caches, DEFAULT_CACHE_ALIAS)
302-
# While it can be restored to the original, any views that were
303-
# wrapped with the cache_page decorator will continue to use a
304-
# monkey patched cache.
268+
for alias in cache.caches:
269+
if isinstance(cache.caches[alias], CacheStatTracker):
270+
cache.caches[alias] = cache.caches[alias].cache
271+
if ConnectionProxy:
272+
cache.cache = ConnectionProxy(cache.caches, DEFAULT_CACHE_ALIAS)
273+
# While it can be restored to the original, any views that were
274+
# wrapped with the cache_page decorator will continue to use a
275+
# monkey patched cache.
305276

306277
def generate_stats(self, request, response):
307278
self.record_stats(

debug_toolbar/panels/profiling.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def parent_classes(self):
3030

3131
def background(self):
3232
r, g, b = hsv_to_rgb(*self.hsv)
33-
return "rgb({:f}%,{:f}%,{:f}%)".format(r * 100, g * 100, b * 100)
33+
return f"rgb({r * 100:f}%,{g * 100:f}%,{b * 100:f}%)"
3434

3535
def func_std_string(self): # match what old profile produced
3636
func_name = self.func

debug_toolbar/panels/settings.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
from collections import OrderedDict
22

3-
import django
43
from django.conf import settings
54
from django.utils.translation import gettext_lazy as _
5+
from django.views.debug import get_default_exception_reporter_filter
66

77
from debug_toolbar.panels import Panel
88

9-
if django.VERSION >= (3, 1):
10-
from django.views.debug import get_default_exception_reporter_filter
11-
12-
get_safe_settings = get_default_exception_reporter_filter().get_safe_settings
13-
else:
14-
from django.views.debug import get_safe_settings
9+
get_safe_settings = get_default_exception_reporter_filter().get_safe_settings
1510

1611

1712
class SettingsPanel(Panel):

debug_toolbar/panels/signals.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def generate_stats(self, request, response):
9797
receiver_class_name = getattr(
9898
receiver.__self__, "__class__", type
9999
).__name__
100-
text = "{}.{}".format(receiver_class_name, receiver_name)
100+
text = f"{receiver_class_name}.{receiver_name}"
101101
else:
102102
text = receiver_name
103103
receivers.append(text)

debug_toolbar/panels/sql/tracking.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
class SQLQueryTriggered(Exception):
1818
"""Thrown when template panel triggers a query"""
1919

20-
pass
21-
2220

2321
class ThreadLocalState(local):
2422
def __init__(self):

debug_toolbar/panels/sql/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def reformat_sql(sql, with_toggle=False):
2626
if not with_toggle:
2727
return formatted
2828
simple = simplify(parse_sql(sql, aligned_indent=False))
29-
uncollapsed = '<span class="djDebugUncollapsed">{}</span>'.format(simple)
30-
collapsed = '<span class="djDebugCollapsed djdt-hidden">{}</span>'.format(formatted)
29+
uncollapsed = f'<span class="djDebugUncollapsed">{simple}</span>'
30+
collapsed = f'<span class="djDebugCollapsed djdt-hidden">{formatted}</span>'
3131
return collapsed + uncollapsed
3232

3333

debug_toolbar/panels/sql/views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ def sql_explain(request, verified_data):
4949
# SQLite's EXPLAIN dumps the low-level opcodes generated for a query;
5050
# EXPLAIN QUERY PLAN dumps a more human-readable summary
5151
# See https://www.sqlite.org/lang_explain.html for details
52-
cursor.execute("EXPLAIN QUERY PLAN {}".format(sql), params)
52+
cursor.execute(f"EXPLAIN QUERY PLAN {sql}", params)
5353
elif vendor == "postgresql":
54-
cursor.execute("EXPLAIN ANALYZE {}".format(sql), params)
54+
cursor.execute(f"EXPLAIN ANALYZE {sql}", params)
5555
else:
56-
cursor.execute("EXPLAIN {}".format(sql), params)
56+
cursor.execute(f"EXPLAIN {sql}", params)
5757
headers = [d[0] for d in cursor.description]
5858
result = cursor.fetchall()
5959

debug_toolbar/panels/templates/panel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def _request_context_bind_template(self, template):
4242
self.context_processors = OrderedDict()
4343
updates = {}
4444
for processor in processors:
45-
name = "{}.{}".format(processor.__module__, processor.__name__)
45+
name = f"{processor.__module__}.{processor.__name__}"
4646
context = processor(self.request)
4747
self.context_processors[name] = context
4848
updates.update(context)

debug_toolbar/panels/templates/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def template_source(request):
4444
except TemplateDoesNotExist:
4545
pass
4646
else:
47-
source = "Template Does Not Exist: {}".format(template_origin_name)
47+
source = f"Template Does Not Exist: {template_origin_name}"
4848

4949
try:
5050
from pygments import highlight

debug_toolbar/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def get_module_path(module_name):
2727
try:
2828
module = import_module(module_name)
2929
except ImportError as e:
30-
raise ImproperlyConfigured("Error importing HIDE_IN_STACKTRACES: {}".format(e))
30+
raise ImproperlyConfigured(f"Error importing HIDE_IN_STACKTRACES: {e}")
3131
else:
3232
source_path = inspect.getsourcefile(module)
3333
if source_path.endswith("__init__.py"):
@@ -157,7 +157,7 @@ def get_name_from_obj(obj):
157157

158158
if hasattr(obj, "__module__"):
159159
module = obj.__module__
160-
name = "{}.{}".format(module, name)
160+
name = f"{module}.{name}"
161161

162162
return name
163163

tests/commands/test_debugsqlshell.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import io
22
import sys
33

4-
import django
54
from django.contrib.auth.models import User
65
from django.core import management
76
from django.db import connection
87
from django.test import TestCase
98
from django.test.utils import override_settings
109

11-
if connection.vendor == "postgresql" and django.VERSION >= (3, 0, 0):
10+
if connection.vendor == "postgresql":
1211
from django.db.backends.postgresql import base as base_module
1312
else:
1413
from django.db.backends import utils as base_module

tests/models.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,8 @@ class Binary(models.Model):
1111
field = models.BinaryField()
1212

1313

14-
try:
15-
from django.db.models import JSONField
16-
except ImportError: # Django<3.1
17-
try:
18-
from django.contrib.postgres.fields import JSONField
19-
except ImportError: # psycopg2 not installed
20-
JSONField = None
21-
22-
23-
if JSONField:
24-
25-
class PostgresJSON(models.Model):
26-
field = JSONField()
14+
class JSON(models.Model):
15+
field = models.JSONField()
2716

2817

2918
if settings.USE_GIS:

0 commit comments

Comments
 (0)