Given that Django is still supporting Python 2.4, I think it should be important for related tools to hold the same support. I'm putting this application into production on a CentOS 5.5 machine, so adding this compatibility become a necessity for me. It wasn't even a difficult task, luckily! Here are the changes necessary:
diff --git a/caching/base.py b/caching/base.py
index 44f5fed..416025e 100644
--- a/caching/base.py
+++ b/caching/base.py
@@ -1,6 +1,4 @@
-import collections
-import functools
-import hashlib
+from compat import *
import logging
from django.conf import settings
@@ -147,7 +145,7 @@ class CacheMachine(object):
flush_keys = [o.flush_key() for o in objects]
query_flush = flush_key(self.query_string)
- flush_lists = collections.defaultdict(list)
+ flush_lists = defaultdict(list)
for key in flush_keys:
flush_lists[key].extend([query_key, query_flush])
flush_lists[query_flush].append(query_key)
@@ -252,13 +250,13 @@ class CachingRawQuerySet(models.query.RawQuerySet):
def flush_key(obj):
"""We put flush lists in the flush: namespace."""
- key = obj if isinstance(obj, basestring) else obj.cache_key
+ key = isinstance(obj, basestring) and obj or obj.cache_key
return FLUSH + make_key(key, with_locale=False)
def add_to_flush_list(mapping):
"""Update flush lists with the {flush_key: [query_key,...]} map."""
- flush_lists = collections.defaultdict(set)
+ flush_lists = defaultdict(set)
flush_lists.update(cache.get_many(mapping.keys()))
for key, list_ in mapping.items():
if flush_lists[key] is None:
@@ -276,7 +274,7 @@ def make_key(k, with_locale=True):
# memcached keys must be < 250 bytes and w/o whitespace, but it's nice
# to see the keys when using locmem.
if 'memcached' in cache.scheme:
- return hashlib.md5(encoding.smart_str(key)).hexdigest()
+ return md5_constructor(encoding.smart_str(key)).hexdigest()
else:
return key
@@ -301,8 +299,7 @@ def cached(function, key_, duration=None):
def cached_with(obj, f, f_key, timeout=None):
"""Helper for caching a function call within an object's flush list."""
try:
- obj_key = (obj.query_key() if hasattr(obj, 'query_key')
- else obj.cache_key)
+ obj_key = hasattr(obj, 'query_key') and obj.query_key() or obj.cache_key
except AttributeError:
log.warning(u'%r cannot be cached.' % obj)
return f()
@@ -352,7 +349,7 @@ class MethodWrapper(object):
self.cache = {}
def __call__(self, *args, **kwargs):
- k = lambda o: o.cache_key if hasattr(o, 'cache_key') else o
+ k = lambda o: hasattr(o, 'cache_key') and o.cache_key or o
arg_keys = map(k, args)
kwarg_keys = [(key, k(val)) for key, val in kwargs.items()]
key = 'm:%s:%s:%s:%s' % (self.obj.cache_key, self.func.__name__,
try:
import functools
except ImportError:
import django.utils.functional as functools
# GPL licensed code taken from NLTK - http://code.google.com/p/nltk/
# collections.defaultdict
# originally contributed by Yoav Goldberg <[email protected]>
# new version by Jason Kirtland from Python cookbook.
# <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/523034>
try:
from collections import defaultdict
except ImportError:
class defaultdict(dict):
def __init__(self, default_factory=None, *a, **kw):
if (default_factory is not None and
not hasattr(default_factory, '__call__')):
raise TypeError('first argument must be callable')
dict.__init__(self, *a, **kw)
self.default_factory = default_factory
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self.__missing__(key)
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
self[key] = value = self.default_factory()
return value
def __reduce__(self):
if self.default_factory is None:
args = tuple()
else:
args = self.default_factory,
return type(self), args, None, None, self.iteritems()
def copy(self):
return self.__copy__()
def __copy__(self):
return type(self)(self.default_factory, self)
def __deepcopy__(self, memo):
import copy
return type(self)(self.default_factory,
copy.deepcopy(self.items()))
def __repr__(self):
return 'defaultdict(%s, %s)' % (self.default_factory,
dict.__repr__(self))
# [XX] to make pickle happy in python 2.4:
import collections
collections.defaultdict = defaultdict
from django.utils.hashcompat import md5_constructor
__all__ = ['functools','defaultdict','md5_constructor']