Add Python 3 suport and drop support for Python 2.5

This commit is contained in:
Venelin Stoykov 2013-08-19 21:27:50 +03:00
parent 453efac553
commit 0575011529
9 changed files with 67 additions and 24 deletions

View file

@ -120,7 +120,7 @@ class ImageCacheFile(BaseIKFile, ImageFile):
)
)
def __nonzero__(self):
def __bool__(self):
if not self.name:
return False
@ -129,6 +129,10 @@ class ImageCacheFile(BaseIKFile, ImageFile):
existence_required.send(sender=self, file=self)
return self.cachefile_backend.exists(self)
def __nonzero__(self):
# Python 2 compatibility
return self.__bool__()
class LazyImageCacheFile(SimpleLazyObject):
def __init__(self, generator_id, *args, **kwargs):

View file

@ -1,4 +1,7 @@
import six
from django.utils.functional import LazyObject
from ..lib import force_text
from ..utils import get_singleton
@ -35,7 +38,7 @@ class DictStrategy(object):
class StrategyWrapper(LazyObject):
def __init__(self, strategy):
if isinstance(strategy, basestring):
if isinstance(strategy, six.string_types):
strategy = get_singleton(strategy, 'cache file strategy')
elif isinstance(strategy, dict):
strategy = DictStrategy(strategy)
@ -50,7 +53,7 @@ class StrategyWrapper(LazyObject):
self._wrapped = state['_wrapped']
def __unicode__(self):
return unicode(self._wrapped)
return force_text(self._wrapped)
def __str__(self):
return str(self._wrapped)

View file

@ -1,6 +1,9 @@
from django.core.files.base import File, ContentFile
from django.utils.encoding import smart_str, smart_unicode
from __future__ import unicode_literals
import os
from django.core.files.base import File, ContentFile
from django.utils.encoding import smart_str
from .lib import smart_text
from .utils import format_to_mimetype, extension_to_mimetype
@ -92,4 +95,5 @@ class IKContentFile(ContentFile):
return smart_str(self.file.name or '')
def __unicode__(self):
return smart_unicode(self.file.name or u'')
# Python 2
return smart_text(self.file.name or '')

View file

@ -1,12 +1,16 @@
from copy import copy
from hashlib import md5
from pickle import Pickler, MARK, DICT
from types import DictionaryType
from pickle import MARK, DICT
try:
from pickle import _Pickler
except ImportError:
# Python 2 compatible
from pickle import Pickler as _Pickler
from .lib import StringIO
class CanonicalizingPickler(Pickler):
dispatch = copy(Pickler.dispatch)
class CanonicalizingPickler(_Pickler):
dispatch = copy(_Pickler.dispatch)
def save_set(self, obj):
rv = obj.__reduce_ex__(0)
@ -20,9 +24,9 @@ class CanonicalizingPickler(Pickler):
write(MARK + DICT)
self.memoize(obj)
self._batch_setitems(sorted(obj.iteritems()))
self._batch_setitems(sorted(obj.items()))
dispatch[DictionaryType] = save_dict
dispatch[dict] = save_dict
def pickle(obj):

View file

@ -19,9 +19,12 @@ except ImportError:
raise ImportError('ImageKit was unable to import the Python Imaging Library. Please confirm it`s installed and available on your current Python path.')
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
from io import BytesIO as StringIO
except:
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
try:
from logging import NullHandler
@ -31,3 +34,17 @@ except ImportError:
class NullHandler(Handler):
def emit(self, record):
pass
# Try to import `force_text` available from Django 1.5
# This function will replace `unicode` used in the code
# If Django version is under 1.5 then use `force_unicde`
# It is used for compatibility between Python 2 and Python 3
# NOTE: I'm not sure if this is the right place. Maybe this can be in `utils`.
try:
from django.utils.encoding import force_text, smart_text
except ImportError:
# Django < 1.5
from django.utils.encoding import force_unicode as force_text, smart_unicode as smart_text
__all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', 'ImageFilter',
'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler', 'force_text', 'smart_text']

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
from django.db import models
from .files import ProcessedImageFieldFile
from .utils import ImageSpecFileDescriptor
@ -13,7 +15,7 @@ class SpecHostField(SpecHost):
# Generate a spec_id to register the spec with. The default spec id is
# "<app>:<model>_<field>"
if not spec_id:
spec_id = (u'%s:%s:%s' % (cls._meta.app_label,
spec_id = ('%s:%s:%s' % (cls._meta.app_label,
cls._meta.object_name, name)).lower()
# Register the spec with the id. This allows specs to be overridden

View file

@ -1,9 +1,13 @@
from __future__ import unicode_literals
from django import template
from django.utils.html import escape
from django.utils.safestring import mark_safe
from .compat import parse_bits
from ..cachefiles import ImageCacheFile
from ..registry import generator_registry
from ..lib import force_text
register = template.Library()
@ -40,7 +44,7 @@ class GenerateImageAssignmentNode(template.Node):
self._variable_name = variable_name
def get_variable_name(self, context):
return unicode(self._variable_name)
return force_text(self._variable_name)
def render(self, context):
variable_name = self.get_variable_name(context)
@ -70,7 +74,7 @@ class GenerateImageTagNode(template.Node):
attrs['src'] = file.url
attr_str = ' '.join('%s="%s"' % (escape(k), escape(v)) for k, v in
attrs.items())
return mark_safe(u'<img %s />' % attr_str)
return mark_safe('<img %s />' % attr_str)
class ThumbnailAssignmentNode(template.Node):
@ -83,7 +87,7 @@ class ThumbnailAssignmentNode(template.Node):
self._generator_kwargs = generator_kwargs
def get_variable_name(self, context):
return unicode(self._variable_name)
return force_text(self._variable_name)
def render(self, context):
variable_name = self.get_variable_name(context)
@ -131,7 +135,7 @@ class ThumbnailImageTagNode(template.Node):
attrs['src'] = file.url
attr_str = ' '.join('%s="%s"' % (escape(k), escape(v)) for k, v in
attrs.items())
return mark_safe(u'<img %s />' % attr_str)
return mark_safe('<img %s />' % attr_str)
def parse_ik_tag_bits(parser, bits):

View file

@ -1,3 +1,4 @@
from __future__ import unicode_literals
import logging
from tempfile import NamedTemporaryFile
@ -11,7 +12,7 @@ import re
from .lib import NullHandler
bad_memcached_key_chars = re.compile(ur'[\u0000-\u001f\s]+')
bad_memcached_key_chars = re.compile(r'[\u0000-\u001f\s]+')
_autodiscovered = False
@ -32,7 +33,7 @@ def get_by_qname(path, desc):
module, objname = path[:dot], path[dot + 1:]
try:
mod = import_module(module)
except ImportError, e:
except ImportError as e:
raise ImproperlyConfigured('Error importing %s module %s: "%s"' %
(desc, module, e))
try:

View file

@ -19,10 +19,12 @@ if 'publish' in sys.argv:
read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read()
def exec_file(filepath, globalz=None, localz=None):
exec(read(filepath), globalz, localz)
# Load package meta from the pkgmeta module without loading imagekit.
pkgmeta = {}
execfile(os.path.join(os.path.dirname(__file__),
exec_file(os.path.join(os.path.dirname(__file__),
'imagekit', 'pkgmeta.py'), pkgmeta)
@ -51,6 +53,7 @@ setup(
install_requires=[
'django-appconf>=0.5',
'pilkit>=0.2.0',
'six',
],
extras_require={
'async': ['django-celery>=3.0'],
@ -62,9 +65,10 @@ setup(
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Topic :: Utilities'
],
)