diff options
| author | David Cramer | 2012-01-12 19:13:47 -0800 |
|---|---|---|
| committer | David Cramer | 2012-01-12 19:13:47 -0800 |
| commit | 01cd08518ded622d3308dd539b00ebbf7012894e (patch) | |
| tree | a9cca14ff92d4602a51d4999430574587a733d1d | |
| parent | c4eeef24faa81e7bc64ebfbd72c046f25c7b3381 (diff) | |
| download | django-debug-toolbar-01cd08518ded622d3308dd539b00ebbf7012894e.tar.bz2 | |
pep8
24 files changed, 203 insertions, 177 deletions
diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 8f0445a..3009b5f 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -5,7 +5,6 @@ import imp import thread from django.conf import settings -from django.conf.urls.defaults import include, patterns from django.http import HttpResponseRedirect from django.shortcuts import render_to_response from django.utils.encoding import smart_unicode @@ -16,6 +15,7 @@ from debug_toolbar.toolbar.loader import DebugToolbar _HTML_TYPES = ('text/html', 'application/xhtml+xml') + def replace_insensitive(string, target, replacement): """ Similar to string.replace() but is case insensitive @@ -25,9 +25,10 @@ def replace_insensitive(string, target, replacement): index = no_case.rfind(target.lower()) if index >= 0: return string[:index] + replacement + string[index + len(target):] - else: # no results so return the original string + else: # no results so return the original string return string + class DebugToolbarMiddleware(object): """ Middleware to set up Debug Toolbar on incoming request and render toolbar @@ -43,10 +44,10 @@ class DebugToolbarMiddleware(object): self._urlconfs = {} # Set method to use to decide to show toolbar - self.show_toolbar = self._show_toolbar # default + self.show_toolbar = self._show_toolbar # default # The tag to attach the toolbar to - self.tag= u'</body>' + self.tag = u'</body>' if hasattr(settings, 'DEBUG_TOOLBAR_CONFIG'): show_toolbar_callback = settings.DEBUG_TOOLBAR_CONFIG.get( diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py index b4f11fb..f1751d8 100644 --- a/debug_toolbar/panels/__init__.py +++ b/debug_toolbar/panels/__init__.py @@ -9,41 +9,41 @@ class DebugPanel(object): """ # name = 'Base' # template = 'debug_toolbar/panels/base.html' - has_content = False # If content returns something, set to true in subclass - + has_content = False # If content returns something, set to true in subclass + # We'll maintain a local context instance so we can expose our template # context variables to panels which need them: context = {} - + # Panel methods def __init__(self, context={}): self.context.update(context) self.slug = slugify(self.name) - + def dom_id(self): return 'djDebug%sPanel' % (self.name.replace(' ', '')) - + def nav_title(self): """Title showing in toolbar""" raise NotImplementedError - + def nav_subtitle(self): """Subtitle showing until title in toolbar""" return '' - + def title(self): """Title showing in panel""" raise NotImplementedError - + def url(self): raise NotImplementedError - + def content(self): if self.has_content: context = self.context.copy() context.update(self.get_stats()) return render_to_string(self.template, context) - + def record_stats(self, stats): toolbar = DebugToolbarMiddleware.get_current() panel_stats = toolbar.stats.get(self.slug) @@ -51,17 +51,17 @@ class DebugPanel(object): panel_stats.update(stats) else: toolbar.stats[self.slug] = stats - + def get_stats(self): toolbar = DebugToolbarMiddleware.get_current() return toolbar.stats.get(self.slug, {}) - + # Standard middleware methods def process_request(self, request): pass - + def process_view(self, request, view_func, view_args, view_kwargs): pass - + def process_response(self, request, response): pass diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py index 620be86..ace343b 100644 --- a/debug_toolbar/panels/cache.py +++ b/debug_toolbar/panels/cache.py @@ -6,12 +6,13 @@ from django.core.cache.backends.base import BaseCache from django.utils.translation import ugettext_lazy as _ from debug_toolbar.panels import DebugPanel + class CacheStatTracker(BaseCache): """A small class used to track cache calls.""" def __init__(self, cache): self.cache = cache self.reset() - + def reset(self): self.calls = [] self.hits = 0 @@ -21,11 +22,11 @@ class CacheStatTracker(BaseCache): self.get_many = 0 self.deletes = 0 self.total_time = 0 - + def _get_func_info(self): stack = inspect.stack()[2] return (stack[1], stack[2], stack[3], stack[4]) - + def get(self, key, default=None): t = time.time() value = self.cache.get(key, default) @@ -38,7 +39,7 @@ class CacheStatTracker(BaseCache): self.gets += 1 self.calls.append((this_time, 'get', (key,), self._get_func_info())) return value - + def set(self, key, value, timeout=None): t = time.time() self.cache.set(key, value, timeout) @@ -46,7 +47,7 @@ class CacheStatTracker(BaseCache): self.total_time += this_time * 1000 self.sets += 1 self.calls.append((this_time, 'set', (key, value, timeout), self._get_func_info())) - + def delete(self, key): t = time.time() self.cache.delete(key) @@ -54,7 +55,7 @@ class CacheStatTracker(BaseCache): self.total_time += this_time * 1000 self.deletes += 1 self.calls.append((this_time, 'delete', (key,), self._get_func_info())) - + def get_many(self, keys): t = time.time() results = self.cache.get_many(keys) @@ -68,6 +69,7 @@ class CacheStatTracker(BaseCache): self.hits += 1 self.calls.append((this_time, 'get_many', (keys,), self._get_func_info())) + class CacheDebugPanel(DebugPanel): """ Panel that displays the cache statistics. @@ -75,7 +77,7 @@ class CacheDebugPanel(DebugPanel): name = 'Cache' template = 'debug_toolbar/panels/cache.html' has_content = True - + def __init__(self, *args, **kwargs): super(CacheDebugPanel, self).__init__(*args, **kwargs) # This is hackish but to prevent threading issues is somewhat needed @@ -85,16 +87,16 @@ class CacheDebugPanel(DebugPanel): else: self.cache = CacheStatTracker(cache.cache) cache.cache = self.cache - + def nav_title(self): return _('Cache: %.2fms') % self.cache.total_time - + def title(self): return _('Cache Usage') - + def url(self): return '' - + def process_response(self, request, response): self.record_stats({ 'cache_calls': len(self.cache.calls), diff --git a/debug_toolbar/panels/headers.py b/debug_toolbar/panels/headers.py index 181e88d..9824d0e 100644 --- a/debug_toolbar/panels/headers.py +++ b/debug_toolbar/panels/headers.py @@ -32,21 +32,21 @@ class HeaderDebugPanel(DebugPanel): 'SERVER_PROTOCOL', 'SERVER_SOFTWARE', ) - + def nav_title(self): return _('HTTP Headers') - + def title(self): return _('HTTP Headers') - + def url(self): return '' - + def process_request(self, request): self.headers = dict( [(k, request.META[k]) for k in self.header_filter if k in request.META] ) - + def process_response(self, request, response): self.record_stats({ 'headers': self.headers diff --git a/debug_toolbar/panels/logger.py b/debug_toolbar/panels/logger.py index 55ae9bd..e894b50 100644 --- a/debug_toolbar/panels/logger.py +++ b/debug_toolbar/panels/logger.py @@ -13,16 +13,16 @@ class LogCollector(object): if threading is None: raise NotImplementedError("threading module is not available, \ the logging panel cannot be used without it") - self.records = {} # a dictionary that maps threads to log records - + self.records = {} # a dictionary that maps threads to log records + def add_record(self, record, thread=None): # Avoid logging SQL queries since they are already in the SQL panel # TODO: Make this check whether SQL panel is enabled if record.get('channel', '') == 'django.db.backends': return - + self.get_records(thread).append(record) - + def get_records(self, thread=None): """ Returns a list of records for the provided thread, of if none is provided, @@ -33,7 +33,7 @@ class LogCollector(object): if thread not in self.records: self.records[thread] = [] return self.records[thread] - + def clear_records(self, thread=None): if thread is None: thread = threading.currentThread() @@ -45,7 +45,7 @@ class ThreadTrackingHandler(logging.Handler): def __init__(self, collector): logging.Handler.__init__(self) self.collector = collector - + def emit(self, record): record = { 'message': record.getMessage(), @@ -75,7 +75,7 @@ if logbook_supported: def __init__(self, collector): logbook.handlers.Handler.__init__(self, bubble=True) self.collector = collector - + def emit(self, record): record = { 'message': record.message, @@ -86,37 +86,37 @@ if logbook_supported: 'channel': record.channel, } self.collector.add_record(record) - - + logbook_handler = LogbookThreadTrackingHandler(collector) - logbook_handler.push_application() # register with logbook + logbook_handler.push_application() # register with logbook + class LoggingPanel(DebugPanel): name = 'Logging' template = 'debug_toolbar/panels/logger.html' has_content = True - + def process_request(self, request): collector.clear_records() - + def process_response(self, request, response): records = self.get_and_delete() self.record_stats({'records': records}) - + def get_and_delete(self): records = collector.get_records() collector.clear_records() return records - + def nav_title(self): return _("Logging") - + def nav_subtitle(self): # FIXME l10n: use ngettext return "%s message%s" % (len(collector.get_records()), (len(collector.get_records()) == 1) and '' or 's') - + def title(self): return _('Log Messages') - + def url(self): return '' diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py index d07fd2a..f21c345 100644 --- a/debug_toolbar/panels/profiling.py +++ b/debug_toolbar/panels/profiling.py @@ -32,7 +32,7 @@ class DjangoDebugToolbarStats(Stats): class FunctionCall(object): def __init__(self, statobj, func, depth=0, stats=None, - id=0, parent_ids=[], hsv=(0,0.5,1)): + id=0, parent_ids=[], hsv=(0, 0.5, 1)): self.statobj = statobj self.func = func if stats: @@ -49,10 +49,10 @@ class FunctionCall(object): return self.parent_classes def background(self): - r,g,b = hsv_to_rgb(*self.hsv) - return 'rgb(%f%%,%f%%,%f%%)' %(r*100, g*100, b*100) + r, g, b = hsv_to_rgb(*self.hsv) + return 'rgb(%f%%,%f%%,%f%%)' % (r * 100, g * 100, b * 100) - def func_std_string(self): # match what old profile produced + def func_std_string(self): # match what old profile produced func_name = self.func if func_name[:2] == ('~', 0): # special case for built-in functions @@ -65,7 +65,7 @@ class FunctionCall(object): file_name, line_num, method = self.func idx = file_name.find('/site-packages/') if idx > -1: - file_name = file_name[idx+14:] + file_name = file_name[(idx + 14):] file_path, file_name = file_name.rsplit(os.sep, 1) @@ -77,23 +77,23 @@ class FunctionCall(object): )) def subfuncs(self): - i=0 + i = 0 h, s, v = self.hsv count = len(self.statobj.all_callees[self.func]) for func, stats in self.statobj.all_callees[self.func].iteritems(): i += 1 - h1 = h + (i/count)/(self.depth+1) + h1 = h + (i / count) / (self.depth + 1) if stats[3] == 0: s1 = 0 else: - s1 = s*(stats[3]/self.stats[3]) + s1 = s * (stats[3] / self.stats[3]) yield FunctionCall(self.statobj, func, - self.depth+1, + self.depth + 1, stats=stats, id=str(self.id) + '_' + str(i), parent_ids=self.parent_ids + [self.id], - hsv=(h1,s1,1)) + hsv=(h1, s1, 1)) def count(self): return self.stats[1] @@ -111,7 +111,7 @@ class FunctionCall(object): if nc == 0: return 0 - return tt/nc + return tt / nc def cumtime_per_call(self): cc, nc, tt, ct = self.stats @@ -119,7 +119,7 @@ class FunctionCall(object): if cc == 0: return 0 - return ct/cc + return ct / cc def indent(self): return 16 * self.depth @@ -136,6 +136,7 @@ class FunctionCall(object): self._line_stats_text = False return self._line_stats_text + class ProfilingDebugPanel(DebugPanel): """ Panel that displays the Django version. @@ -201,6 +202,6 @@ class ProfilingDebugPanel(DebugPanel): root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0) func_list = [] - self.add_node(func_list, root, 10, root.stats[3]/8) + self.add_node(func_list, root, 10, root.stats[3] / 8) self.record_stats({'func_list': func_list}) diff --git a/debug_toolbar/panels/request_vars.py b/debug_toolbar/panels/request_vars.py index ee9cdc5..4f85052 100644 --- a/debug_toolbar/panels/request_vars.py +++ b/debug_toolbar/panels/request_vars.py @@ -3,6 +3,7 @@ from django.utils.translation import ugettext_lazy as _ from debug_toolbar.panels import DebugPanel from debug_toolbar.utils import get_name_from_obj + class RequestVarsDebugPanel(DebugPanel): """ A panel to display request variables (POST/GET, session, cookies). @@ -10,49 +11,49 @@ class RequestVarsDebugPanel(DebugPanel): name = 'RequestVars' template = 'debug_toolbar/panels/request_vars.html' has_content = True - + def __init__(self, *args, **kwargs): DebugPanel.__init__(self, *args, **kwargs) self.view_func = None self.view_args = None self.view_kwargs = None - + def nav_title(self): return _('Request Vars') - + def title(self): return _('Request Vars') - + def url(self): return '' - + def process_request(self, request): self.request = request - + def process_view(self, request, view_func, view_args, view_kwargs): self.view_func = view_func self.view_args = view_args self.view_kwargs = view_kwargs - + def process_response(self, request, response): self.record_stats({ 'get': [(k, self.request.GET.getlist(k)) for k in self.request.GET], 'post': [(k, self.request.POST.getlist(k)) for k in self.request.POST], 'cookies': [(k, self.request.COOKIES.get(k)) for k in self.request.COOKIES], }) - + if hasattr(self, 'view_func'): if self.view_func is not None: name = get_name_from_obj(self.view_func) else: name = '<no view>' - + self.record_stats({ 'view_func': name, 'view_args': self.view_args, 'view_kwargs': self.view_kwargs }) - + if hasattr(self.request, 'session'): self.record_stats({ 'session': [(k, self.request.session.get(k)) for k in self.request.session.iterkeys()] diff --git a/debug_toolbar/panels/settings_vars.py b/debug_toolbar/panels/settings_vars.py index e154dda..194295e 100644 --- a/debug_toolbar/panels/settings_vars.py +++ b/debug_toolbar/panels/settings_vars.py @@ -11,16 +11,16 @@ class SettingsVarsDebugPanel(DebugPanel): name = 'SettingsVars' template = 'debug_toolbar/panels/settings_vars.html' has_content = True - + def nav_title(self): return _('Settings') - + def title(self): return _('Settings from <code>%s</code>') % settings.SETTINGS_MODULE - + def url(self): return '' - + def process_response(self, request, response): self.record_stats({ 'settings': get_safe_settings(), diff --git a/debug_toolbar/panels/signals.py b/debug_toolbar/panels/signals.py index 1d60292..b7dbffe 100644 --- a/debug_toolbar/panels/signals.py +++ b/debug_toolbar/panels/signals.py @@ -15,6 +15,7 @@ except ImportError: from debug_toolbar.panels import DebugPanel + class SignalDebugPanel(DebugPanel): name = "Signals" template = 'debug_toolbar/panels/signals.html' diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index b27e6c0..18fffdc 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -18,12 +18,12 @@ from debug_toolbar.utils.tracking import replace_call @replace_call(BaseDatabaseWrapper.cursor) def cursor(func, self): result = func(self) - + djdt = DebugToolbarMiddleware.get_current() if not djdt: return result logger = djdt.get_panel(SQLDebugPanel) - + return CursorWrapper(result, self, logger=logger) @@ -39,7 +39,7 @@ def get_isolation_level_display(engine, level): } else: raise ValueError(engine) - + return choices.get(level) @@ -55,7 +55,7 @@ def get_transaction_status_display(engine, level): } else: raise ValueError(engine) - + return choices.get(level) @@ -67,7 +67,7 @@ class SQLDebugPanel(DebugPanel): name = 'SQL' template = 'debug_toolbar/panels/sql.html' has_content = True - + def __init__(self, *args, **kwargs): super(SQLDebugPanel, self).__init__(*args, **kwargs) self._offset = dict((k, len(connections[k].queries)) for k in connections) @@ -77,33 +77,33 @@ class SQLDebugPanel(DebugPanel): self._databases = {} self._transaction_status = {} self._transaction_ids = {} - + def get_transaction_id(self, alias): conn = connections[alias].connection if not conn: return None - + engine = conn.__class__.__module__.split('.', 1)[0] if engine == 'psycopg2': cur_status = conn.get_transaction_status() else: raise ValueError(engine) - + last_status = self._transaction_status.get(alias) self._transaction_status[alias] = cur_status - + if not cur_status: # No available state return None - + if cur_status != last_status: if cur_status: self._transaction_ids[alias] = uuid.uuid4().hex else: self._transaction_ids[alias] = None - + return self._transaction_ids[alias] - + def record(self, alias, **kwargs): self._queries.append((alias, kwargs)) if alias not in self._databases: @@ -116,10 +116,10 @@ class SQLDebugPanel(DebugPanel): self._databases[alias]['num_queries'] += 1 self._sql_time += kwargs['duration'] self._num_queries += 1 - + def nav_title(self): return _('SQL') - + def nav_subtitle(self): # TODO l10n: use ngettext return "%d %s in %.2fms" % ( @@ -127,30 +127,25 @@ class SQLDebugPanel(DebugPanel): (self._num_queries == 1) and 'query' or 'queries', self._sql_time ) - + def title(self): count = len(self._databases) - + return __('SQL Queries from %(count)d connection', 'SQL Queries from %(count)d connections', count) % dict( count=count, ) - + def url(self): return '' - + def process_response(self, request, response): if self._queries: width_ratio_tally = 0 - colors = [ - (256, 0, 0), # red - (0, 256, 0), # blue - (0, 0, 256), # green - ] - factor = int(256.0/(len(self._databases)*2.5)) + factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.itervalues()): rgb = [0, 0, 0] color = n % 3 - rgb[color] = 256 - n/3*factor + rgb[color] = 256 - n / 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: @@ -161,23 +156,23 @@ class SQLDebugPanel(DebugPanel): nn = 0 rgb[nn] = nc db['rgb_color'] = rgb - + trans_ids = {} trans_id = None i = 0 for alias, query in self._queries: trans_id = query.get('trans_id') last_trans_id = trans_ids.get(alias) - + if trans_id != last_trans_id: if last_trans_id: - self._queries[i-1][1]['ends_trans'] = True + self._queries[(i - 1)][1]['ends_trans'] = True trans_ids[alias] = trans_id if trans_id: query['starts_trans'] = True if trans_id: query['in_trans'] = True - + query['alias'] = alias if 'iso_level' in query: query['iso_level'] = get_isolation_level_display(query['engine'], query['iso_level']) @@ -187,14 +182,14 @@ class SQLDebugPanel(DebugPanel): query['rgb_color'] = self._databases[alias]['rgb_color'] try: query['width_ratio'] = (query['duration'] / self._sql_time) * 100 - query['width_ratio_relative'] = 100.0 * query['width_ratio'] / (100.0 - width_ratio_tally) + query['width_ratio_relative'] = 100.0 * query['width_ratio'] / (100.0 - width_ratio_tally) except ZeroDivisionError: query['width_ratio'] = 0 query['width_ratio_relative'] = 0 query['start_offset'] = width_ratio_tally query['end_offset'] = query['width_ratio'] + query['start_offset'] width_ratio_tally += query['width_ratio'] - + stacktrace = [] for frame in query['stacktrace']: params = map(escape, frame[0].rsplit('/', 1) + list(frame[1:])) @@ -205,10 +200,10 @@ class SQLDebugPanel(DebugPanel): continue query['stacktrace'] = mark_safe('\n'.join(stacktrace)) i += 1 - + if trans_id: - self._queries[i-1][1]['ends_trans'] = True - + self._queries[(i - 1)][1]['ends_trans'] = True + self.record_stats({ 'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']), 'queries': [q for a, q in self._queries], @@ -236,6 +231,6 @@ def swap_fields(sql): def reformat_sql(sql): stack = sqlparse.engine.FilterStack() - stack.preprocess.append(BoldKeywordFilter()) # add our custom filter - stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings + stack.preprocess.append(BoldKeywordFilter()) # add our custom filter + stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings return swap_fields(''.join(stack.run(sql))) diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py index a69b42a..48225a0 100644 --- a/debug_toolbar/panels/template.py +++ b/debug_toolbar/panels/template.py @@ -19,7 +19,7 @@ from debug_toolbar.utils.tracking.db import recording, SQLQueryTriggered from django.test.utils import instrumented_test_render from django.template import Template -if not hasattr(Template, '_render'): # Django < 1.2 +if not hasattr(Template, '_render'): # Django < 1.2 if Template.render != instrumented_test_render: Template.original_render = Template.render Template.render = instrumented_test_render @@ -31,6 +31,8 @@ else: # MONSTER monkey-patch old_template_init = Template.__init__ + + def new_template_init(self, template_string, origin=None, name='<Unknown Template>'): old_template_init(self, template_string, origin, name) self.origin = origin @@ -44,18 +46,18 @@ class TemplateDebugPanel(DebugPanel): name = 'Template' template = 'debug_toolbar/panels/templates.html' has_content = True - + def __init__(self, *args, **kwargs): super(TemplateDebugPanel, self).__init__(*args, **kwargs) self.templates = [] template_rendered.connect(self._store_template_info) - + def _store_template_info(self, sender, **kwargs): t = kwargs['template'] if t.name and t.name.startswith('debug_toolbar/'): return # skip templates that we are generating through the debug toolbar. context_data = kwargs['context'] - + context_list = [] for context_layer in context_data.dicts: temp_layer = {} @@ -95,20 +97,20 @@ class TemplateDebugPanel(DebugPanel): pass kwargs['context'] = context_list self.templates.append(kwargs) - + def nav_title(self): return _('Templates') - + def title(self): num_templates = len(self.templates) return _('Templates (%(num_templates)s rendered)') % {'num_templates': num_templates} - + def url(self): return '' - + def process_request(self, request): self.request = request - + def process_response(self, request, response): context_processors = dict( [ @@ -133,7 +135,7 @@ class TemplateDebugPanel(DebugPanel): context_list = template_data.get('context', []) info['context'] = '\n'.join(context_list) template_context.append(info) - + self.record_stats({ 'templates': template_context, 'template_dirs': [normpath(x) for x in settings.TEMPLATE_DIRS], diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index 943dd8a..7428e83 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -1,7 +1,7 @@ try: import resource except ImportError: - pass # Will fail on Win32 systems + pass # Will fail on Win32 systems import time from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ @@ -14,7 +14,7 @@ class TimerDebugPanel(DebugPanel): """ name = 'Timer' template = 'debug_toolbar/panels/timer.html' - try: # if resource module not available, don't show content panel + try: # if resource module not available, don't show content panel resource except NameError: has_content = False @@ -92,5 +92,5 @@ class TimerDebugPanel(DebugPanel): ) context = self.context.copy() - context.update({'rows': rows,}) + context.update({'rows': rows}) return render_to_string(self.template, context) diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py index 8ac0e82..3d4303d 100644 --- a/debug_toolbar/panels/version.py +++ b/debug_toolbar/panels/version.py @@ -14,19 +14,19 @@ class VersionDebugPanel(DebugPanel): name = 'Version' template = 'debug_toolbar/panels/versions.html' has_content = True - + def nav_title(self): return _('Versions') - + def nav_subtitle(self): return 'Django %s' % django.get_version() - + def url(self): return '' - + def title(self): return _('Versions') - + def process_response(self, request, response): versions = {} versions['Python'] = '%d.%d.%d' % sys.version_info[:3] @@ -49,7 +49,7 @@ class VersionDebugPanel(DebugPanel): if isinstance(version, (list, tuple)): version = '.'.join(str(o) for o in version) versions[name] = version - + self.record_stats({ 'versions': versions, 'paths': sys.path, diff --git a/debug_toolbar/templatetags/debug_toolbar_utils.py b/debug_toolbar/templatetags/debug_toolbar_utils.py index 6b204eb..c057312 100644 --- a/debug_toolbar/templatetags/debug_toolbar_utils.py +++ b/debug_toolbar/templatetags/debug_toolbar_utils.py @@ -4,8 +4,9 @@ from django.utils.numberformat import format register = template.Library() + @register.filter def dotted_number(number): number = float(number) return format(number, '.', 6) - + diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index cf7a243..a69c314 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -1,15 +1,17 @@ """ The main DebugToolbar class that loads and renders the Toolbar. """ -import os.path, os +import os +import os.path from django.conf import settings from django.template.loader import render_to_string from django.utils.datastructures import SortedDict from django.utils.safestring import mark_safe + class DebugToolbar(object): - + def __init__(self, request): self.request = request self._panels = SortedDict() @@ -21,7 +23,7 @@ class DebugToolbar(object): # Check if settings has a DEBUG_TOOLBAR_CONFIG and updated config self.config.update(getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {})) self.template_context = { - 'BASE_URL': base_url, # for backwards compatibility + 'BASE_URL': base_url, # for backwards compatibility 'DEBUG_TOOLBAR_MEDIA_URL': self.config.get('MEDIA_URL'), } # Override this tuple by copying to settings.py as `DEBUG_TOOLBAR_PANELS` @@ -39,31 +41,31 @@ class DebugToolbar(object): ) self.load_panels() self.stats = {} - + def _get_panels(self): return self._panels.values() panels = property(_get_panels) - + def get_panel(self, cls): return self._panels[cls] - + def load_panels(self): """ Populate debug panels """ from django.conf import settings from django.core import exceptions - + # Check if settings has a DEBUG_TOOLBAR_PANELS, otherwise use default if hasattr(settings, 'DEBUG_TOOLBAR_PANELS'): self.default_panels = settings.DEBUG_TOOLBAR_PANELS - + for panel_path in self.default_panels: try: dot = panel_path.rindex('.') except ValueError: raise exceptions.ImproperlyConfigured, '%s isn\'t a debug panel module' % panel_path - panel_module, panel_classname = panel_path[:dot], panel_path[dot+1:] + panel_module, panel_classname = panel_path[:dot], panel_path[(dot + 1):] try: mod = __import__(panel_module, {}, {}, ['']) except ImportError, e: @@ -72,25 +74,25 @@ class DebugToolbar(object): panel_class = getattr(mod, panel_classname) except AttributeError: raise exceptions.ImproperlyConfigured, 'Toolbar Panel module "%s" does not define a "%s" class' % (panel_module, panel_classname) - + try: panel_instance = panel_class(context=self.template_context) except: - raise # Bubble up problem loading panel - + raise # Bubble up problem loading panel + self._panels[panel_class] = panel_instance - + def render_toolbar(self): """ Renders the overall Toolbar with panels inside. """ media_path = os.path.join(os.path.dirname(__file__), os.pardir, 'media', 'debug_toolbar') - + context = self.template_context.copy() context.update({ 'panels': self.panels, 'js': mark_safe(open(os.path.join(media_path, 'js', 'toolbar.min.js'), 'r').read()), 'css': mark_safe(open(os.path.join(media_path, 'css', 'toolbar.min.css'), 'r').read()), }) - + return render_to_string('debug_toolbar/base.html', context) diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py index 77491e3..986b78e 100644 --- a/debug_toolbar/urls.py +++ b/debug_toolbar/urls.py @@ -1,11 +1,10 @@ """ -URLpatterns for the debug toolbar. +URLpatterns for the debug toolbar. These should not be loaded explicitly; the debug toolbar middleware will patch this into the urlconf for the request. """ from django.conf.urls.defaults import * -from django.conf import settings _PREFIX = '__debug__' diff --git a/debug_toolbar/utils/__init__.py b/debug_toolbar/utils/__init__.py index 45dfc6f..01f817a 100644 --- a/debug_toolbar/utils/__init__.py +++ b/debug_toolbar/utils/__init__.py @@ -11,12 +11,14 @@ from django.views.debug import linebreak_iter django_path = os.path.realpath(os.path.dirname(django.__file__)) socketserver_path = os.path.realpath(os.path.dirname(SocketServer.__file__)) + def ms_from_timedelta(td): """ Given a timedelta object, returns a float representing milliseconds """ return (td.seconds * 1000) + (td.microseconds / 1000.0) + def tidy_stacktrace(stack): """ Clean up stacktrace and remove all entries that: @@ -45,6 +47,7 @@ def tidy_stacktrace(stack): trace.append((path, line_no, func_name, text)) return trace + def get_template_info(source, context_lines=3): line = 0 upto = 0 @@ -79,6 +82,7 @@ def get_template_info(source, context_lines=3): 'context': context, } + def get_name_from_obj(obj): if hasattr(obj, '__name__'): name = obj.__name__ @@ -93,6 +97,7 @@ def get_name_from_obj(obj): return name + def getframeinfo(frame, context=1): """ Get information about a frame or traceback object. @@ -116,7 +121,7 @@ def getframeinfo(frame, context=1): filename = inspect.getsourcefile(frame) or inspect.getfile(frame) if context > 0: - start = lineno - 1 - context//2 + start = lineno - 1 - context // 2 try: lines, lnum = inspect.findsource(frame) except (IOError, IndexError): @@ -124,7 +129,7 @@ def getframeinfo(frame, context=1): else: start = max(start, 1) start = max(0, min(start, len(lines) - context)) - lines = lines[start:start+context] + lines = lines[start:(start + context)] index = lineno - 1 - start else: lines = index = None @@ -134,6 +139,7 @@ def getframeinfo(frame, context=1): else: return (filename, lineno, frame.f_code.co_name, lines, index) + def get_stack(context=1): """ Get a list of records for a frame and all higher (calling) frames. @@ -148,4 +154,4 @@ def get_stack(context=1): while frame: framelist.append((frame,) + getframeinfo(frame, context)) frame = frame.f_back - return framelist
\ No newline at end of file + return framelist diff --git a/debug_toolbar/utils/compat/db.py b/debug_toolbar/utils/compat/db.py index 4273d9e..6ff09ec 100644 --- a/debug_toolbar/utils/compat/db.py +++ b/debug_toolbar/utils/compat/db.py @@ -10,4 +10,4 @@ except ImportError: 'default': { 'ENGINE': settings.DATABASE_ENGINE, } - }
\ No newline at end of file + } diff --git a/debug_toolbar/utils/sqlparse/engine/filter.py b/debug_toolbar/utils/sqlparse/engine/filter.py index c1c0d6a..a31c5de 100644 --- a/debug_toolbar/utils/sqlparse/engine/filter.py +++ b/debug_toolbar/utils/sqlparse/engine/filter.py @@ -61,7 +61,7 @@ class StatementFilter(TokenFilter): if unified == 'END': # Should this respect a preceeding BEGIN? # In CASE ... WHEN ... END this results in a split level -1. - self._begin_depth = max(0, self._begin_depth-1) + self._begin_depth = max(0, self._begin_depth - 1) return -1 if ttype is T.Keyword.DDL and unified.startswith('CREATE'): diff --git a/debug_toolbar/utils/sqlparse/filters.py b/debug_toolbar/utils/sqlparse/filters.py index 2d247e7..897cc90 100644 --- a/debug_toolbar/utils/sqlparse/filters.py +++ b/debug_toolbar/utils/sqlparse/filters.py @@ -146,13 +146,14 @@ class ReindentFilter(Filter): split_words = ('FROM', 'JOIN$', 'AND', 'OR', 'GROUP', 'ORDER', 'UNION', 'VALUES', 'SET', 'BETWEEN') + def _next_token(i): t = tlist.token_next_match(i, T.Keyword, split_words, regex=True) if t and t.value.upper() == 'BETWEEN': - t = _next_token(tlist.token_index(t)+1) + t = _next_token(tlist.token_index(t) + 1) if t and t.value.upper() == 'AND': - t = _next_token(tlist.token_index(t)+1) + t = _next_token(tlist.token_index(t) + 1) return t idx = 0 diff --git a/debug_toolbar/utils/sqlparse/sql.py b/debug_toolbar/utils/sqlparse/sql.py index 55bf804..2f9f538 100644 --- a/debug_toolbar/utils/sqlparse/sql.py +++ b/debug_toolbar/utils/sqlparse/sql.py @@ -146,7 +146,7 @@ class TokenList(Token): def _pprint_tree(self, max_depth=None, depth=0): """Pretty-print the object tree.""" - indent = ' '*(depth*2) + indent = ' ' * (depth * 2) for idx, token in enumerate(self.tokens): if token.is_group(): pre = ' +-' @@ -156,7 +156,7 @@ class TokenList(Token): token._get_repr_name(), token._get_repr_value()) if (token.is_group() and (max_depth is None or depth < max_depth)): - token._pprint_tree(max_depth, depth+1) + token._pprint_tree(max_depth, depth + 1) def flatten(self): """Generator yielding ungrouped tokens. diff --git a/debug_toolbar/utils/tracking/__init__.py b/debug_toolbar/utils/tracking/__init__.py index db8ff18..9c72803 100644 --- a/debug_toolbar/utils/tracking/__init__.py +++ b/debug_toolbar/utils/tracking/__init__.py @@ -2,18 +2,21 @@ import logging import time import types + def post_dispatch(func): def wrapped(callback): register_hook(func, 'after', callback) return callback return wrapped + def pre_dispatch(func): def wrapped(callback): register_hook(func, 'before', callback) return callback return wrapped + def replace_call(func): def inner(callback): def wrapped(*args, **kwargs): @@ -28,6 +31,7 @@ def replace_call(func): return wrapped return inner + def fire_hook(hook, sender, **kwargs): try: for callback in callbacks[hook].get(id(sender), []): @@ -36,6 +40,7 @@ def fire_hook(hook, sender, **kwargs): # Log the exception, dont mess w/ the underlying function logging.exception(e) + def _replace_function(func, wrapped): if isinstance(func, types.FunctionType): if func.__module__ == '__builtin__': @@ -58,6 +63,7 @@ callbacks = { 'after': {}, } + def register_hook(func, hook, callback): """ def myhook(sender, args, kwargs): @@ -81,10 +87,10 @@ def register_hook(func, hook, callback): wrapped.__wrapped__ = actual wrapped.__doc__ = getattr(actual, '__doc__', None) wrapped.__name__ = actual.__name__ - + id_ = id(actual) if id_ not in callbacks[hook]: callbacks[hook][id_] = [] callbacks[hook][id_].append(callback) - _replace_function(func, wrapped)
\ No newline at end of file + _replace_function(func, wrapped) diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py index dd9916b..3fa809a 100644 --- a/debug_toolbar/views.py +++ b/debug_toolbar/views.py @@ -14,12 +14,15 @@ from django.utils.hashcompat import sha_constructor from debug_toolbar.utils.compat.db import connections + class InvalidSQLError(Exception): def __init__(self, value): self.value = value + def __str__(self): return repr(self.value) + def debug_media(request, path): root = getattr(settings, 'DEBUG_TOOLBAR_MEDIA_ROOT', None) if root is None: @@ -27,6 +30,7 @@ def debug_media(request, path): root = os.path.join(parent, 'media', 'debug_toolbar') return django.views.static.serve(request, path, root) + def sql_select(request): """ Returns the output of the SQL SELECT statement. @@ -43,7 +47,7 @@ def sql_select(request): alias = request.GET.get('alias', 'default') hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): - return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert + return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connections[alias].cursor() @@ -61,6 +65,7 @@ def sql_select(request): return render_to_response('debug_toolbar/panels/sql_select.html', context) raise InvalidSQLError("Only 'select' queries are allowed.") + def sql_explain(request): """ Returns the output of the SQL EXPLAIN on the given query. @@ -77,7 +82,7 @@ def sql_explain(request): alias = request.GET.get('alias', 'default') hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): - return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert + return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connections[alias].cursor() @@ -106,6 +111,7 @@ def sql_explain(request): return render_to_response('debug_toolbar/panels/sql_explain.html', context) raise InvalidSQLError("Only 'select' queries are allowed.") + def sql_profile(request): """ Returns the output of running the SQL and getting the profiling statistics. @@ -122,7 +128,7 @@ def sql_profile(request): alias = request.GET.get('alias', 'default') hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): - return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert + return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connections[alias].cursor() @@ -130,9 +136,9 @@ def sql_profile(request): headers = None result_error = None try: - cursor.execute("SET PROFILING=1") # Enable profiling - cursor.execute(sql, params) # Execute SELECT - cursor.execute("SET PROFILING=0") # Disable profiling + cursor.execute("SET PROFILING=1") # Enable profiling + cursor.execute(sql, params) # Execute SELECT + cursor.execute("SET PROFILING=0") # Disable profiling # The Query ID should always be 1 here but I'll subselect to get the last one just in case... cursor.execute("SELECT * FROM information_schema.profiling WHERE query_id=(SELECT query_id FROM information_schema.profiling ORDER BY query_id DESC LIMIT 1)") headers = [d[0] for d in cursor.description] @@ -151,6 +157,7 @@ def sql_profile(request): return render_to_response('debug_toolbar/panels/sql_profile.html', context) raise InvalidSQLError("Only 'select' queries are allowed.") + def template_source(request): """ Return the source of a template, syntax-highlighted by Pygments if @@ -164,7 +171,7 @@ def template_source(request): if template_name is None: return HttpResponseBadRequest('"template" key is required') - try: # Django 1.2 ... + try: # Django 1.2 ... from django.template.loader import find_template_loader, make_origin loaders = [] for loader_name in settings.TEMPLATE_LOADERS: @@ -178,7 +185,7 @@ def template_source(request): break except TemplateDoesNotExist: source = "Template Does Not Exist: %s" % (template_name,) - except (ImportError, AttributeError): # Django 1.1 ... + except (ImportError, AttributeError): # Django 1.1 ... from django.template.loader import find_template_source source, origin = find_template_source(template_name) diff --git a/runtests.py b/runtests.py index ec71a57..3432f8b 100644 --- a/runtests.py +++ b/runtests.py @@ -7,7 +7,7 @@ from django.conf import settings, global_settings if not settings.configured: settings.configure( - DATABASES = { + DATABASES={ 'default': { 'ENGINE': 'django.db.backends.sqlite3', } @@ -18,12 +18,12 @@ if not settings.configured: 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', - + 'debug_toolbar', - + 'tests', ], - MIDDLEWARE_CLASSES = global_settings.MIDDLEWARE_CLASSES + ( + MIDDLEWARE_CLASSES=global_settings.MIDDLEWARE_CLASSES + ( 'debug_toolbar.middleware.DebugToolbarMiddleware', ), ROOT_URLCONF='', @@ -33,11 +33,12 @@ if not settings.configured: from django.test.simple import DjangoTestSuiteRunner + def runtests(*test_args, **kwargs): if 'south' in settings.INSTALLED_APPS: from south.management.commands import patch_for_test_db_setup patch_for_test_db_setup() - + if not test_args: test_args = ['tests'] parent = dirname(abspath(__file__)) @@ -49,7 +50,7 @@ def runtests(*test_args, **kwargs): if __name__ == '__main__': parser = OptionParser() parser.add_option('--failfast', action='store_true', default=False, dest='failfast') - + (options, args) = parser.parse_args() - + runtests(failfast=options.failfast, *args) |
