Skip to content

Commit a8fa2cf

Browse files
committed
Make debug_toolbar.settings import safe.
Fix #801.
1 parent c2658d1 commit a8fa2cf

File tree

10 files changed

+119
-107
lines changed

10 files changed

+119
-107
lines changed

debug_toolbar/apps.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ class DebugToolbarConfig(AppConfig):
1111
verbose_name = _("Debug Toolbar")
1212

1313
def ready(self):
14-
if dt_settings.PATCH_SETTINGS:
14+
if dt_settings.get_patch_settings():
1515
dt_settings.patch_all()
1616
dt_settings.check_middleware()

debug_toolbar/middleware.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class DebugToolbarMiddleware(object):
4343
def __init__(self):
4444
# If SHOW_TOOLBAR_CALLBACK is a string, which is the recommended
4545
# setup, resolve it to the corresponding callable.
46-
func_or_path = dt_settings.CONFIG['SHOW_TOOLBAR_CALLBACK']
46+
func_or_path = dt_settings.get_config()['SHOW_TOOLBAR_CALLBACK']
4747
if isinstance(func_or_path, six.string_types):
4848
self.show_toolbar = import_string(func_or_path)
4949
else:
@@ -113,7 +113,7 @@ def process_response(self, request, response):
113113

114114
# Insert the toolbar in the response.
115115
content = force_text(response.content, encoding=settings.DEFAULT_CHARSET)
116-
insert_before = dt_settings.CONFIG['INSERT_BEFORE']
116+
insert_before = dt_settings.get_config()['INSERT_BEFORE']
117117
try: # Python >= 2.7
118118
pattern = re.escape(insert_before)
119119
bits = re.split(pattern, content, flags=re.IGNORECASE)

debug_toolbar/panels/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def panel_id(self):
2424
@property
2525
def enabled(self):
2626
# Check to see if settings has a default value for it
27-
disabled_panels = dt_settings.CONFIG['DISABLE_PANELS']
27+
disabled_panels = dt_settings.get_config()['DISABLE_PANELS']
2828
panel_path = get_name_from_obj(self)
2929
# Some panels such as the SQLPanel and TemplatesPanel exist in a
3030
# panel module, but can be disabled without panel in the path.

debug_toolbar/panels/cache.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def wrapped(self, *args, **kwargs):
3333
value = method(self, *args, **kwargs)
3434
t = time.time() - t
3535

36-
if dt_settings.CONFIG['ENABLE_STACKTRACES']:
36+
if dt_settings.get_config()['ENABLE_STACKTRACES']:
3737
stacktrace = tidy_stacktrace(reversed(get_stack()))
3838
else:
3939
stacktrace = []

debug_toolbar/panels/profiling.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def generate_stats(self, request, response):
172172
func_list = []
173173
self.add_node(func_list,
174174
root,
175-
dt_settings.CONFIG['PROFILER_MAX_DEPTH'],
175+
dt_settings.get_config()['PROFILER_MAX_DEPTH'],
176176
root.stats[3] / 8)
177177

178178
self.record_stats({'func_list': func_list})

debug_toolbar/panels/sql/tracking.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def _record(self, method, sql, params):
102102
finally:
103103
stop_time = time()
104104
duration = (stop_time - start_time) * 1000
105-
if dt_settings.CONFIG['ENABLE_STACKTRACES']:
105+
if dt_settings.get_config()['ENABLE_STACKTRACES']:
106106
stacktrace = tidy_stacktrace(reversed(get_stack()))
107107
else:
108108
stacktrace = []
@@ -129,7 +129,7 @@ def _record(self, method, sql, params):
129129
'stacktrace': stacktrace,
130130
'start_time': start_time,
131131
'stop_time': stop_time,
132-
'is_slow': duration > dt_settings.CONFIG['SQL_WARNING_THRESHOLD'],
132+
'is_slow': duration > dt_settings.get_config()['SQL_WARNING_THRESHOLD'],
133133
'is_select': sql.lower().strip().startswith('select'),
134134
'template_info': template_info,
135135
}

debug_toolbar/settings.py

+105-90
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from django.conf import settings
77
from django.utils import six
8+
from django.utils.lru_cache import lru_cache
89
from django.utils.module_loading import import_string
910

1011
# Always import this module as follows:
@@ -39,32 +40,63 @@
3940
'SQL_WARNING_THRESHOLD': 500, # milliseconds
4041
}
4142

42-
USER_CONFIG = getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {})
43-
# Backward-compatibility for 1.0, remove in 2.0.
44-
_RENAMED_CONFIG = {
45-
'RESULTS_STORE_SIZE': 'RESULTS_CACHE_SIZE',
46-
'ROOT_TAG_ATTRS': 'ROOT_TAG_EXTRA_ATTRS',
47-
'HIDDEN_STACKTRACE_MODULES': 'HIDE_IN_STACKTRACES'
48-
}
49-
for old_name, new_name in _RENAMED_CONFIG.items():
50-
if old_name in USER_CONFIG:
43+
44+
@lru_cache()
45+
def get_config():
46+
USER_CONFIG = getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {})
47+
48+
# Backward-compatibility for 1.0, remove in 2.0.
49+
_RENAMED_CONFIG = {
50+
'RESULTS_STORE_SIZE': 'RESULTS_CACHE_SIZE',
51+
'ROOT_TAG_ATTRS': 'ROOT_TAG_EXTRA_ATTRS',
52+
'HIDDEN_STACKTRACE_MODULES': 'HIDE_IN_STACKTRACES'
53+
}
54+
for old_name, new_name in _RENAMED_CONFIG.items():
55+
if old_name in USER_CONFIG:
56+
warnings.warn(
57+
"%r was renamed to %r. Update your DEBUG_TOOLBAR_CONFIG "
58+
"setting." % (old_name, new_name), DeprecationWarning)
59+
USER_CONFIG[new_name] = USER_CONFIG.pop(old_name)
60+
61+
if 'HIDE_DJANGO_SQL' in USER_CONFIG:
62+
warnings.warn(
63+
"HIDE_DJANGO_SQL was removed. Update your "
64+
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
65+
USER_CONFIG.pop('HIDE_DJANGO_SQL')
66+
67+
if 'TAG' in USER_CONFIG:
5168
warnings.warn(
52-
"%r was renamed to %r. Update your DEBUG_TOOLBAR_CONFIG "
53-
"setting." % (old_name, new_name), DeprecationWarning)
54-
USER_CONFIG[new_name] = USER_CONFIG.pop(old_name)
55-
if 'HIDE_DJANGO_SQL' in USER_CONFIG:
56-
warnings.warn(
57-
"HIDE_DJANGO_SQL was removed. Update your "
58-
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
59-
USER_CONFIG.pop('HIDE_DJANGO_SQL')
60-
if 'TAG' in USER_CONFIG:
61-
warnings.warn(
62-
"TAG was replaced by INSERT_BEFORE. Update your "
63-
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
64-
USER_CONFIG['INSERT_BEFORE'] = '</%s>' % USER_CONFIG.pop('TAG')
65-
66-
CONFIG = CONFIG_DEFAULTS.copy()
67-
CONFIG.update(USER_CONFIG)
69+
"TAG was replaced by INSERT_BEFORE. Update your "
70+
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
71+
USER_CONFIG['INSERT_BEFORE'] = '</%s>' % USER_CONFIG.pop('TAG')
72+
73+
CONFIG = CONFIG_DEFAULTS.copy()
74+
CONFIG.update(USER_CONFIG)
75+
76+
if 'INTERCEPT_REDIRECTS' in USER_CONFIG:
77+
warnings.warn(
78+
"INTERCEPT_REDIRECTS is deprecated. Please use the "
79+
"DISABLE_PANELS config in the "
80+
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
81+
if USER_CONFIG['INTERCEPT_REDIRECTS']:
82+
if 'debug_toolbar.panels.redirects.RedirectsPanel' \
83+
in CONFIG['DISABLE_PANELS']:
84+
# RedirectsPanel should be enabled
85+
try:
86+
CONFIG['DISABLE_PANELS'].remove(
87+
'debug_toolbar.panels.redirects.RedirectsPanel'
88+
)
89+
except KeyError:
90+
# We wanted to remove it, but it didn't exist. This is fine
91+
pass
92+
elif 'debug_toolbar.panels.redirects.RedirectsPanel' \
93+
not in CONFIG['DISABLE_PANELS']:
94+
# RedirectsPanel should be disabled
95+
CONFIG['DISABLE_PANELS'].add(
96+
'debug_toolbar.panels.redirects.RedirectsPanel'
97+
)
98+
99+
return CONFIG
68100

69101

70102
PANELS_DEFAULTS = [
@@ -82,71 +114,54 @@
82114
'debug_toolbar.panels.redirects.RedirectsPanel',
83115
]
84116

85-
try:
86-
PANELS = list(settings.DEBUG_TOOLBAR_PANELS)
87-
except AttributeError:
88-
PANELS = PANELS_DEFAULTS
89-
else:
90-
# Backward-compatibility for 1.0, remove in 2.0.
91-
_RENAMED_PANELS = {
92-
'debug_toolbar.panels.version.VersionDebugPanel':
93-
'debug_toolbar.panels.versions.VersionsPanel',
94-
'debug_toolbar.panels.timer.TimerDebugPanel':
95-
'debug_toolbar.panels.timer.TimerPanel',
96-
'debug_toolbar.panels.settings_vars.SettingsDebugPanel':
97-
'debug_toolbar.panels.settings.SettingsPanel',
98-
'debug_toolbar.panels.headers.HeaderDebugPanel':
99-
'debug_toolbar.panels.headers.HeadersPanel',
100-
'debug_toolbar.panels.request_vars.RequestVarsDebugPanel':
101-
'debug_toolbar.panels.request.RequestPanel',
102-
'debug_toolbar.panels.sql.SQLDebugPanel':
103-
'debug_toolbar.panels.sql.SQLPanel',
104-
'debug_toolbar.panels.template.TemplateDebugPanel':
105-
'debug_toolbar.panels.templates.TemplatesPanel',
106-
'debug_toolbar.panels.cache.CacheDebugPanel':
107-
'debug_toolbar.panels.cache.CachePanel',
108-
'debug_toolbar.panels.signals.SignalDebugPanel':
109-
'debug_toolbar.panels.signals.SignalsPanel',
110-
'debug_toolbar.panels.logger.LoggingDebugPanel':
111-
'debug_toolbar.panels.logging.LoggingPanel',
112-
'debug_toolbar.panels.redirects.InterceptRedirectsDebugPanel':
113-
'debug_toolbar.panels.redirects.RedirectsPanel',
114-
'debug_toolbar.panels.profiling.ProfilingDebugPanel':
115-
'debug_toolbar.panels.profiling.ProfilingPanel',
116-
}
117-
for index, old_panel in enumerate(PANELS):
118-
new_panel = _RENAMED_PANELS.get(old_panel)
119-
if new_panel is not None:
120-
warnings.warn(
121-
"%r was renamed to %r. Update your DEBUG_TOOLBAR_PANELS "
122-
"setting." % (old_panel, new_panel), DeprecationWarning)
123-
PANELS[index] = new_panel
124-
125-
126-
if 'INTERCEPT_REDIRECTS' in USER_CONFIG:
127-
warnings.warn(
128-
"INTERCEPT_REDIRECTS is deprecated. Please use the "
129-
"DISABLE_PANELS config in the "
130-
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
131-
if USER_CONFIG['INTERCEPT_REDIRECTS']:
132-
if 'debug_toolbar.panels.redirects.RedirectsPanel' \
133-
in CONFIG['DISABLE_PANELS']:
134-
# RedirectsPanel should be enabled
135-
try:
136-
CONFIG['DISABLE_PANELS'].remove(
137-
'debug_toolbar.panels.redirects.RedirectsPanel'
138-
)
139-
except KeyError:
140-
# We wanted to remove it, but it didn't exist. This is fine
141-
pass
142-
elif 'debug_toolbar.panels.redirects.RedirectsPanel' \
143-
not in CONFIG['DISABLE_PANELS']:
144-
# RedirectsPanel should be disabled
145-
CONFIG['DISABLE_PANELS'].add(
146-
'debug_toolbar.panels.redirects.RedirectsPanel'
147-
)
148-
149-
PATCH_SETTINGS = getattr(settings, 'DEBUG_TOOLBAR_PATCH_SETTINGS', settings.DEBUG)
117+
118+
@lru_cache()
119+
def get_panels():
120+
try:
121+
PANELS = list(settings.DEBUG_TOOLBAR_PANELS)
122+
except AttributeError:
123+
PANELS = PANELS_DEFAULTS
124+
else:
125+
# Backward-compatibility for 1.0, remove in 2.0.
126+
_RENAMED_PANELS = {
127+
'debug_toolbar.panels.version.VersionDebugPanel':
128+
'debug_toolbar.panels.versions.VersionsPanel',
129+
'debug_toolbar.panels.timer.TimerDebugPanel':
130+
'debug_toolbar.panels.timer.TimerPanel',
131+
'debug_toolbar.panels.settings_vars.SettingsDebugPanel':
132+
'debug_toolbar.panels.settings.SettingsPanel',
133+
'debug_toolbar.panels.headers.HeaderDebugPanel':
134+
'debug_toolbar.panels.headers.HeadersPanel',
135+
'debug_toolbar.panels.request_vars.RequestVarsDebugPanel':
136+
'debug_toolbar.panels.request.RequestPanel',
137+
'debug_toolbar.panels.sql.SQLDebugPanel':
138+
'debug_toolbar.panels.sql.SQLPanel',
139+
'debug_toolbar.panels.template.TemplateDebugPanel':
140+
'debug_toolbar.panels.templates.TemplatesPanel',
141+
'debug_toolbar.panels.cache.CacheDebugPanel':
142+
'debug_toolbar.panels.cache.CachePanel',
143+
'debug_toolbar.panels.signals.SignalDebugPanel':
144+
'debug_toolbar.panels.signals.SignalsPanel',
145+
'debug_toolbar.panels.logger.LoggingDebugPanel':
146+
'debug_toolbar.panels.logging.LoggingPanel',
147+
'debug_toolbar.panels.redirects.InterceptRedirectsDebugPanel':
148+
'debug_toolbar.panels.redirects.RedirectsPanel',
149+
'debug_toolbar.panels.profiling.ProfilingDebugPanel':
150+
'debug_toolbar.panels.profiling.ProfilingPanel',
151+
}
152+
for index, old_panel in enumerate(PANELS):
153+
new_panel = _RENAMED_PANELS.get(old_panel)
154+
if new_panel is not None:
155+
warnings.warn(
156+
"%r was renamed to %r. Update your DEBUG_TOOLBAR_PANELS "
157+
"setting." % (old_panel, new_panel), DeprecationWarning)
158+
PANELS[index] = new_panel
159+
return PANELS
160+
161+
162+
@lru_cache()
163+
def get_patch_settings():
164+
return getattr(settings, 'DEBUG_TOOLBAR_PATCH_SETTINGS', settings.DEBUG)
150165

151166

152167
# The following functions can monkey-patch settings automatically. Several

debug_toolbar/toolbar.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class DebugToolbar(object):
2121

2222
def __init__(self, request):
2323
self.request = request
24-
self.config = dt_settings.CONFIG.copy()
24+
self.config = dt_settings.get_config().copy()
2525
self._panels = OrderedDict()
2626
for panel_class in self.get_panel_classes():
2727
panel_instance = panel_class(self)
@@ -107,7 +107,7 @@ def get_panel_classes(cls):
107107
if cls._panel_classes is None:
108108
# Load panels in a temporary variable for thread safety.
109109
panel_classes = []
110-
for panel_path in dt_settings.PANELS:
110+
for panel_path in dt_settings.get_panels():
111111
# This logic could be replaced with import_by_path in Django 1.6.
112112
try:
113113
panel_module, panel_classname = panel_path.rsplit('.', 1)

debug_toolbar/utils.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
from django.utils.html import escape
1515
from django.utils.safestring import mark_safe
1616

17+
from debug_toolbar import settings as dt_settings
1718
from debug_toolbar.compat import linebreak_iter
1819

19-
from .settings import CONFIG
20-
2120
try:
2221
import threading
2322
except ImportError:
@@ -43,7 +42,7 @@ def get_module_path(module_name):
4342

4443
hidden_paths = [
4544
get_module_path(module_name)
46-
for module_name in CONFIG['HIDE_IN_STACKTRACES']
45+
for module_name in dt_settings.get_config()['HIDE_IN_STACKTRACES']
4746
]
4847

4948

tests/__init__.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@
1010
@receiver(setting_changed)
1111
def update_toolbar_config(**kwargs):
1212
if kwargs['setting'] == 'DEBUG_TOOLBAR_CONFIG':
13-
dt_settings.CONFIG = {}
14-
dt_settings.CONFIG.update(dt_settings.CONFIG_DEFAULTS)
15-
dt_settings.CONFIG.update(kwargs['value'] or {})
13+
dt_settings.get_config.cache_clear()
1614
# This doesn't account for deprecated configuration options.
1715

1816

1917
@receiver(setting_changed)
2018
def update_toolbar_panels(**kwargs):
2119
if kwargs['setting'] == 'DEBUG_TOOLBAR_PANELS':
22-
dt_settings.PANELS = kwargs['value'] or dt_settings.PANELS_DEFAULTS
20+
dt_settings.get_panels.cache_clear()
2321
DebugToolbar._panel_classes = None
2422
# Not implemented: invalidate debug_toolbar.urls.
2523
# This doesn't account for deprecated panel names.

0 commit comments

Comments
 (0)