From 25e53acf47d874eba62daa80758013bbe9fc5264 Mon Sep 17 00:00:00 2001 From: Bohuslav Kabrda Date: Fri, 22 Mar 2013 15:59:53 +0100 Subject: [PATCH] First bunch of fixes for Python 3 compatibility. Still supports Python 2.6 --- debug_toolbar/__init__.py | 2 +- debug_toolbar/middleware.py | 15 +++- debug_toolbar/panels/sql.py | 1 - debug_toolbar/toolbar/loader.py | 2 +- debug_toolbar/utils/__init__.py | 5 +- debug_toolbar/utils/sqlparse/lexer.py | 2 +- debug_toolbar/utils/sqlparse/sql.py | 5 +- debug_toolbar/utils/tracking/db.py | 5 +- tests/tests.py | 102 ++++++++++++++------------ 9 files changed, 79 insertions(+), 60 deletions(-) diff --git a/debug_toolbar/__init__.py b/debug_toolbar/__init__.py index 48da4a621..feb6925a2 100644 --- a/debug_toolbar/__init__.py +++ b/debug_toolbar/__init__.py @@ -3,5 +3,5 @@ try: VERSION = __import__('pkg_resources') \ .get_distribution('django-debug-toolbar').version -except Exception, e: +except Exception as e: VERSION = 'unknown' diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 2c36a19f3..583fb24b3 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -2,12 +2,18 @@ Debug Toolbar middleware """ import imp -import thread - +try: # python 3 compat + import thread +except ImportError: + import threading as thread +import sys from django.conf import settings from django.http import HttpResponseRedirect from django.shortcuts import render_to_response -from django.utils.encoding import smart_unicode +try: # python 3 compat + from django.utils.encoding import smart_unicode +except ImportError: + from django.utils.encoding import smart_text as smart_unicode from django.utils.importlib import import_module import debug_toolbar.urls @@ -76,7 +82,8 @@ def process_request(self, request): __traceback_hide__ = True if self.show_toolbar(request): urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF) - if isinstance(urlconf, basestring): + # the below condition is for python 3 compat + if isinstance(urlconf, basestring if sys.version_info[0] < 3 else str): urlconf = import_module(getattr(request, 'urlconf', settings.ROOT_URLCONF)) if urlconf not in self._urlconfs: diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index a49288863..dbc058e53 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -25,7 +25,6 @@ def cursor(func, self): return CursorWrapper(result, self, logger=logger) - def get_isolation_level_display(engine, level): if engine == 'psycopg2': import psycopg2.extensions diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index 570111848..d5e21624e 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -93,7 +93,7 @@ def load_panel_classes(): panel_module, panel_classname = panel_path[:dot], panel_path[dot + 1:] try: mod = import_module(panel_module) - except ImportError, e: + except ImportError as e: raise ImproperlyConfigured( 'Error importing debug panel %s: "%s"' % (panel_module, e)) diff --git a/debug_toolbar/utils/__init__.py b/debug_toolbar/utils/__init__.py index 2d2ff101f..a437101d6 100644 --- a/debug_toolbar/utils/__init__.py +++ b/debug_toolbar/utils/__init__.py @@ -1,7 +1,10 @@ import inspect import os.path import django -import SocketServer +try: # python 3 compat + import SocketServer +except ImportError: + import socketserver as SocketServer import sys from django.conf import settings diff --git a/debug_toolbar/utils/sqlparse/lexer.py b/debug_toolbar/utils/sqlparse/lexer.py index ae3fc2e95..b3e37433e 100644 --- a/debug_toolbar/utils/sqlparse/lexer.py +++ b/debug_toolbar/utils/sqlparse/lexer.py @@ -79,7 +79,7 @@ def _process_state(cls, unprocessed, processed, state): try: rex = re.compile(tdef[0], rflags).match - except Exception, err: + except Exception as err: raise ValueError(("uncompilable regex %r in state" " %r of %r: %s" % (tdef[0], state, cls, err))) diff --git a/debug_toolbar/utils/sqlparse/sql.py b/debug_toolbar/utils/sqlparse/sql.py index 2f9f538a6..c3b6e29e4 100644 --- a/debug_toolbar/utils/sqlparse/sql.py +++ b/debug_toolbar/utils/sqlparse/sql.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """This module contains classes representing syntactical elements of SQL.""" +from __future__ import print_function import re @@ -152,9 +153,9 @@ def _pprint_tree(self, max_depth=None, depth=0): pre = ' +-' else: pre = ' | ' - print '%s%s%d %s \'%s\'' % (indent, pre, idx, + print('%s%s%d %s \'%s\'' % (indent, pre, idx, token._get_repr_name(), - token._get_repr_value()) + token._get_repr_value())) if (token.is_group() and (max_depth is None or depth < max_depth)): token._pprint_tree(max_depth, depth + 1) diff --git a/debug_toolbar/utils/tracking/db.py b/debug_toolbar/utils/tracking/db.py index 0ff33591b..854c0d0a1 100644 --- a/debug_toolbar/utils/tracking/db.py +++ b/debug_toolbar/utils/tracking/db.py @@ -5,7 +5,10 @@ from django.conf import settings from django.template import Node -from django.utils.encoding import force_unicode, smart_str +try: # python 3 compat + from django.utils.encoding import force_unicode, smart_str +except ImportError: + from django.utils.encoding import force_text as force_unicode, smart_bytes as smart_str from debug_toolbar.utils import ms_from_timedelta, tidy_stacktrace, \ get_template_info, get_stack diff --git a/tests/tests.py b/tests/tests.py index f76f1ab0d..fe9ec67a0 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,5 +1,9 @@ from __future__ import with_statement -import thread +try: # python 3 compat + import thread +except ImportError: + import threading as thread +import sys from django.conf import settings from django.contrib.auth.models import User @@ -19,6 +23,8 @@ rf = RequestFactory() +if sys.version_info[0] > 2: + basestring = str class Settings(object): """Allows you to define settings that are required for this function to work""" @@ -30,12 +36,12 @@ def __init__(self, **overrides): self._orig = {} def __enter__(self): - for k, v in self.overrides.iteritems(): + for k, v in self.overrides.items(): self._orig[k] = getattr(settings, k, self.NotDefined) setattr(settings, k, v) def __exit__(self, exc_type, exc_value, traceback): - for k, v in self._orig.iteritems(): + for k, v in self._orig.items(): if v is self.NotDefined: delattr(settings, k) else: @@ -62,7 +68,7 @@ class DebugToolbarTestCase(BaseTestCase): def test_middleware(self): with Settings(INTERNAL_IPS=['127.0.0.1'], DEBUG=True): resp = self.client.get('/execute_sql/') - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) def test_show_toolbar_DEBUG(self): request = rf.get('/') @@ -107,7 +113,7 @@ def test_request_urlconf_string(self): self.assertFalse(isinstance(request.urlconf, basestring)) self.assertTrue(hasattr(request.urlconf.urlpatterns[1], '_callback_str')) - self.assertEquals(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') + self.assertEqual(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') def test_request_urlconf_string_per_request(self): request = rf.get('/') @@ -122,7 +128,7 @@ def test_request_urlconf_string_per_request(self): self.assertFalse(isinstance(request.urlconf, basestring)) self.assertTrue(hasattr(request.urlconf.urlpatterns[1], '_callback_str')) - self.assertEquals(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') + self.assertEqual(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') def test_request_urlconf_module(self): request = rf.get('/') @@ -135,7 +141,7 @@ def test_request_urlconf_module(self): self.assertFalse(isinstance(request.urlconf, basestring)) self.assertTrue(hasattr(request.urlconf.urlpatterns[1], '_callback_str')) - self.assertEquals(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') + self.assertEqual(request.urlconf.urlpatterns[-1]._callback_str, 'tests.views.execute_sql') def test_tuple_urlconf(self): request = rf.get('/') @@ -158,27 +164,27 @@ def _resolve_stats(self, path): def test_url_resolving_positional(self): stats = self._resolve_stats('/resolving1/a/b/') - 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'], {}) + self.assertEqual(stats['view_urlname'], 'positional-resolving') # Django >= 1.3 + self.assertEqual(stats['view_func'], 'tests.views.resolving_view') + self.assertEqual(stats['view_args'], ('a', 'b')) + self.assertEqual(stats['view_kwargs'], {}) def test_url_resolving_named(self): stats = self._resolve_stats('/resolving2/a/b/') - self.assertEquals(stats['view_args'], ()) - self.assertEquals(stats['view_kwargs'], {'arg1': 'a', 'arg2': 'b'}) + self.assertEqual(stats['view_args'], ()) + self.assertEqual(stats['view_kwargs'], {'arg1': 'a', 'arg2': 'b'}) def test_url_resolving_mixed(self): stats = self._resolve_stats('/resolving3/a/') - self.assertEquals(stats['view_args'], ('a',)) - self.assertEquals(stats['view_kwargs'], {'arg2': 'default'}) + self.assertEqual(stats['view_args'], ('a',)) + self.assertEqual(stats['view_kwargs'], {'arg2': 'default'}) def test_url_resolving_bad(self): stats = self._resolve_stats('/non-existing-url/') - self.assertEquals(stats['view_urlname'], 'None') - self.assertEquals(stats['view_args'], 'None') - self.assertEquals(stats['view_kwargs'], 'None') - self.assertEquals(stats['view_func'], '') + self.assertEqual(stats['view_urlname'], 'None') + self.assertEqual(stats['view_args'], 'None') + self.assertEqual(stats['view_kwargs'], 'None') + self.assertEqual(stats['view_func'], '') class DebugToolbarNameFromObjectTest(BaseTestCase): @@ -186,30 +192,30 @@ def test_func(self): def x(): return 1 res = get_name_from_obj(x) - self.assertEquals(res, 'tests.tests.x') + self.assertEqual(res, 'tests.tests.x') def test_lambda(self): res = get_name_from_obj(lambda: 1) - self.assertEquals(res, 'tests.tests.') + self.assertEqual(res, 'tests.tests.') def test_class(self): class A: pass res = get_name_from_obj(A) - self.assertEquals(res, 'tests.tests.A') + self.assertEqual(res, 'tests.tests.A') class SQLPanelTestCase(BaseTestCase): def test_recording(self): panel = self.toolbar.get_panel(SQLDebugPanel) - self.assertEquals(len(panel._queries), 0) + self.assertEqual(len(panel._queries), 0) list(User.objects.all()) # ensure query was logged - self.assertEquals(len(panel._queries), 1) + self.assertEqual(len(panel._queries), 1) query = panel._queries[0] - self.assertEquals(query[0], 'default') + self.assertEqual(query[0], 'default') self.assertTrue('sql' in query[1]) self.assertTrue('duration' in query[1]) self.assertTrue('stacktrace' in query[1]) @@ -232,21 +238,21 @@ def test_erroneous_query(self): def test_disable_stacktraces(self): panel = self.toolbar.get_panel(SQLDebugPanel) - self.assertEquals(len(panel._queries), 0) + self.assertEqual(len(panel._queries), 0) with Settings(DEBUG_TOOLBAR_CONFIG={'ENABLE_STACKTRACES': False}): list(User.objects.all()) # ensure query was logged - self.assertEquals(len(panel._queries), 1) + self.assertEqual(len(panel._queries), 1) query = panel._queries[0] - self.assertEquals(query[0], 'default') + self.assertEqual(query[0], 'default') self.assertTrue('sql' in query[1]) self.assertTrue('duration' in query[1]) self.assertTrue('stacktrace' in query[1]) # ensure the stacktrace is empty - self.assertEquals([], query[1]['stacktrace']) + self.assertEqual([], query[1]['stacktrace']) class TemplatePanelTestCase(BaseTestCase): @@ -262,7 +268,7 @@ def test_queryset_hook(self): }) t.render(c) # ensure the query was NOT logged - self.assertEquals(len(sql_panel._queries), 0) + self.assertEqual(len(sql_panel._queries), 0) ctx = template_panel.templates[0]['context'][0] self.assertIn('<>', ctx) self.assertIn('<>', ctx) @@ -290,23 +296,23 @@ def test(**kwargs): foo.update(kwargs) self.assertTrue(hasattr(module_func, '__wrapped__')) - self.assertEquals(len(callbacks['before']), 1) + self.assertEqual(len(callbacks['before']), 1) module_func('hi', foo='bar') self.assertTrue('sender' in foo, foo) # best we can do - self.assertEquals(foo['sender'].__name__, 'module_func') + self.assertEqual(foo['sender'].__name__, 'module_func') self.assertTrue('start' in foo, foo) self.assertTrue(foo['start'] > 0) self.assertTrue('stop' not in foo, foo) self.assertTrue('args' in foo, foo) self.assertTrue(len(foo['args']), 1) - self.assertEquals(foo['args'][0], 'hi') + self.assertEqual(foo['args'][0], 'hi') self.assertTrue('kwargs' in foo, foo) self.assertTrue(len(foo['kwargs']), 1) self.assertTrue('foo' in foo['kwargs']) - self.assertEquals(foo['kwargs']['foo'], 'bar') + self.assertEqual(foo['kwargs']['foo'], 'bar') callbacks['before'] = {} @@ -315,23 +321,23 @@ def test(**kwargs): foo.update(kwargs) self.assertTrue(hasattr(TrackingTestCase.class_func, '__wrapped__')) - self.assertEquals(len(callbacks['before']), 1) + self.assertEqual(len(callbacks['before']), 1) self.class_func('hello', foo='bar') self.assertTrue('sender' in foo, foo) # best we can do - self.assertEquals(foo['sender'].__name__, 'class_func') + self.assertEqual(foo['sender'].__name__, 'class_func') self.assertTrue('start' in foo, foo) self.assertTrue(foo['start'] > 0) self.assertTrue('stop' not in foo, foo) self.assertTrue('args' in foo, foo) self.assertTrue(len(foo['args']), 2) - self.assertEquals(foo['args'][1], 'hello') + self.assertEqual(foo['args'][1], 'hello') self.assertTrue('kwargs' in foo, foo) self.assertTrue(len(foo['kwargs']), 1) self.assertTrue('foo' in foo['kwargs']) - self.assertEquals(foo['kwargs']['foo'], 'bar') + self.assertEqual(foo['kwargs']['foo'], 'bar') callbacks['before'] = {} @@ -340,13 +346,13 @@ def test(**kwargs): foo.update(kwargs) self.assertTrue(hasattr(TrackingTestCase.class_method, '__wrapped__')) - self.assertEquals(len(callbacks['before']), 1) + self.assertEqual(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.assertEqual(foo['sender'].__name__, 'class_method') self.assertTrue('start' in foo, foo) self.assertTrue('stop' not in foo, foo) self.assertTrue('args' in foo, foo) @@ -359,24 +365,24 @@ def test(**kwargs): foo.update(kwargs) self.assertTrue(hasattr(module_func, '__wrapped__')) - self.assertEquals(len(callbacks['after']), 1) + self.assertEqual(len(callbacks['after']), 1) module_func('hi', foo='bar') self.assertTrue('sender' in foo, foo) # best we can do - self.assertEquals(foo['sender'].__name__, 'module_func') + self.assertEqual(foo['sender'].__name__, 'module_func') self.assertTrue('start' in foo, foo) self.assertTrue(foo['start'] > 0) self.assertTrue('stop' in foo, foo) self.assertTrue(foo['stop'] > foo['start']) self.assertTrue('args' in foo, foo) self.assertTrue(len(foo['args']), 1) - self.assertEquals(foo['args'][0], 'hi') + self.assertEqual(foo['args'][0], 'hi') self.assertTrue('kwargs' in foo, foo) self.assertTrue(len(foo['kwargs']), 1) self.assertTrue('foo' in foo['kwargs']) - self.assertEquals(foo['kwargs']['foo'], 'bar') + self.assertEqual(foo['kwargs']['foo'], 'bar') callbacks['after'] = {} @@ -385,21 +391,21 @@ def test(**kwargs): foo.update(kwargs) self.assertTrue(hasattr(TrackingTestCase.class_func, '__wrapped__')) - self.assertEquals(len(callbacks['after']), 1) + self.assertEqual(len(callbacks['after']), 1) self.class_func('hello', foo='bar') self.assertTrue('sender' in foo, foo) # best we can do - self.assertEquals(foo['sender'].__name__, 'class_func') + self.assertEqual(foo['sender'].__name__, 'class_func') self.assertTrue('start' in foo, foo) self.assertTrue(foo['start'] > 0) self.assertTrue('stop' in foo, foo) self.assertTrue(foo['stop'] > foo['start']) self.assertTrue('args' in foo, foo) self.assertTrue(len(foo['args']), 2) - self.assertEquals(foo['args'][1], 'hello') + self.assertEqual(foo['args'][1], 'hello') self.assertTrue('kwargs' in foo, foo) self.assertTrue(len(foo['kwargs']), 1) self.assertTrue('foo' in foo['kwargs']) - self.assertEquals(foo['kwargs']['foo'], 'bar') + self.assertEqual(foo['kwargs']['foo'], 'bar')