Skip to content

Commit

Permalink
Make debug_toolbar.settings import safe.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaugustin committed Feb 21, 2016
1 parent c2658d1 commit a8fa2cf
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 107 deletions.
2 changes: 1 addition & 1 deletion debug_toolbar/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ class DebugToolbarConfig(AppConfig):
verbose_name = _("Debug Toolbar")

def ready(self):
if dt_settings.PATCH_SETTINGS:
if dt_settings.get_patch_settings():
dt_settings.patch_all()
dt_settings.check_middleware()
4 changes: 2 additions & 2 deletions debug_toolbar/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class DebugToolbarMiddleware(object):
def __init__(self):
# If SHOW_TOOLBAR_CALLBACK is a string, which is the recommended
# setup, resolve it to the corresponding callable.
func_or_path = dt_settings.CONFIG['SHOW_TOOLBAR_CALLBACK']
func_or_path = dt_settings.get_config()['SHOW_TOOLBAR_CALLBACK']
if isinstance(func_or_path, six.string_types):
self.show_toolbar = import_string(func_or_path)
else:
Expand Down Expand Up @@ -113,7 +113,7 @@ def process_response(self, request, response):

# Insert the toolbar in the response.
content = force_text(response.content, encoding=settings.DEFAULT_CHARSET)
insert_before = dt_settings.CONFIG['INSERT_BEFORE']
insert_before = dt_settings.get_config()['INSERT_BEFORE']
try: # Python >= 2.7
pattern = re.escape(insert_before)
bits = re.split(pattern, content, flags=re.IGNORECASE)
Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/panels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def panel_id(self):
@property
def enabled(self):
# Check to see if settings has a default value for it
disabled_panels = dt_settings.CONFIG['DISABLE_PANELS']
disabled_panels = dt_settings.get_config()['DISABLE_PANELS']
panel_path = get_name_from_obj(self)
# Some panels such as the SQLPanel and TemplatesPanel exist in a
# panel module, but can be disabled without panel in the path.
Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/panels/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def wrapped(self, *args, **kwargs):
value = method(self, *args, **kwargs)
t = time.time() - t

if dt_settings.CONFIG['ENABLE_STACKTRACES']:
if dt_settings.get_config()['ENABLE_STACKTRACES']:
stacktrace = tidy_stacktrace(reversed(get_stack()))
else:
stacktrace = []
Expand Down
2 changes: 1 addition & 1 deletion debug_toolbar/panels/profiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def generate_stats(self, request, response):
func_list = []
self.add_node(func_list,
root,
dt_settings.CONFIG['PROFILER_MAX_DEPTH'],
dt_settings.get_config()['PROFILER_MAX_DEPTH'],
root.stats[3] / 8)

self.record_stats({'func_list': func_list})
4 changes: 2 additions & 2 deletions debug_toolbar/panels/sql/tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def _record(self, method, sql, params):
finally:
stop_time = time()
duration = (stop_time - start_time) * 1000
if dt_settings.CONFIG['ENABLE_STACKTRACES']:
if dt_settings.get_config()['ENABLE_STACKTRACES']:
stacktrace = tidy_stacktrace(reversed(get_stack()))
else:
stacktrace = []
Expand All @@ -129,7 +129,7 @@ def _record(self, method, sql, params):
'stacktrace': stacktrace,
'start_time': start_time,
'stop_time': stop_time,
'is_slow': duration > dt_settings.CONFIG['SQL_WARNING_THRESHOLD'],
'is_slow': duration > dt_settings.get_config()['SQL_WARNING_THRESHOLD'],
'is_select': sql.lower().strip().startswith('select'),
'template_info': template_info,
}
Expand Down
195 changes: 105 additions & 90 deletions debug_toolbar/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from django.conf import settings
from django.utils import six
from django.utils.lru_cache import lru_cache
from django.utils.module_loading import import_string

# Always import this module as follows:
Expand Down Expand Up @@ -39,32 +40,63 @@
'SQL_WARNING_THRESHOLD': 500, # milliseconds
}

USER_CONFIG = getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {})
# Backward-compatibility for 1.0, remove in 2.0.
_RENAMED_CONFIG = {
'RESULTS_STORE_SIZE': 'RESULTS_CACHE_SIZE',
'ROOT_TAG_ATTRS': 'ROOT_TAG_EXTRA_ATTRS',
'HIDDEN_STACKTRACE_MODULES': 'HIDE_IN_STACKTRACES'
}
for old_name, new_name in _RENAMED_CONFIG.items():
if old_name in USER_CONFIG:

@lru_cache()
def get_config():
USER_CONFIG = getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {})

# Backward-compatibility for 1.0, remove in 2.0.
_RENAMED_CONFIG = {
'RESULTS_STORE_SIZE': 'RESULTS_CACHE_SIZE',
'ROOT_TAG_ATTRS': 'ROOT_TAG_EXTRA_ATTRS',
'HIDDEN_STACKTRACE_MODULES': 'HIDE_IN_STACKTRACES'
}
for old_name, new_name in _RENAMED_CONFIG.items():
if old_name in USER_CONFIG:
warnings.warn(
"%r was renamed to %r. Update your DEBUG_TOOLBAR_CONFIG "
"setting." % (old_name, new_name), DeprecationWarning)
USER_CONFIG[new_name] = USER_CONFIG.pop(old_name)

if 'HIDE_DJANGO_SQL' in USER_CONFIG:
warnings.warn(
"HIDE_DJANGO_SQL was removed. Update your "
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
USER_CONFIG.pop('HIDE_DJANGO_SQL')

if 'TAG' in USER_CONFIG:
warnings.warn(
"%r was renamed to %r. Update your DEBUG_TOOLBAR_CONFIG "
"setting." % (old_name, new_name), DeprecationWarning)
USER_CONFIG[new_name] = USER_CONFIG.pop(old_name)
if 'HIDE_DJANGO_SQL' in USER_CONFIG:
warnings.warn(
"HIDE_DJANGO_SQL was removed. Update your "
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
USER_CONFIG.pop('HIDE_DJANGO_SQL')
if 'TAG' in USER_CONFIG:
warnings.warn(
"TAG was replaced by INSERT_BEFORE. Update your "
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
USER_CONFIG['INSERT_BEFORE'] = '</%s>' % USER_CONFIG.pop('TAG')

CONFIG = CONFIG_DEFAULTS.copy()
CONFIG.update(USER_CONFIG)
"TAG was replaced by INSERT_BEFORE. Update your "
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
USER_CONFIG['INSERT_BEFORE'] = '</%s>' % USER_CONFIG.pop('TAG')

CONFIG = CONFIG_DEFAULTS.copy()
CONFIG.update(USER_CONFIG)

if 'INTERCEPT_REDIRECTS' in USER_CONFIG:
warnings.warn(
"INTERCEPT_REDIRECTS is deprecated. Please use the "
"DISABLE_PANELS config in the "
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
if USER_CONFIG['INTERCEPT_REDIRECTS']:
if 'debug_toolbar.panels.redirects.RedirectsPanel' \
in CONFIG['DISABLE_PANELS']:
# RedirectsPanel should be enabled
try:
CONFIG['DISABLE_PANELS'].remove(
'debug_toolbar.panels.redirects.RedirectsPanel'
)
except KeyError:
# We wanted to remove it, but it didn't exist. This is fine
pass
elif 'debug_toolbar.panels.redirects.RedirectsPanel' \
not in CONFIG['DISABLE_PANELS']:
# RedirectsPanel should be disabled
CONFIG['DISABLE_PANELS'].add(
'debug_toolbar.panels.redirects.RedirectsPanel'
)

return CONFIG


PANELS_DEFAULTS = [
Expand All @@ -82,71 +114,54 @@
'debug_toolbar.panels.redirects.RedirectsPanel',
]

try:
PANELS = list(settings.DEBUG_TOOLBAR_PANELS)
except AttributeError:
PANELS = PANELS_DEFAULTS
else:
# Backward-compatibility for 1.0, remove in 2.0.
_RENAMED_PANELS = {
'debug_toolbar.panels.version.VersionDebugPanel':
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerDebugPanel':
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings_vars.SettingsDebugPanel':
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeaderDebugPanel':
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.request_vars.RequestVarsDebugPanel':
'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLDebugPanel':
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.template.TemplateDebugPanel':
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CacheDebugPanel':
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalDebugPanel':
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logger.LoggingDebugPanel':
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.InterceptRedirectsDebugPanel':
'debug_toolbar.panels.redirects.RedirectsPanel',
'debug_toolbar.panels.profiling.ProfilingDebugPanel':
'debug_toolbar.panels.profiling.ProfilingPanel',
}
for index, old_panel in enumerate(PANELS):
new_panel = _RENAMED_PANELS.get(old_panel)
if new_panel is not None:
warnings.warn(
"%r was renamed to %r. Update your DEBUG_TOOLBAR_PANELS "
"setting." % (old_panel, new_panel), DeprecationWarning)
PANELS[index] = new_panel


if 'INTERCEPT_REDIRECTS' in USER_CONFIG:
warnings.warn(
"INTERCEPT_REDIRECTS is deprecated. Please use the "
"DISABLE_PANELS config in the "
"DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning)
if USER_CONFIG['INTERCEPT_REDIRECTS']:
if 'debug_toolbar.panels.redirects.RedirectsPanel' \
in CONFIG['DISABLE_PANELS']:
# RedirectsPanel should be enabled
try:
CONFIG['DISABLE_PANELS'].remove(
'debug_toolbar.panels.redirects.RedirectsPanel'
)
except KeyError:
# We wanted to remove it, but it didn't exist. This is fine
pass
elif 'debug_toolbar.panels.redirects.RedirectsPanel' \
not in CONFIG['DISABLE_PANELS']:
# RedirectsPanel should be disabled
CONFIG['DISABLE_PANELS'].add(
'debug_toolbar.panels.redirects.RedirectsPanel'
)

PATCH_SETTINGS = getattr(settings, 'DEBUG_TOOLBAR_PATCH_SETTINGS', settings.DEBUG)

@lru_cache()
def get_panels():
try:
PANELS = list(settings.DEBUG_TOOLBAR_PANELS)
except AttributeError:
PANELS = PANELS_DEFAULTS
else:
# Backward-compatibility for 1.0, remove in 2.0.
_RENAMED_PANELS = {
'debug_toolbar.panels.version.VersionDebugPanel':
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerDebugPanel':
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings_vars.SettingsDebugPanel':
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeaderDebugPanel':
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.request_vars.RequestVarsDebugPanel':
'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLDebugPanel':
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.template.TemplateDebugPanel':
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CacheDebugPanel':
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalDebugPanel':
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logger.LoggingDebugPanel':
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.InterceptRedirectsDebugPanel':
'debug_toolbar.panels.redirects.RedirectsPanel',
'debug_toolbar.panels.profiling.ProfilingDebugPanel':
'debug_toolbar.panels.profiling.ProfilingPanel',
}
for index, old_panel in enumerate(PANELS):
new_panel = _RENAMED_PANELS.get(old_panel)
if new_panel is not None:
warnings.warn(
"%r was renamed to %r. Update your DEBUG_TOOLBAR_PANELS "
"setting." % (old_panel, new_panel), DeprecationWarning)
PANELS[index] = new_panel
return PANELS


@lru_cache()
def get_patch_settings():
return getattr(settings, 'DEBUG_TOOLBAR_PATCH_SETTINGS', settings.DEBUG)


# The following functions can monkey-patch settings automatically. Several
Expand Down
4 changes: 2 additions & 2 deletions debug_toolbar/toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class DebugToolbar(object):

def __init__(self, request):
self.request = request
self.config = dt_settings.CONFIG.copy()
self.config = dt_settings.get_config().copy()
self._panels = OrderedDict()
for panel_class in self.get_panel_classes():
panel_instance = panel_class(self)
Expand Down Expand Up @@ -107,7 +107,7 @@ def get_panel_classes(cls):
if cls._panel_classes is None:
# Load panels in a temporary variable for thread safety.
panel_classes = []
for panel_path in dt_settings.PANELS:
for panel_path in dt_settings.get_panels():
# This logic could be replaced with import_by_path in Django 1.6.
try:
panel_module, panel_classname = panel_path.rsplit('.', 1)
Expand Down
5 changes: 2 additions & 3 deletions debug_toolbar/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
from django.utils.html import escape
from django.utils.safestring import mark_safe

from debug_toolbar import settings as dt_settings
from debug_toolbar.compat import linebreak_iter

from .settings import CONFIG

try:
import threading
except ImportError:
Expand All @@ -43,7 +42,7 @@ def get_module_path(module_name):

hidden_paths = [
get_module_path(module_name)
for module_name in CONFIG['HIDE_IN_STACKTRACES']
for module_name in dt_settings.get_config()['HIDE_IN_STACKTRACES']
]


Expand Down
6 changes: 2 additions & 4 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@
@receiver(setting_changed)
def update_toolbar_config(**kwargs):
if kwargs['setting'] == 'DEBUG_TOOLBAR_CONFIG':
dt_settings.CONFIG = {}
dt_settings.CONFIG.update(dt_settings.CONFIG_DEFAULTS)
dt_settings.CONFIG.update(kwargs['value'] or {})
dt_settings.get_config.cache_clear()
# This doesn't account for deprecated configuration options.


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

0 comments on commit a8fa2cf

Please sign in to comment.