Skip to content

Commit 1b2caac

Browse files
committed
Merged graingert/patch-2 to master.
2 parents 25ea0b4 + 9a924cd commit 1b2caac

File tree

29 files changed

+329
-2780
lines changed

29 files changed

+329
-2780
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ env:
66
- DJANGO_VERSION=1.3.7
77
- DJANGO_VERSION=1.4.5
88
- DJANGO_VERSION=1.5.1
9+
matrix:
10+
include:
11+
- python: 3.2
12+
env: DJANGO_VERSION=1.5.1
13+
- python: 3.3
14+
env: DJANGO_VERSION=1.5.1
915
install:
1016
- pip install Django==$DJANGO_VERSION
17+
- python setup.py install
1118
script: python setup.py test

debug_toolbar/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
try:
44
VERSION = __import__('pkg_resources') \
55
.get_distribution('django-debug-toolbar').version
6-
except Exception, e:
6+
except Exception as e:
77
VERSION = 'unknown'
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
from __future__ import print_function
12
from datetime import datetime
23

34
from django.db.backends import util
45
from django.core.management.commands.shell import Command
56

6-
from debug_toolbar.utils import ms_from_timedelta, sqlparse
7+
from debug_toolbar.utils import ms_from_timedelta
8+
import sqlparse
79

810

911
class PrintQueryWrapper(util.CursorDebugWrapper):
@@ -14,8 +16,8 @@ def execute(self, sql, params=()):
1416
finally:
1517
raw_sql = self.db.ops.last_executed_query(self.cursor, sql, params)
1618
execution_time = datetime.now() - starttime
17-
print sqlparse.format(raw_sql, reindent=True),
18-
print ' [%.2fms]' % (ms_from_timedelta(execution_time),)
19-
print
19+
print(sqlparse.format(raw_sql, reindent=True),)
20+
print(' [%.2fms]' % (ms_from_timedelta(execution_time),))
21+
print()
2022

2123
util.CursorDebugWrapper = PrintQueryWrapper

debug_toolbar/middleware.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1+
from __future__ import unicode_literals
12
"""
23
Debug Toolbar middleware
34
"""
45
import imp
5-
import threading
6+
from django.utils.six.moves import _thread
67

78
from django.conf import settings
89
from django.http import HttpResponseRedirect
910
from django.shortcuts import render_to_response
10-
from django.utils.encoding import smart_unicode
11+
from django.utils.encoding import smart_text
1112
from django.utils.importlib import import_module
13+
from django.utils.six import string_types
1214

1315
import debug_toolbar.urls
1416
from debug_toolbar.toolbar.loader import DebugToolbar
1517

1618
_HTML_TYPES = ('text/html', 'application/xhtml+xml')
17-
threading._DummyThread._Thread__stop = lambda x: 1 # Handles python threading module bug - http://bugs.python.org/issue14308
1819

1920

2021
def replace_insensitive(string, target, replacement):
@@ -39,7 +40,7 @@ class DebugToolbarMiddleware(object):
3940

4041
@classmethod
4142
def get_current(cls):
42-
return cls.debug_toolbars.get(threading.currentThread().ident)
43+
return cls.debug_toolbars.get(_thread.get_ident())
4344

4445
def __init__(self):
4546
self._urlconfs = {}
@@ -48,7 +49,7 @@ def __init__(self):
4849
self.show_toolbar = self._show_toolbar # default
4950

5051
# The tag to attach the toolbar to
51-
self.tag = u'</body>'
52+
self.tag = '</body>'
5253

5354
if hasattr(settings, 'DEBUG_TOOLBAR_CONFIG'):
5455
show_toolbar_callback = settings.DEBUG_TOOLBAR_CONFIG.get(
@@ -58,7 +59,7 @@ def __init__(self):
5859

5960
tag = settings.DEBUG_TOOLBAR_CONFIG.get('TAG', None)
6061
if tag:
61-
self.tag = u'</' + tag + u'>'
62+
self.tag = '</' + tag + '>'
6263

6364
def _show_toolbar(self, request):
6465
if getattr(settings, 'TEST', False):
@@ -77,13 +78,13 @@ def process_request(self, request):
7778
__traceback_hide__ = True
7879
if self.show_toolbar(request):
7980
urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF)
80-
if isinstance(urlconf, basestring):
81+
if isinstance(urlconf, string_types):
8182
urlconf = import_module(getattr(request, 'urlconf', settings.ROOT_URLCONF))
8283

8384
if urlconf not in self._urlconfs:
8485
new_urlconf = imp.new_module('urlconf')
8586
new_urlconf.urlpatterns = debug_toolbar.urls.urlpatterns + \
86-
list(urlconf.urlpatterns)
87+
list(urlconf.urlpatterns)
8788

8889
if hasattr(urlconf, 'handler403'):
8990
new_urlconf.handler403 = urlconf.handler403
@@ -99,11 +100,11 @@ def process_request(self, request):
99100
toolbar = DebugToolbar(request)
100101
for panel in toolbar.panels:
101102
panel.process_request(request)
102-
self.__class__.debug_toolbars[threading.currentThread().ident] = toolbar
103+
self.__class__.debug_toolbars[_thread.get_ident()] = toolbar
103104

104105
def process_view(self, request, view_func, view_args, view_kwargs):
105106
__traceback_hide__ = True
106-
toolbar = self.__class__.debug_toolbars.get(threading.currentThread().ident)
107+
toolbar = self.__class__.debug_toolbars.get(_thread.get_ident())
107108
if not toolbar:
108109
return
109110
result = None
@@ -115,7 +116,7 @@ def process_view(self, request, view_func, view_args, view_kwargs):
115116

116117
def process_response(self, request, response):
117118
__traceback_hide__ = True
118-
ident = threading.currentThread().ident
119+
ident = _thread.get_ident()
119120
toolbar = self.__class__.debug_toolbars.get(ident)
120121
if not toolbar or request.is_ajax():
121122
return response
@@ -135,9 +136,9 @@ def process_response(self, request, response):
135136
for panel in toolbar.panels:
136137
panel.process_response(request, response)
137138
response.content = replace_insensitive(
138-
smart_unicode(response.content),
139+
smart_text(response.content),
139140
self.tag,
140-
smart_unicode(toolbar.render_toolbar() + self.tag))
141+
smart_text(toolbar.render_toolbar() + self.tag))
141142
if response.get('Content-Length', None):
142143
response['Content-Length'] = len(response.content)
143144
del self.__class__.debug_toolbars[ident]

debug_toolbar/panels/cache.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from __future__ import unicode_literals
12
import inspect
23
import sys
34
import time
@@ -10,6 +11,7 @@
1011
from django.template import Node
1112
from django.utils.datastructures import SortedDict
1213
from django.utils.translation import ugettext_lazy as _, ungettext
14+
from django.utils.six import iteritems
1315

1416
from debug_toolbar.panels import DebugPanel
1517
from debug_toolbar.utils import (tidy_stacktrace, render_stacktrace,
@@ -59,7 +61,7 @@ def __init__(self, cache):
5961
self.cache = cache
6062

6163
def __repr__(self):
62-
return u"<CacheStatTracker for %s>" % self.cache.__repr__()
64+
return "<CacheStatTracker for %s>" % self.cache.__repr__()
6365

6466
def _get_func_info(self):
6567
frame = sys._getframe(3)
@@ -166,7 +168,7 @@ def _store_call_info(self, sender, name=None, time_taken=0,
166168
else:
167169
self.hits += 1
168170
elif name == 'get_many':
169-
for key, value in return_value.iteritems():
171+
for key, value in iteritems(return_value):
170172
if value is None:
171173
self.misses += 1
172174
else:

debug_toolbar/panels/profiling.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from __future__ import unicode_literals
12
from __future__ import division
23

4+
from django.utils.six import iteritems
35
from django.utils.translation import ugettext_lazy as _
46
from django.utils.safestring import mark_safe
57
from debug_toolbar.panels import DebugPanel
@@ -23,7 +25,7 @@ class DjangoDebugToolbarStats(Stats):
2325

2426
def get_root_func(self):
2527
if self.__root is None:
26-
for func, (cc, nc, tt, ct, callers) in self.stats.iteritems():
28+
for func, (cc, nc, tt, ct, callers) in iteritems(self.stats):
2729
if len(callers) == 0:
2830
self.__root = func
2931
break
@@ -80,7 +82,7 @@ def subfuncs(self):
8082
i = 0
8183
h, s, v = self.hsv
8284
count = len(self.statobj.all_callees[self.func])
83-
for func, stats in self.statobj.all_callees[self.func].iteritems():
85+
for func, stats in iteritems(self.statobj.all_callees[self.func]):
8486
i += 1
8587
h1 = h + (i / count) / (self.depth + 1)
8688
if stats[3] == 0:
@@ -155,12 +157,12 @@ def title(self):
155157
return _('Profiling')
156158

157159
def _unwrap_closure_and_profile(self, func):
158-
if not hasattr(func, 'func_code'):
160+
if not hasattr(func, '__code__'):
159161
return
160162
self.line_profiler.add_function(func)
161-
if func.func_closure:
162-
for cell in func.func_closure:
163-
if hasattr(cell.cell_contents, 'func_code'):
163+
if func.__closure__:
164+
for cell in func.__closure__:
165+
if hasattr(cell.cell_contents, '__code__'):
164166
self._unwrap_closure_and_profile(cell.cell_contents)
165167

166168
def process_view(self, request, view_func, view_args, view_kwargs):

debug_toolbar/panels/request_vars.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.core.urlresolvers import resolve
22
from django.http import Http404
33
from django.utils.translation import ugettext_lazy as _
4+
from django.utils.six import iterkeys
45

56
from debug_toolbar.panels import DebugPanel
67
from debug_toolbar.utils import get_name_from_obj
@@ -53,5 +54,5 @@ def process_response(self, request, response):
5354
if hasattr(self.request, 'session'):
5455
self.record_stats({
5556
'session': [(k, self.request.session.get(k))
56-
for k in self.request.session.iterkeys()]
57+
for k in iterkeys(self.request.session)]
5758
})

debug_toolbar/panels/sql.py

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1+
import re
12
import uuid
2-
from copy import copy
3+
import sqlparse
34

45
from django.db.backends import BaseDatabaseWrapper
6+
from django.utils.html import escape
57
from django.utils.translation import ugettext_lazy as _, ungettext_lazy as __
8+
from django.utils.six import itervalues
69

7-
from debug_toolbar.forms import SQLSelectForm
810
from debug_toolbar.utils.compat.db import connections
911
from debug_toolbar.middleware import DebugToolbarMiddleware
1012
from debug_toolbar.panels import DebugPanel
1113
from debug_toolbar.utils import render_stacktrace
12-
from debug_toolbar.utils.sql import reformat_sql
1314
from debug_toolbar.utils.tracking.db import CursorWrapper
14-
from debug_toolbar.utils.tracking import replace_call
15+
from debug_toolbar.utils.tracking import monkey_patch_call
1516

1617

1718
# Inject our tracking cursor
18-
@replace_call(BaseDatabaseWrapper.cursor)
19+
@monkey_patch_call(BaseDatabaseWrapper, 'cursor')
1920
def cursor(func, self):
2021
result = func(self)
2122

@@ -26,6 +27,8 @@ def cursor(func, self):
2627

2728
return CursorWrapper(result, self, logger=logger)
2829

30+
BaseDatabaseWrapper.cursor = cursor
31+
2932

3033
def get_isolation_level_display(engine, level):
3134
if engine == 'psycopg2':
@@ -77,11 +80,9 @@ def __init__(self, *args, **kwargs):
7780
self._transaction_ids = {}
7881

7982
def get_transaction_id(self, alias):
80-
if alias not in connections:
81-
return
8283
conn = connections[alias].connection
8384
if not conn:
84-
return
85+
return None
8586

8687
engine = conn.__class__.__module__.split('.', 1)[0]
8788
if engine == 'psycopg2':
@@ -137,7 +138,7 @@ def process_response(self, request, response):
137138
if self._queries:
138139
width_ratio_tally = 0
139140
factor = int(256.0 / (len(self._databases) * 2.5))
140-
for n, db in enumerate(self._databases.itervalues()):
141+
for n, db in enumerate(itervalues(self._databases)):
141142
rgb = [0, 0, 0]
142143
color = n % 3
143144
rgb[color] = 256 - n / 3 * factor
@@ -173,9 +174,6 @@ def process_response(self, request, response):
173174
query['iso_level'] = get_isolation_level_display(query['engine'], query['iso_level'])
174175
if 'trans_status' in query:
175176
query['trans_status'] = get_transaction_status_display(query['engine'], query['trans_status'])
176-
177-
query['form'] = SQLSelectForm(auto_id=None, initial=copy(query))
178-
179177
if query['sql']:
180178
query['sql'] = reformat_sql(query['sql'])
181179
query['rgb_color'] = self._databases[alias]['rgb_color']
@@ -199,3 +197,28 @@ def process_response(self, request, response):
199197
'queries': [q for a, q in self._queries],
200198
'sql_time': self._sql_time,
201199
})
200+
201+
202+
class BoldKeywordFilter():
203+
"""sqlparse filter to bold SQL keywords"""
204+
def process(self, stack, stream):
205+
"""Process the token stream"""
206+
for token_type, value in stream:
207+
is_keyword = token_type in sqlparse.tokens.Keyword
208+
if is_keyword:
209+
yield sqlparse.tokens.Text, '<strong>'
210+
yield token_type, escape(value)
211+
if is_keyword:
212+
yield sqlparse.tokens.Text, '</strong>'
213+
214+
215+
def swap_fields(sql):
216+
return re.sub('SELECT</strong> (.*?) <strong>FROM', 'SELECT</strong> <a class="djDebugUncollapsed djDebugToggle" href="#">&bull;&bull;&bull;</a> ' +
217+
'<a class="djDebugCollapsed djDebugToggle" href="#">\g<1></a> <strong>FROM', sql)
218+
219+
220+
def reformat_sql(sql):
221+
stack = sqlparse.engine.FilterStack()
222+
stack.preprocess.append(BoldKeywordFilter()) # add our custom filter
223+
stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings
224+
return swap_fields(''.join(stack.run(sql)))

debug_toolbar/templates/debug_toolbar/panels/cache.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ <h3>{% trans "Commands" %}</h3>
2222
<table>
2323
<thead>
2424
<tr>
25-
{% for name in counts.iterkeys %}
25+
{% for name in counts.keys %}
2626
<th>{{ name }}</th>
2727
{% endfor %}
2828
</tr>
2929
</thead>
3030
<tbody>
3131
<tr>
32-
{% for value in counts.itervalues %}
32+
{% for value in counts.values %}
3333
<td>{{ value }}</td>
3434
{% endfor %}
3535
</tr>

debug_toolbar/templates/debug_toolbar/panels/headers.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
</tr>
88
</thead>
99
<tbody>
10-
{% for key, value in headers.iteritems %}
10+
{% for key, value in headers.items %}
1111
<tr class="{% cycle 'djDebugOdd' 'djDebugEven' %}">
1212
<td>{{ key|escape }}</td>
1313
<td>{{ value|escape }}</td>

debug_toolbar/templates/debug_toolbar/panels/templates.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ <h4>{% blocktrans count templates|length as template_count %}Template{% plural %
3131
<h4>{% blocktrans count context_processors|length as context_processors_count %}Context processor{% plural %}Context processors{% endblocktrans %}</h4>
3232
{% if context_processors %}
3333
<dl>
34-
{% for key, value in context_processors.iteritems %}
34+
{% for key, value in context_processors.items %}
3535
<dt><strong>{{ key|escape }}</strong></dt>
3636
<dd>
3737
<div class="djTemplateShowContextDiv"><a class="djTemplateShowContext"><span class="toggleArrow">&#x25B6;</span> {% trans 'Toggle Context' %}</a></div>

debug_toolbar/templates/debug_toolbar/panels/versions.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
</tr>
88
</thead>
99
<tbody>
10-
{% for package, version in versions.iteritems %}
10+
{% for package, version in versions.items %}
1111
<tr class="{% cycle 'djDebugOdd' 'djDebugEven' %}">
1212
<td>{{ package }}</td>
1313
<td>{{ version }}</td>

0 commit comments

Comments
 (0)