diff --git a/.travis.yml b/.travis.yml index 331c488d..b7c9514a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,10 @@ language: python python: - "2.7" - - "3.2" - "3.3" - "3.4" + - "3.5" env: - - DJANGO_VERSION=1.5 - - DJANGO_VERSION=1.6 - - DJANGO_VERSION=1.7 - DJANGO_VERSION=1.8 # command to run tests install: ./install_redis.sh diff --git a/README.rst b/README.rst index 4d55092d..79724006 100644 --- a/README.rst +++ b/README.rst @@ -21,6 +21,11 @@ Docs can be found at http://django-redis-cache.readthedocs.org/en/latest/. Changelog ========= +1.7.0 +----- + +* Drops support for Django < 1.8 and Python 3.2. + 1.5.0 ----- diff --git a/redis_cache/backends/base.py b/redis_cache/backends/base.py index 46d36d43..fb8f9156 100644 --- a/redis_cache/backends/base.py +++ b/redis_cache/backends/base.py @@ -1,4 +1,6 @@ -from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError +from django.core.cache.backends.base import ( + BaseCache, DEFAULT_TIMEOUT, InvalidCacheBackendError, +) from django.core.exceptions import ImproperlyConfigured try: @@ -10,7 +12,6 @@ from redis.connection import DefaultParser -from redis_cache.compat import DEFAULT_TIMEOUT from redis_cache.connection import pool from redis_cache.utils import ( CacheKey, get_servers, parse_connection_kwargs, import_class diff --git a/redis_cache/backends/multiple.py b/redis_cache/backends/multiple.py index 6db0d934..820dea98 100644 --- a/redis_cache/backends/multiple.py +++ b/redis_cache/backends/multiple.py @@ -1,7 +1,8 @@ from collections import defaultdict +from django.core.cache.backends.base import DEFAULT_TIMEOUT + from redis_cache.backends.base import BaseRedisCache -from redis_cache.compat import DEFAULT_TIMEOUT from redis_cache.sharder import HashRing diff --git a/redis_cache/backends/single.py b/redis_cache/backends/single.py index 210c6589..f13aec74 100644 --- a/redis_cache/backends/single.py +++ b/redis_cache/backends/single.py @@ -1,11 +1,11 @@ -from redis_cache.compat import DEFAULT_TIMEOUT - try: import cPickle as pickle except ImportError: import pickle import random +from django.core.cache.backends.base import DEFAULT_TIMEOUT + from redis_cache.backends.base import BaseRedisCache diff --git a/redis_cache/compat.py b/redis_cache/compat.py deleted file mode 100644 index f5ea8bd9..00000000 --- a/redis_cache/compat.py +++ /dev/null @@ -1,44 +0,0 @@ -import sys -import django - - -PY3 = (sys.version_info >= (3,)) - -try: - # Django 1.5+ - from django.utils.encoding import smart_text, smart_bytes -except ImportError: - # older Django, thus definitely Python 2 - from django.utils.encoding import smart_unicode, smart_str - smart_text = smart_unicode - smart_bytes = smart_str - -if PY3: - bytes_type = bytes - from urllib.parse import parse_qs, urlparse -else: - bytes_type = str - from urlparse import parse_qs, urlparse - - -if django.VERSION[:2] >= (1, 6): - from django.core.cache.backends.base import DEFAULT_TIMEOUT as DJANGO_DEFAULT_TIMEOUT - DEFAULT_TIMEOUT = DJANGO_DEFAULT_TIMEOUT -else: - DEFAULT_TIMEOUT = None - - -def python_2_unicode_compatible(klass): - """ - A decorator that defines __unicode__ and __str__ methods under Python 2. - Under Python 3 it does nothing. - - To support Python 2 and 3 with a single code base, define a __str__ method - returning text and apply this decorator to the class. - - Backported from Django 1.5+. - """ - if not PY3: - klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode('utf-8') - return klass diff --git a/redis_cache/serializers.py b/redis_cache/serializers.py index 2454a61e..ac83eafd 100644 --- a/redis_cache/serializers.py +++ b/redis_cache/serializers.py @@ -15,7 +15,7 @@ except ImportError: pass -from redis_cache.compat import smart_bytes, smart_text +from django.utils.encoding import force_bytes, force_text class BaseSerializer(object): @@ -39,7 +39,7 @@ def serialize(self, value): return pickle.dumps(value, self.pickle_version) def deserialize(self, value): - return pickle.loads(smart_bytes(value)) + return pickle.loads(force_bytes(value)) class JSONSerializer(BaseSerializer): @@ -48,10 +48,10 @@ def __init__(self, **kwargs): super(JSONSerializer, self).__init__(**kwargs) def serialize(self, value): - return smart_bytes(json.dumps(value)) + return force_bytes(json.dumps(value)) def deserialize(self, value): - return json.loads(smart_text(value)) + return json.loads(force_text(value)) class MSGPackSerializer(BaseSerializer): diff --git a/redis_cache/sharder.py b/redis_cache/sharder.py index dcfc1fec..ed65224f 100644 --- a/redis_cache/sharder.py +++ b/redis_cache/sharder.py @@ -1,6 +1,6 @@ from bisect import insort, bisect import hashlib -from redis_cache.compat import smart_text +from django.utils.encoding import force_text DIGITS = 8 @@ -17,8 +17,8 @@ def __init__(self, node, i): self._node = node self._i = i key = "{0}:{1}".format( - smart_text(i), - smart_text(self._node), + force_text(i), + force_text(self._node), ) self._position = get_slot(key) @@ -52,5 +52,5 @@ def remove(self, node): del self._nodes[n - i - 1] def get_node(self, key): - i = bisect(self._nodes, get_slot(smart_text(key))) - 1 + i = bisect(self._nodes, get_slot(force_text(key))) - 1 return self._nodes[i]._node diff --git a/redis_cache/utils.py b/redis_cache/utils.py index 6e94c75c..a7ecd720 100644 --- a/redis_cache/utils.py +++ b/redis_cache/utils.py @@ -1,21 +1,12 @@ +import importlib import warnings from django.core.exceptions import ImproperlyConfigured -from redis.connection import SSLConnection - -from redis_cache.compat import ( - smart_text, python_2_unicode_compatible, parse_qs, urlparse -) +from django.utils import six +from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.six.moves.urllib.parse import parse_qs, urlparse -try: - import importlib -except ImportError: - from django.utils import importlib - -try: - basestring -except NameError: - basestring = str +from redis.connection import SSLConnection @python_2_unicode_compatible @@ -30,20 +21,20 @@ def __init__(self, key, versioned_key): def __eq__(self, other): return self._versioned_key == other - def __unicode__(self): - return smart_text(self._versioned_key) + def __str__(self): + return force_text(self._versioned_key) def __hash__(self): return hash(self._versioned_key) - __repr__ = __str__ = __unicode__ + __repr__ = __str__ def get_servers(location): """Returns a list of servers given the server argument passed in from Django. """ - if isinstance(location, basestring): + if isinstance(location, six.string_types): servers = location.split(',') elif hasattr(location, '__iter__'): servers = location diff --git a/requirements-dev.txt b/requirements-dev.txt index 38159a0d..e4a555d7 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,5 @@ hiredis==0.2.0 django-nose==1.4 nose==1.3.6 -unittest2==1.0.1 msgpack-python==0.4.6 pyyaml==3.11 diff --git a/setup.py b/setup.py index 9c1f21ea..2ef8b3d5 100644 --- a/setup.py +++ b/setup.py @@ -11,15 +11,15 @@ install_requires=['redis>=2.10.3'], classifiers=[ "Programming Language :: Python", - "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", "Operating System :: OS Independent", "Topic :: Software Development :: Libraries", "Topic :: Utilities", "Environment :: Web Environment", "Framework :: Django", + "Framework :: Django :: 1.8", ], ) diff --git a/tests/testapp/tests/base_tests.py b/tests/testapp/tests/base_tests.py index 0e9e193b..30b39507 100644 --- a/tests/testapp/tests/base_tests.py +++ b/tests/testapp/tests/base_tests.py @@ -4,14 +4,8 @@ from hashlib import sha1 import os import subprocess -import sys import time -if sys.version_info < (2, 7): - import unittest2 as unittest -else: - import unittest - try: import cPickle as pickle @@ -20,17 +14,13 @@ from django.core.cache import get_cache from django.core.exceptions import ImproperlyConfigured -from django.test import TestCase -try: - from django.test import override_settings -except ImportError: - from django.test.utils import override_settings +from django.test import TestCase, override_settings +from django.utils.encoding import force_bytes import redis from tests.testapp.models import Poll, expensive_calculation from redis_cache.cache import RedisCache, pool -from redis_cache.compat import DEFAULT_TIMEOUT, smart_bytes from redis_cache.utils import get_servers, parse_connection_kwargs @@ -299,7 +289,6 @@ def test_expiration(self): self.assertEqual(self.cache.get("expire2"), "newvalue") self.assertEqual("expire3" in self.cache, False) - @unittest.skipIf(DEFAULT_TIMEOUT is None, "Version of django doesn't support indefinite timeouts.") def test_set_expiration_timeout_None(self): key, value = 'key', 'value' self.cache.set(key, value, timeout=None) @@ -479,7 +468,7 @@ def test_clearing_using_version(self): def test_reinsert_keys(self): self.cache._pickle_version = 0 for i in range(2000): - s = sha1(smart_bytes(i)).hexdigest() + s = sha1(force_bytes(i)).hexdigest() self.cache.set(s, self.cache) self.cache._pickle_version = -1 self.cache.reinsert_keys() @@ -563,7 +552,6 @@ def test_ttl_set_expiry(self): ttl = self.cache.ttl('a') self.assertAlmostEqual(ttl, 10) - @unittest.skipIf(DEFAULT_TIMEOUT is None, "Version of django doesn't support indefinite timeouts.") def test_ttl_no_expiry(self): self.cache.set('a', 'a', timeout=None) ttl = self.cache.ttl('a') diff --git a/tests/testapp/tests/compressor_tests.py b/tests/testapp/tests/compressor_tests.py index 660cf9d1..392e0c92 100644 --- a/tests/testapp/tests/compressor_tests.py +++ b/tests/testapp/tests/compressor_tests.py @@ -1,10 +1,5 @@ # -*- coding: utf-8 -*- -try: - from django.test import override_settings -except ImportError: - from django.test.utils import override_settings -from django.test import TestCase - +from django.test import TestCase, override_settings from tests.testapp.tests.base_tests import BaseRedisTestCase diff --git a/tests/testapp/tests/master_slave_tests.py b/tests/testapp/tests/master_slave_tests.py index 951f34fe..b1dad180 100644 --- a/tests/testapp/tests/master_slave_tests.py +++ b/tests/testapp/tests/master_slave_tests.py @@ -1,10 +1,6 @@ import time -from django.test import TestCase -try: - from django.test import override_settings -except ImportError: - from django.test.utils import override_settings +from django.test import TestCase, override_settings from redis_cache.connection import pool diff --git a/tests/testapp/tests/serializers_tests.py b/tests/testapp/tests/serializers_tests.py index 403b5332..338ffe85 100644 --- a/tests/testapp/tests/serializers_tests.py +++ b/tests/testapp/tests/serializers_tests.py @@ -1,11 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.test import TestCase -try: - from django.test import override_settings -except ImportError: - from django.test.utils import override_settings +from django.test import TestCase, override_settings from tests.testapp.tests.base_tests import SetupMixin @@ -171,4 +167,3 @@ class MSGPackSerializerTestCase(BaseSerializerTestCase): class YAMLSerializerTestCase(BaseSerializerTestCase): converts_tuple_to_list = False serializes_objects = True - diff --git a/tests/testapp/tests/socket_tests.py b/tests/testapp/tests/socket_tests.py index b02707e4..4efbf1a1 100644 --- a/tests/testapp/tests/socket_tests.py +++ b/tests/testapp/tests/socket_tests.py @@ -3,11 +3,7 @@ from tests.testapp.tests.base_tests import BaseRedisTestCase from tests.testapp.tests.multi_server_tests import MultiServerTests -try: - from django.test import override_settings -except ImportError: - from django.test.utils import override_settings -from django.test import TestCase +from django.test import TestCase, override_settings LOCATION = "unix://:yadayada@/tmp/redis0.sock?db=15" diff --git a/tests/testapp/tests/socket_timeout_tests.py b/tests/testapp/tests/socket_timeout_tests.py index 0dc381ab..90e7d52a 100644 --- a/tests/testapp/tests/socket_timeout_tests.py +++ b/tests/testapp/tests/socket_timeout_tests.py @@ -1,9 +1,5 @@ # -*- coding: utf-8 -*- -try: - from django.test import override_settings -except ImportError: - from django.test.utils import override_settings -from django.test import TestCase +from django.test import TestCase, override_settings from redis.exceptions import ConnectionError from tests.testapp.tests.base_tests import SetupMixin diff --git a/tests/testapp/tests/tcp_tests.py b/tests/testapp/tests/tcp_tests.py index 86a50382..1ebd6e1d 100644 --- a/tests/testapp/tests/tcp_tests.py +++ b/tests/testapp/tests/tcp_tests.py @@ -1,11 +1,7 @@ # -*- coding: utf-8 -*- from tests.testapp.tests.base_tests import BaseRedisTestCase from tests.testapp.tests.multi_server_tests import MultiServerTests -try: - from django.test import override_settings -except ImportError: - from django.test.utils import override_settings -from django.test import TestCase +from django.test import TestCase, override_settings from redis_cache.cache import ImproperlyConfigured from redis.connection import UnixDomainSocketConnection