Skip to content

Commit 304e188

Browse files
committed
Support python 2/3, and Django 1.7/1.9
* `assertEquals`, `assertRaisesRegexp` have been deprecated in python 3 * `iteritems` is not supported in python 3 * `str` and `bytes` are handled separately in python 3 * `xrange` is not supported in python 3 * `mark_safe` is required in Django 1.9 to add tags to HTML
1 parent 063a54c commit 304e188

File tree

6 files changed

+44
-20
lines changed

6 files changed

+44
-20
lines changed

cloudinary/compat.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
to_bytearray = lambda s: bytearray(s, 'utf8')
1616
to_string = lambda b: b.decode('utf8')
1717
string_types = (str)
18+
1819
else:
1920
import httplib
2021
from httplib import NotConnected
@@ -29,6 +30,12 @@
2930
to_string = str
3031
string_types = (str, unicode)
3132

33+
try:
34+
cldrange = xrange
35+
except NameError:
36+
def cldrange(*args, **kwargs):
37+
return iter(range(*args, **kwargs))
38+
3239
try:
3340
advance_iterator = next
3441
except NameError:

cloudinary/poster/encode.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ def encode_and_quote(data):
5656
def _strify(s):
5757
if s is None:
5858
return None
59-
return to_bytes(s)
59+
elif isinstance(s, bytes):
60+
return s
61+
else:
62+
try:
63+
return to_bytes(s)
64+
except AttributeError:
65+
return to_bytes(str(s))
6066
else:
6167
def _strify(s):
6268
"""If s is a unicode string, encode it to UTF-8 and return the results, otherwise return str(s), or None if s is None"""
@@ -236,10 +242,10 @@ def encode(self, boundary):
236242
else:
237243
value = self.value
238244

239-
if re.search("^--%s$" % re.escape(boundary), value, re.M):
245+
if re.search(to_bytes("^--%s$" % re.escape(boundary)), value, re.M):
240246
raise ValueError("boundary found in encoded string")
241247

242-
return "%s%s\r\n" % (self.encode_hdr(boundary), value)
248+
return to_bytes(self.encode_hdr(boundary)) + value + b"\r\n"
243249

244250
def iter_encode(self, boundary, blocksize=4096):
245251
"""Yields the encoding of this parameter
@@ -248,7 +254,7 @@ def iter_encode(self, boundary, blocksize=4096):
248254
total = self.get_size(boundary)
249255
current = 0
250256
if self.value is not None:
251-
block = to_bytes(self.encode(boundary))
257+
block = self.encode(boundary)
252258
current += len(block)
253259
yield block
254260
if self.cb:

cloudinary/templatetags/cloudinary.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from django import template
66
from django.forms import Form
7+
from django.utils.safestring import mark_safe
78

89
import cloudinary
910
from cloudinary import CloudinaryResource, utils, uploader
@@ -34,7 +35,7 @@ def cloudinary_tag(context, image, options_dict={}, **options):
3435
pass
3536
if not isinstance(image, CloudinaryResource):
3637
image = CloudinaryResource(image)
37-
return image.image(**options)
38+
return mark_safe(image.image(**options))
3839

3940
@register.simple_tag
4041
def cloudinary_direct_upload_field(field_name="image", request=None):

cloudinary/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
RANGE_VALUE_RE = r'^(?P<value>(\d+\.)?\d+)(?P<modifier>[%pP])?$'
1313
RANGE_RE = r'^(\d+\.)?\d+[%pP]?\.\.(\d+\.)?\d+[%pP]?$'
14-
__LAYER_KEYWORD_PARAMS = dict(font_weight = "normal", font_style = "normal", text_decoration = "none", text_align = None, stroke = "none")
14+
__LAYER_KEYWORD_PARAMS = [("font_weight", "normal"), ("font_style", "normal"), ("text_decoration", "none"), ("text_align", None), ("stroke", "none")]
1515

1616
def build_array(arg):
1717
if isinstance(arg, list):
@@ -222,7 +222,7 @@ def generate_responsive_breakpoints_string(breakpoints):
222222
if breakpoints is None:
223223
return None
224224
breakpoints = build_array(breakpoints)
225-
return json.dumps(map(breakpoint_settings_mapper, breakpoints))
225+
return json.dumps(list(map(breakpoint_settings_mapper, breakpoints)))
226226

227227
def finalize_source(source, format, url_suffix):
228228
source = re.sub(r'([^:])/+', r'\1/', source)
@@ -512,7 +512,7 @@ def __process_text_options(layer, layer_parameter):
512512
font_family = layer.get("font_family")
513513
font_size = layer.get("font_size")
514514
keywords = []
515-
for attr, default_value in __LAYER_KEYWORD_PARAMS.iteritems():
515+
for attr, default_value in __LAYER_KEYWORD_PARAMS:
516516
attr_value =layer.get(attr)
517517
if (attr_value != default_value and attr_value is not None):
518518
keywords.append(attr_value)

tests/api_test.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
class ApiTest(unittest.TestCase):
77
initialized = False
88
def setUp(self):
9+
try:
10+
self.assertRaisesRegex
11+
except AttributeError:
12+
self.assertRaisesRegex = self.assertRaisesRegexp
13+
914
if ApiTest.initialized: return
1015
ApiTest.initialized = True
1116
cloudinary.reset_config()
@@ -14,13 +19,17 @@ def setUp(self):
1419
api.delete_resources(["api_test", "api_test2", "api_test3"])
1520
except:
1621
pass
17-
for transformation in ["api_test_transformation", "api_test_transformation2", "api_test_transformation3",
18-
"api_test_upload_preset", "api_test_upload_preset2", "api_test_upload_preset3",
19-
"api_test_upload_preset4"]:
22+
for transformation in ["api_test_transformation", "api_test_transformation2", "api_test_transformation3"]:
2023
try:
2124
api.delete_transformation(transformation)
2225
except:
2326
pass
27+
for transformation in ["api_test_upload_preset", "api_test_upload_preset2", "api_test_upload_preset3",
28+
"api_test_upload_preset4"]:
29+
try:
30+
api.delete_upload_preset(transformation)
31+
except:
32+
pass
2433
ApiTest.timestamp_tag = "api_test_tag_{0}".format(utils.now())
2534
uploader.upload("tests/logo.png", public_id="api_test", tags=["api_test_tag", self.timestamp_tag], context="key=value", eager=[{"width": 100,"crop": "scale"}])
2635
uploader.upload("tests/logo.png", public_id="api_test2", tags=["api_test_tag", self.timestamp_tag], context="key=value", eager=[{"width": 100,"crop": "scale"}])
@@ -267,25 +276,25 @@ def test20_manual_moderation(self):
267276
def test22_raw_conversion(self):
268277
""" should support requesting raw_convert """
269278
resource = uploader.upload("tests/docx.docx", resource_type="raw")
270-
with self.assertRaisesRegexp(api.BadRequest, 'Illegal value'):
279+
with self.assertRaisesRegex(api.BadRequest, 'Illegal value'):
271280
api.update(resource["public_id"], raw_convert="illegal", resource_type="raw")
272281

273282
@unittest.skipUnless(cloudinary.config().api_secret, "requires api_key/api_secret")
274283
def test23_categorization(self):
275284
""" should support requesting categorization """
276-
with self.assertRaisesRegexp(api.BadRequest, 'Illegal value'):
285+
with self.assertRaisesRegex(api.BadRequest, 'Illegal value'):
277286
api.update("api_test", categorization="illegal")
278287

279288
@unittest.skipUnless(cloudinary.config().api_secret, "requires api_key/api_secret")
280289
def test24_detection(self):
281290
""" should support requesting detection """
282-
with self.assertRaisesRegexp(api.BadRequest, 'Illegal value'):
291+
with self.assertRaisesRegex(api.BadRequest, 'Illegal value'):
283292
api.update("api_test", detection="illegal")
284293

285294
@unittest.skipUnless(cloudinary.config().api_secret, "requires api_key/api_secret")
286295
def test26_auto_tagging(self):
287296
""" should support requesting auto_tagging """
288-
with self.assertRaisesRegexp(api.BadRequest, 'Must use'):
297+
with self.assertRaisesRegex(api.BadRequest, 'Must use'):
289298
api.update("api_test", auto_tagging=0.5)
290299

291300
@unittest.skipUnless(cloudinary.config().api_secret, "requires api_key/api_secret")
@@ -358,7 +367,7 @@ def test31_update_upload_presets(self):
358367
@unittest.skipUnless(cloudinary.config().api_secret, "requires api_key/api_secret")
359368
def test32_background_removal(self):
360369
""" should support requesting background_removal """
361-
with self.assertRaisesRegexp(api.BadRequest, 'Illegal value'):
370+
with self.assertRaisesRegex(api.BadRequest, 'Illegal value'):
362371
api.update("api_test", background_removal="illegal")
363372

364373
@unittest.skipUnless(cloudinary.config().api_secret, "requires api_key/api_secret")
@@ -377,7 +386,7 @@ def test_folder_listing(self):
377386
result = api.subfolders("test_folder1")
378387
self.assertEqual(result["folders"][0]["path"], "test_folder1/test_subfolder1")
379388
self.assertEqual(result["folders"][1]["path"], "test_folder1/test_subfolder2")
380-
with self.assertRaisesRegexp(api.NotFound):
389+
with self.assertRaisesRegex(api.NotFound):
381390
api.subfolders("test_folder")
382391
api.delete_resources_by_prefix("test_folder")
383392

@@ -390,7 +399,7 @@ def test_CloudinaryImage_len(self):
390399
"signature": "5678",
391400
}
392401
myCloudinaryImage = cloudinary.CloudinaryImage(metadata=metadata)
393-
self.assertEquals(len(myCloudinaryImage), len(metadata["public_id"]))
402+
self.assertEqual(len(myCloudinaryImage), len(metadata["public_id"]))
394403

395404
@unittest.skipUnless(cloudinary.config().api_secret, "requires api_key/api_secret")
396405
def test_restore(self):

tests/utils_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import unittest
33
import re
44
from fractions import Fraction
5+
from cloudinary.compat import cldrange
56

67
DEFAULT_ROOT_PATH = 'http://res.cloudinary.com/test123/'
78
DEFAULT_UPLOAD_PATH = 'http://res.cloudinary.com/test123/image/upload/'
@@ -471,11 +472,11 @@ def test_overlay_options(self):
471472
dict(resource_type = "subtitles",public_id = "sample_sub_he.srt", font_family = "Arial", font_size = 40),"subtitles:Arial_40:sample_sub_he.srt"
472473
]
473474

474-
for i in xrange(0, len(tests), 2):
475+
for i in cldrange(0, len(tests), 2):
475476
options = tests[i]
476477
expected = tests[i + 1]
477478
result = cloudinary.utils.process_layer(options, "overlay")
478-
self.assertEqual(result, expected)
479+
self.assertEqual(expected, result)
479480

480481
def test_overlay_error_1(self):
481482
""" Must supply font_family for text in overlay """

0 commit comments

Comments
 (0)