diff --git a/.frigg.yml b/.frigg.yml index ad8ee48..afc3ce6 100644 --- a/.frigg.yml +++ b/.frigg.yml @@ -2,9 +2,19 @@ tasks: - tox -e flake8 - tox -e isort - tox -e py34-pillow + - tox -e py27-pillow + - tox -e py34-pgmagick + - tox -e py27-pgmagick + - tox -e py34-wand + - tox -e py27-wand - tox -e py34-django17 + - tox -e py27-django17 - tox -e py34-django18 + - tox -e py27-django18 - tox -e py34-redis + - tox -e py27-redis + - flake8 + - isort -rc -c thumbnails tests - coverage combine && coverage report && coverage xml - tox -e docs diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 49de0c6..42aaa81 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,9 @@ Changes since last release ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Nothing yet. + +0.6.0 +~~~~~ + - Reintroduce support for Python 2 0.5.0 ~~~~~ diff --git a/setup.py b/setup.py index 8645cae..f207694 100644 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ def _read_long_description(): classifiers=[ 'Development Status :: 4 - Beta', 'Programming Language :: Python', + 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.4', ] ) diff --git a/tests/compat.py b/tests/compat.py new file mode 100644 index 0000000..ae4ad71 --- /dev/null +++ b/tests/compat.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +import six + +if six.PY3: + from unittest import mock # noqa + +elif six.PY2: + import mock # noqa diff --git a/tests/test_cache_backends.py b/tests/test_cache_backends.py index e6da03b..6b0e101 100644 --- a/tests/test_cache_backends.py +++ b/tests/test_cache_backends.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- import unittest -from unittest import mock from thumbnails.cache_backends import (BaseCacheBackend, DjangoCacheBackend, RedisCacheBackend, SimpleCacheBackend) from thumbnails.images import Thumbnail +from .compat import mock from .utils import has_installed diff --git a/tests/test_compat.py b/tests/test_compat.py new file mode 100644 index 0000000..032a8bd --- /dev/null +++ b/tests/test_compat.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +import os +import shutil +import unittest + +from thumbnails.compat import makedirs + + +class CompatTestCase(unittest.TestCase): + + def test_makedirs(self): + path = os.path.join(os.getcwd(), 'makedirs-test/folders') + makedirs(path, exist_ok=True) + makedirs(path, exist_ok=True) + + with self.assertRaises(OSError): + makedirs(path) + + shutil.rmtree(os.path.dirname(path)) diff --git a/tests/test_conf.py b/tests/test_conf.py index 6a3ab2c..ea00c44 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -2,10 +2,10 @@ import os import unittest from copy import deepcopy -from unittest import mock from thumbnails.conf.wrapper import SettingsWrapper +from .compat import mock from .utils import has_installed diff --git a/tests/test_engines.py b/tests/test_engines.py index a3eae4a..901031f 100644 --- a/tests/test_engines.py +++ b/tests/test_engines.py @@ -2,7 +2,6 @@ import hashlib import os import unittest -from unittest import mock from PIL import Image @@ -11,6 +10,7 @@ from thumbnails.errors import ThumbnailError from thumbnails.images import SourceFile, Thumbnail +from .compat import mock from .utils import is_tox_env diff --git a/tests/test_images.py b/tests/test_images.py index 4e483cd..2b663f6 100644 --- a/tests/test_images.py +++ b/tests/test_images.py @@ -2,15 +2,15 @@ import hashlib import os import unittest -from io import BytesIO -from unittest import mock from PIL import Image +from thumbnails.compat import BytesIO from thumbnails.conf import settings from thumbnails.images import SourceFile, Thumbnail from . import data +from .compat import mock from .utils import has_installed diff --git a/tests/test_init.py b/tests/test_init.py index 2a09d21..01efc2a 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- import unittest -from unittest import mock from thumbnails import get_thumbnail from thumbnails.conf import settings from thumbnails.images import Thumbnail +from .compat import mock from .utils import override_settings diff --git a/tests/test_templatetags.py b/tests/test_templatetags.py index ed746b7..a3f8258 100644 --- a/tests/test_templatetags.py +++ b/tests/test_templatetags.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- import unittest -from unittest import mock from thumbnails import settings +from .compat import mock from .utils import has_installed try: diff --git a/thumbnails/compat.py b/thumbnails/compat.py new file mode 100644 index 0000000..2518a83 --- /dev/null +++ b/thumbnails/compat.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +import errno + +import six + +BytesIO = six.BytesIO +StringIO = six.StringIO + +if six.PY3: + from os import makedirs +else: + from os import makedirs as os_makedirs + + def makedirs(name, mode=0o777, exist_ok=False): + try: + os_makedirs(name, mode) + except OSError as e: + if e.errno != errno.EEXIST or not exist_ok: + raise diff --git a/thumbnails/conf/wrapper.py b/thumbnails/conf/wrapper.py index 1373fe7..4603eb7 100644 --- a/thumbnails/conf/wrapper.py +++ b/thumbnails/conf/wrapper.py @@ -3,6 +3,8 @@ import json import os +from thumbnails.compat import makedirs + from . import defaults @@ -27,8 +29,8 @@ def __init__(self): pass if not os.path.exists(self.THUMBNAIL_PATH): - os.makedirs(os.path.dirname(self.THUMBNAIL_PATH), exist_ok=True) - os.makedirs(self.THUMBNAIL_PATH, exist_ok=True) + makedirs(os.path.dirname(self.THUMBNAIL_PATH), exist_ok=True) + makedirs(self.THUMBNAIL_PATH, exist_ok=True) def __getattr__(self, key): value = self.defaults.get(key, 'unknown setting') diff --git a/thumbnails/engines/pillow_engine.py b/thumbnails/engines/pillow_engine.py index d0ddce1..59db0d4 100644 --- a/thumbnails/engines/pillow_engine.py +++ b/thumbnails/engines/pillow_engine.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from io import BytesIO +from thumbnails.compat import BytesIO from thumbnails.errors import ThumbnailError from .base import BaseThumbnailEngine diff --git a/thumbnails/images.py b/thumbnails/images.py index 8c51736..18156b8 100644 --- a/thumbnails/images.py +++ b/thumbnails/images.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import base64 import os -from io import BytesIO import requests +from thumbnails.compat import BytesIO from thumbnails.conf import settings from thumbnails.helpers import get_engine, get_storage_backend diff --git a/thumbnails/storage_backends.py b/thumbnails/storage_backends.py index c0311b1..886fa52 100644 --- a/thumbnails/storage_backends.py +++ b/thumbnails/storage_backends.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import codecs import os -from io import BytesIO from thumbnails import helpers +from .compat import BytesIO, makedirs from .conf import settings @@ -51,7 +51,7 @@ class FilesystemStorageBackend(BaseStorageBackend): def __init__(self): super(FilesystemStorageBackend, self).__init__() if not os.path.exists(self.location): - os.makedirs(self.location, exist_ok=True) + makedirs(self.location, exist_ok=True) def _open(self, name, mode='rb', encoding=None, errors='strict'): return codecs.open(name, mode=mode, encoding=encoding, errors=errors) @@ -61,7 +61,7 @@ def _exists(self, name): def _save(self, name, data): if not os.path.exists(os.path.dirname(name)): - os.makedirs(os.path.dirname(name), exist_ok=True) + makedirs(os.path.dirname(name), exist_ok=True) with open(name, 'wb') as f: f.write(data) diff --git a/tox.ini b/tox.ini index 4a85078..9cde1ca 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,9 @@ [tox] envlist = flake8,isort, - {py34}-{pillow,wand,pgmagick}, - {py34}-{django17,django18,redis}, - docs + {py27,py34}-{pillow,wand,pgmagick}, + {py27,py34}-{django17,django18,redis}, + py34-docs skipsdist = True [testenv]