diff options
| -rw-r--r-- | debug_toolbar/models.py | 29 | ||||
| -rw-r--r-- | debug_toolbar/panels/cache.py | 3 | ||||
| -rw-r--r-- | debug_toolbar/panels/signals.py | 13 | ||||
| -rw-r--r-- | debug_toolbar/panels/version.py | 4 | ||||
| -rw-r--r-- | debug_toolbar/toolbar/loader.py | 5 | ||||
| -rw-r--r-- | debug_toolbar/utils/__init__.py | 7 | ||||
| -rw-r--r-- | debug_toolbar/utils/tracking/__init__.py | 6 | ||||
| -rw-r--r-- | setup.py | 3 | ||||
| -rw-r--r-- | tests/tests.py | 110 |
9 files changed, 103 insertions, 77 deletions
diff --git a/debug_toolbar/models.py b/debug_toolbar/models.py index 9ea9e86..7ef8601 100644 --- a/debug_toolbar/models.py +++ b/debug_toolbar/models.py @@ -1,3 +1,30 @@ +from django.conf import settings +from django.utils.importlib import import_module + from debug_toolbar.toolbar.loader import load_panel_classes +from debug_toolbar.middleware import DebugToolbarMiddleware + +loaded = False + + +def is_toolbar(cls): + return (issubclass(cls, DebugToolbarMiddleware) or + DebugToolbarMiddleware in getattr(cls, '__bases__', ())) + + +def iter_toolbar_middlewares(): + global loaded + for middleware_path in settings.MIDDLEWARE_CLASSES: + try: + mod_path, cls_name = middleware_path.rsplit('.', 1) + mod = import_module(mod_path) + middleware_cls = getattr(mod, cls_name) + except (AttributeError, ImportError, ValueError): + continue + if is_toolbar(middleware_cls) and not loaded: + # we have a hit! + loaded = True + yield middleware_cls -load_panel_classes() +for middleware_cls in iter_toolbar_middlewares(): + load_panel_classes() diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py index 585521c..e25f08b 100644 --- a/debug_toolbar/panels/cache.py +++ b/debug_toolbar/panels/cache.py @@ -58,6 +58,9 @@ class CacheStatTracker(BaseCache): def __init__(self, cache): self.cache = cache + def __repr__(self): + return u"<CacheStatTracker for %s>" % self.cache.__repr__() + def _get_func_info(self): frame = sys._getframe(3) info = inspect.getframeinfo(frame) diff --git a/debug_toolbar/panels/signals.py b/debug_toolbar/panels/signals.py index 2d38b1f..984b064 100644 --- a/debug_toolbar/panels/signals.py +++ b/debug_toolbar/panels/signals.py @@ -1,5 +1,3 @@ -import sys - from django.conf import settings from django.core.signals import (request_started, request_finished, got_request_exception) @@ -7,6 +5,8 @@ from django.db.models.signals import (class_prepared, pre_init, post_init, pre_save, post_save, pre_delete, post_delete, post_syncdb) from django.dispatch.dispatcher import WEAKREF_TYPES from django.utils.translation import ugettext_lazy as _, ungettext +from django.utils.importlib import import_module + try: from django.db.backends.signals import connection_created @@ -60,6 +60,7 @@ class SignalDebugPanel(DebugPanel): def url(self): return '' + @property def signals(self): signals = self.SIGNALS.copy() if hasattr(settings, 'DEBUG_TOOLBAR_CONFIG'): @@ -67,12 +68,10 @@ class SignalDebugPanel(DebugPanel): else: extra_signals = [] for signal in extra_signals: - parts = signal.split('.') - path = '.'.join(parts[:-1]) - __import__(path) - signals[parts[-1]] = getattr(sys.modules[path], parts[-1]) + mod_path, signal_name = signal.rsplit('.', 1) + signals_mod = import_module(mod_path) + signals[signal_name] = getattr(signals_mod, signal_name) return signals - signals = property(signals) def process_response(self, request, response): signals = [] diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py index 7ed9716..ccb0ad8 100644 --- a/debug_toolbar/panels/version.py +++ b/debug_toolbar/panels/version.py @@ -4,6 +4,7 @@ import django from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django.utils.datastructures import SortedDict +from django.utils.importlib import import_module from debug_toolbar.panels import DebugPanel @@ -32,8 +33,7 @@ class VersionDebugPanel(DebugPanel): versions = [('Python', '%d.%d.%d' % sys.version_info[:3])] for app in list(settings.INSTALLED_APPS) + ['django']: name = app.split('.')[-1].replace('_', ' ').capitalize() - __import__(app) - app = sys.modules[app] + app = import_module(app) if hasattr(app, 'get_version'): get_version = app.get_version if callable(get_version): diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index 4d09a27..02a558d 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -7,6 +7,7 @@ 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.importlib import import_module from django.utils.safestring import mark_safe @@ -91,10 +92,10 @@ def load_panel_classes(): dot = panel_path.rindex('.') except ValueError: raise ImproperlyConfigured( - '%s isn\'t a debug panel module' % panel_path) + "%s isn't a debug panel module" % panel_path) panel_module, panel_classname = panel_path[:dot], panel_path[dot + 1:] try: - mod = __import__(panel_module, {}, {}, ['']) + mod = import_module(panel_module) except ImportError, e: raise ImproperlyConfigured( 'Error importing debug panel %s: "%s"' % diff --git a/debug_toolbar/utils/__init__.py b/debug_toolbar/utils/__init__.py index f7a3de0..bfb485c 100644 --- a/debug_toolbar/utils/__init__.py +++ b/debug_toolbar/utils/__init__.py @@ -21,6 +21,9 @@ def ms_from_timedelta(td): return (td.seconds * 1000) + (td.microseconds / 1000.0) +hide_django_sql = getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {}).get('HIDE_DJANGO_SQL', True) + + def tidy_stacktrace(stack): """ Clean up stacktrace and remove all entries that: @@ -37,8 +40,7 @@ def tidy_stacktrace(stack): # inspection. if '__traceback_hide__' in frame.f_locals: continue - if getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {}).get('HIDE_DJANGO_SQL', True) \ - and django_path in s_path and not 'django/contrib' in s_path: + if hide_django_sql and django_path in s_path and not 'django/contrib' in s_path: continue if socketserver_path in s_path: continue @@ -62,7 +64,6 @@ def render_stacktrace(trace): return mark_safe('\n'.join(stacktrace)) - def get_template_info(source, context_lines=3): line = 0 upto = 0 diff --git a/debug_toolbar/utils/tracking/__init__.py b/debug_toolbar/utils/tracking/__init__.py index 9c72803..766c248 100644 --- a/debug_toolbar/utils/tracking/__init__.py +++ b/debug_toolbar/utils/tracking/__init__.py @@ -1,6 +1,7 @@ import logging import time import types +from django.utils.importlib import import_module def post_dispatch(func): @@ -47,11 +48,10 @@ def _replace_function(func, wrapped): # oh shit __builtins__[func] = wrapped else: - module = __import__(func.__module__, {}, {}, [func.__module__], 0) + module = import_module(func.__module__) setattr(module, func.__name__, wrapped) elif getattr(func, 'im_self', None): - # TODO: classmethods - raise NotImplementedError + setattr(func.im_self, func.__name__, classmethod(wrapped)) elif hasattr(func, 'im_class'): # for unbound methods setattr(func.im_class, func.__name__, wrapped) @@ -13,8 +13,7 @@ setup( license='BSD', packages=find_packages(exclude=('tests', 'example')), tests_require=[ - 'django>=1.1,<1.5', - 'dingus', + 'django>=1.3,<1.5', ], test_suite='runtests.runtests', include_package_data=True, diff --git a/tests/tests.py b/tests/tests.py index 7d6436e..32ea9d9 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,3 +1,11 @@ +import thread + +from django.conf import settings +from django.contrib.auth.models import User +from django.http import HttpResponse +from django.test import TestCase, RequestFactory +from django.template import Template, Context + from debug_toolbar.middleware import DebugToolbarMiddleware from debug_toolbar.panels.sql import SQLDebugPanel from debug_toolbar.panels.request_vars import RequestVarsDebugPanel @@ -6,15 +14,7 @@ from debug_toolbar.toolbar.loader import DebugToolbar from debug_toolbar.utils import get_name_from_obj from debug_toolbar.utils.tracking import pre_dispatch, post_dispatch, callbacks -from django.conf import settings -from django.contrib.auth.models import User -from django.http import HttpResponse -from django.test import TestCase -from django.template import Template, Context -from django import VERSION - -from dingus import Dingus -import thread +rf = RequestFactory() class Settings(object): @@ -38,10 +38,11 @@ class Settings(object): else: setattr(settings, k, v) + class BaseTestCase(TestCase): def setUp(self): - request = Dingus('request') - response = Dingus('response') + request = rf.get('/') + response = HttpResponse() toolbar = DebugToolbar(request) DebugToolbarMiddleware.debug_toolbars[thread.get_ident()] = toolbar @@ -51,6 +52,7 @@ class BaseTestCase(TestCase): self.toolbar = toolbar self.toolbar.stats = {} + class DebugToolbarTestCase(BaseTestCase): urls = 'tests.urls' @@ -60,9 +62,7 @@ class DebugToolbarTestCase(BaseTestCase): self.assertEquals(resp.status_code, 200) def test_show_toolbar_DEBUG(self): - request = self.request - - request.META = {'REMOTE_ADDR': '127.0.0.1'} + request = rf.get('/') middleware = DebugToolbarMiddleware() with Settings(INTERNAL_IPS=['127.0.0.1'], DEBUG=True): @@ -72,9 +72,7 @@ class DebugToolbarTestCase(BaseTestCase): self.assertFalse(middleware._show_toolbar(request)) def test_show_toolbar_TEST(self): - request = self.request - - request.META = {'REMOTE_ADDR': '127.0.0.1'} + request = rf.get('/') middleware = DebugToolbarMiddleware() with Settings(INTERNAL_IPS=['127.0.0.1'], TEST=True, DEBUG=True): @@ -84,7 +82,7 @@ class DebugToolbarTestCase(BaseTestCase): self.assertTrue(middleware._show_toolbar(request)) def test_show_toolbar_INTERNAL_IPS(self): - request = self.request + request = rf.get('/') request.META = {'REMOTE_ADDR': '127.0.0.1'} middleware = DebugToolbarMiddleware() @@ -96,10 +94,8 @@ class DebugToolbarTestCase(BaseTestCase): self.assertFalse(middleware._show_toolbar(request)) def test_request_urlconf_string(self): - request = self.request - + request = rf.get('/') request.urlconf = 'tests.urls' - request.META = {'REMOTE_ADDR': '127.0.0.1'} middleware = DebugToolbarMiddleware() with Settings(INTERNAL_IPS=['127.0.0.1'], DEBUG=True): @@ -113,10 +109,8 @@ class DebugToolbarTestCase(BaseTestCase): self.assertEquals(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') def test_request_urlconf_string_per_request(self): - request = self.request - + request = rf.get('/') request.urlconf = 'debug_toolbar.urls' - request.META = {'REMOTE_ADDR': '127.0.0.1'} middleware = DebugToolbarMiddleware() with Settings(INTERNAL_IPS=['127.0.0.1'], DEBUG=True): @@ -132,10 +126,8 @@ class DebugToolbarTestCase(BaseTestCase): self.assertEquals(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') def test_request_urlconf_module(self): - request = self.request - + request = rf.get('/') request.urlconf = __import__('tests.urls').urls - request.META = {'REMOTE_ADDR': '127.0.0.1'} middleware = DebugToolbarMiddleware() with Settings(INTERNAL_IPS=['127.0.0.1'], DEBUG=True): @@ -149,11 +141,10 @@ class DebugToolbarTestCase(BaseTestCase): self.assertEquals(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') def test_tuple_urlconf(self): - request = self.request + request = rf.get('/') urls = __import__('tests.urls').urls urls.urlpatterns = tuple(urls.urlpatterns) request.urlconf = urls - request.META = {'REMOTE_ADDR': '127.0.0.1'} middleware = DebugToolbarMiddleware() with Settings(INTERNAL_IPS=['127.0.0.1'], DEBUG=True): middleware.process_request(request) @@ -170,10 +161,7 @@ class DebugToolbarTestCase(BaseTestCase): def test_url_resolving_positional(self): stats = self._resolve_stats('/resolving1/a/b/') - if tuple(VERSION[:2]) >= (1, 3): - self.assertEquals(stats['view_urlname'], 'positional-resolving') # Django >= 1.3 - else: - self.assertEquals(stats['view_urlname'], '<unavailable>') # Django < 1.3 + self.assertEquals(stats['view_urlname'], 'positional-resolving') # Django >= 1.3 self.assertEquals(stats['view_func'], 'tests.views.resolving_view') self.assertEquals(stats['view_args'], ('a', 'b')) self.assertEquals(stats['view_kwargs'], {}) @@ -204,14 +192,16 @@ class DebugToolbarNameFromObjectTest(BaseTestCase): self.assertEquals(res, 'tests.tests.x') def test_lambda(self): - res = get_name_from_obj(lambda:1) + res = get_name_from_obj(lambda: 1) self.assertEquals(res, 'tests.tests.<lambda>') def test_class(self): - class A: pass + class A: + pass res = get_name_from_obj(A) self.assertEquals(res, 'tests.tests.A') + class SQLPanelTestCase(BaseTestCase): def test_recording(self): panel = self.toolbar.get_panel(SQLDebugPanel) @@ -234,7 +224,7 @@ class SQLPanelTestCase(BaseTestCase): panel = self.toolbar.get_panel(SQLDebugPanel) self.assertEquals(len(panel._queries), 0) - with Settings(DEBUG_TOOLBAR_CONFIG={ 'ENABLE_STACKTRACES' : False }): + with Settings(DEBUG_TOOLBAR_CONFIG={'ENABLE_STACKTRACES': False}): list(User.objects.all()) # ensure query was logged @@ -254,19 +244,25 @@ class TemplatePanelTestCase(BaseTestCase): template_panel = self.toolbar.get_panel(TemplateDebugPanel) sql_panel = self.toolbar.get_panel(SQLDebugPanel) t = Template("No context variables here!") - c = Context({ 'queryset' : User.objects.all(), 'deep_queryset' : { 'queryset' : User.objects.all() } }) + c = Context({ + 'queryset': User.objects.all(), + 'deep_queryset': { + 'queryset': User.objects.all(), + } + }) t.render(c) # ensure the query was NOT logged self.assertEquals(len(sql_panel._queries), 0) ctx = template_panel.templates[0]['context'][0] - ctx = eval(ctx) # convert back to Python - self.assertEquals(ctx['queryset'], '<<queryset of auth.User>>') - self.assertEquals(ctx['deep_queryset'], '<<triggers database query>>') + self.assertIn('<<queryset of auth.User>>', ctx) + self.assertIn('<<triggers database query>>', ctx) + def module_func(*args, **kwargs): """Used by dispatch tests""" return 'blah' + class TrackingTestCase(BaseTestCase): @classmethod def class_method(cls, *args, **kwargs): @@ -327,23 +323,23 @@ class TrackingTestCase(BaseTestCase): self.assertTrue('foo' in foo['kwargs']) self.assertEquals(foo['kwargs']['foo'], 'bar') - # callbacks['before'] = {} - # - # @pre_dispatch(TrackingTestCase.class_method) - # def test(**kwargs): - # foo.update(kwargs) - # - # self.assertTrue(hasattr(TrackingTestCase.class_method, '__wrapped__')) - # self.assertEquals(len(callbacks['before']), 1) - # - # TrackingTestCase.class_method() - # - # self.assertTrue('sender' in foo, foo) - # # best we can do - # self.assertEquals(foo['sender'].__name__, 'class_method') - # self.assertTrue('start' in foo, foo) - # self.assertTrue('stop' not in foo, foo) - # self.assertTrue('args' in foo, foo) + callbacks['before'] = {} + + @pre_dispatch(TrackingTestCase.class_method) + def test(**kwargs): + foo.update(kwargs) + + self.assertTrue(hasattr(TrackingTestCase.class_method, '__wrapped__')) + self.assertEquals(len(callbacks['before']), 1) + + TrackingTestCase.class_method() + + self.assertTrue('sender' in foo, foo) + # best we can do + self.assertEquals(foo['sender'].__name__, 'class_method') + self.assertTrue('start' in foo, foo) + self.assertTrue('stop' not in foo, foo) + self.assertTrue('args' in foo, foo) def test_post_hook(self): foo = {} |
