Blob Blame History Raw
diff --git a/glue/algorithms/__init__.py b/glue/algorithms/__init__.py
index c9413bf..8b0979c 100644
--- a/glue/algorithms/__init__.py
+++ b/glue/algorithms/__init__.py
@@ -1,9 +1,9 @@
-from diagonal import DiagonalAlgorithm
-from horizontal import HorizontalAlgorithm
-from horizontal_bottom import HorizontalBottomAlgorithm
-from square import SquareAlgorithm
-from vertical import VerticalAlgorithm
-from vertical_right import VerticalRightAlgorithm
+from .diagonal import DiagonalAlgorithm
+from .horizontal import HorizontalAlgorithm
+from .horizontal_bottom import HorizontalBottomAlgorithm
+from .square import SquareAlgorithm
+from .vertical import VerticalAlgorithm
+from .vertical_right import VerticalRightAlgorithm
 
 algorithms = {'diagonal': DiagonalAlgorithm,
               'horizontal': HorizontalAlgorithm,
diff --git a/glue/bin.py b/glue/bin.py
index fe2c4c8..259e7d5 100755
--- a/glue/bin.py
+++ b/glue/bin.py
@@ -5,6 +5,7 @@
 
 from PIL import Image as PImage
 
+from glue.compat import itervalues, iterkeys, text_type
 from glue.formats import formats
 from glue.helpers import redirect_stdout
 from glue import exceptions
@@ -20,13 +21,13 @@ def main(argv=None):
 
     parser.add_argument("--source", "-s",
                         dest="source",
-                        type=unicode,
+                        type=text_type,
                         default=os.environ.get('GLUE_SOURCE', None),
                         help="Source path")
 
     parser.add_argument("--output", "-o",
                         dest="output",
-                        type=unicode,
+                        type=text_type,
                         default=os.environ.get('GLUE_OUTPUT', None),
                         help="Output path")
 
@@ -80,7 +81,7 @@ def main(argv=None):
     group.add_argument("-a", "--algorithm",
                        dest="algorithm",
                        metavar='NAME',
-                       type=unicode,
+                       type=text_type,
                        default=os.environ.get('GLUE_ALGORITHM', 'square'),
                        choices=['square', 'vertical', 'horizontal',
                                 'vertical-right', 'horizontal-bottom',
@@ -92,7 +93,7 @@ def main(argv=None):
     group.add_argument("--ordering",
                        dest="algorithm_ordering",
                        metavar='NAME',
-                       type=unicode,
+                       type=text_type,
                        default=os.environ.get('GLUE_ORDERING', 'maxside'),
                        choices=['maxside', 'width', 'height', 'area', 'filename',
                                 '-maxside', '-width', '-height', '-area', '-filename'],
@@ -100,7 +101,7 @@ def main(argv=None):
                              "filename (default: maxside)"))
 
     # Populate the parser with options required by other formats
-    for format in formats.itervalues():
+    for format in itervalues(formats):
         format.populate_argument_parser(parser)
 
     #
@@ -146,7 +147,7 @@ def add_deprecated_argument(*args, **kwargs):
         options.enabled_formats.remove('img')
 
     # Fail if any of the deprecated arguments is used
-    for argument in deprecated_arguments.iterkeys():
+    for argument in iterkeys(deprecated_arguments):
         if getattr(options, argument, None):
             parser.error(("{0} argument is deprectated "
                           "since v0.3").format(deprecated_arguments[argument]))
@@ -233,16 +234,16 @@ def add_deprecated_argument(*args, **kwargs):
                 manager.process()
         else:
             manager.process()
-    except exceptions.ValidationError, e:
+    except exceptions.ValidationError as e:
         sys.stderr.write(e.args[0])
         return e.error_code
-    except exceptions.SourceImagesNotFoundError, e:
+    except exceptions.SourceImagesNotFoundError as e:
         sys.stderr.write("Error: No images found in %s.\n" % e.args[0])
         return e.error_code
-    except exceptions.NoSpritesFoldersFoundError, e:
+    except exceptions.NoSpritesFoldersFoundError as e:
         sys.stderr.write("Error: No sprites folders found in %s.\n" % e.args[0])
         return e.error_code
-    except exceptions.PILUnavailableError, e:
+    except exceptions.PILUnavailableError as e:
         sys.stderr.write(("Error: PIL {0} decoder is unavailable"
                           "Please read the documentation and "
                           "install it before spriting this kind of "
diff --git a/glue/compat.py b/glue/compat.py
new file mode 100644
index 0000000..3718169
--- /dev/null
+++ b/glue/compat.py
@@ -0,0 +1,29 @@
+import sys
+
+PY3 = sys.version_info[0] == 3
+
+if PY3:  # pragma: no cover
+    text_type = str
+    binary_type = bytes
+
+    def itervalues(d):
+        return d.values()
+
+    def iterkeys(d):
+        return d.keys()
+
+    def iteritems(d):
+        return d.items()
+
+else:  # pragma: no cover
+    text_type = unicode
+    binary_type = str
+
+    def itervalues(d):
+        return d.itervalues()
+
+    def iterkeys(d):
+        return d.iterkeys()
+
+    def iteritems(d):
+        return d.iteritems()
diff --git a/glue/core.py b/glue/core.py
index 52b9315..c44c49e 100644
--- a/glue/core.py
+++ b/glue/core.py
@@ -3,12 +3,20 @@
 import sys
 import copy
 import hashlib
-import StringIO
-import ConfigParser
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import BytesIO as StringIO
+
+try:
+    from ConfigParser import RawConfigParser, NoSectionError
+except ImportError:
+    from configparser import RawConfigParser, NoSectionError
 
 from PIL import Image as PILImage
 
 from glue.algorithms import algorithms
+from glue.compat import iteritems
 from glue.helpers import cached_property, round_up
 from glue.formats import ImageFormat
 from glue.exceptions import SourceImagesNotFoundError, PILUnavailableError
@@ -23,11 +31,11 @@ def _get_config_from_file(self, filename, section):
         def clean(value):
             return {'true': True, 'false': False}.get(value.lower(), value)
 
-        config = ConfigParser.RawConfigParser()
+        config = RawConfigParser()
         config.read(os.path.join(self.config_path, filename))
         try:
             keys = config.options(section)
-        except ConfigParser.NoSectionError:
+        except NoSectionError:
             return {}
         return dict([[k, clean(config.get(section, k))] for k in keys])
 
@@ -48,16 +56,13 @@ def __init__(self, path, config):
         with open(self.path, "rb") as img:
             self._image_data = img.read()
 
-        print "\t{0} added to sprite".format(self.filename)
+        print("\t{0} added to sprite".format(self.filename))
 
     @cached_property
     def image(self):
         """Return a Pil representation of this image """
 
-        if sys.version < '3':
-            imageio = StringIO.StringIO(self._image_data)
-        else:
-            imageio = StringIO.BytesIO(self._image_data)
+        imageio = StringIO(self._image_data)
 
         try:
             source_image = PILImage.open(imageio)
@@ -70,7 +75,7 @@ def image(self):
                 img.paste(source_image, (0, 0), mask=mask)
             else:
                 img.paste(source_image, (0, 0))
-        except IOError, e:
+        except IOError as e:
             raise PILUnavailableError(e.args[0].split()[1])
         finally:
             imageio.close()
@@ -105,7 +110,6 @@ def margin(self):
         return self._generate_spacing_info(self.config['margin'])
 
     def _generate_spacing_info(self, data):
-
         data = data.split(',' if ',' in data else ' ')
 
         if len(data) == 4:
@@ -119,7 +123,7 @@ def _generate_spacing_info(self, data):
         else:
             data = [0] * 4
 
-        return map(int, data)
+        return list(map(int, data))
 
     @cached_property
     def horizontal_spacing(self):
@@ -196,7 +200,7 @@ def __init__(self, path, config, name=None):
             if ratio_output_key not in self.config:
                 self.config[ratio_output_key] = img_format.output_path(ratio)
 
-        print "Processing '{0}':".format(self.name)
+        print("Processing '{0}':".format(self.name))
 
         # Generate sprite map
         self.process()
@@ -220,7 +224,7 @@ def hash(self):
             hash_list.append(os.path.relpath(image.path))
             hash_list.append(image._image_data)
 
-        for key, value in self.config.iteritems():
+        for key, value in iteritems(self.config):
             hash_list.append(key)
             hash_list.append(value)
 
diff --git a/glue/formats/base.py b/glue/formats/base.py
index e0abb4b..7724d04 100644
--- a/glue/formats/base.py
+++ b/glue/formats/base.py
@@ -9,6 +9,7 @@
 
 from glue.helpers import round_up, nearest_fration
 from glue import __version__
+from glue.compat import iteritems
 
 
 class BaseFormat(object):
@@ -54,7 +55,7 @@ def validate(self):
     @property
     def format_label(self):
         from glue.formats import formats
-        return dict((v,k) for k, v in formats.iteritems())[self.__class__]
+        return dict((v, k) for k, v in iteritems(formats))[self.__class__]
 
     @classmethod
     def populate_argument_parser(cls, parser):
diff --git a/glue/formats/caat.py b/glue/formats/caat.py
index 79c722b..5705132 100644
--- a/glue/formats/caat.py
+++ b/glue/formats/caat.py
@@ -1,6 +1,6 @@
 import os
 
-from base import BaseJSONFormat
+from .base import BaseJSONFormat
 
 
 class CAATFormat(BaseJSONFormat):
diff --git a/glue/formats/cocos2d.py b/glue/formats/cocos2d.py
index ccbeaf6..6640618 100644
--- a/glue/formats/cocos2d.py
+++ b/glue/formats/cocos2d.py
@@ -1,6 +1,6 @@
 import os
 
-from base import BasePlistFormat
+from .base import BasePlistFormat
 
 
 class Cocos2dFormat(BasePlistFormat):
diff --git a/glue/formats/css.py b/glue/formats/css.py
index ecb7177..7ce1898 100644
--- a/glue/formats/css.py
+++ b/glue/formats/css.py
@@ -3,7 +3,8 @@
 import codecs
 
 from glue import __version__
-from base import JinjaTextFormat
+from glue.compat import iteritems, text_type
+from .base import JinjaTextFormat
 
 from ..exceptions import ValidationError
 
@@ -54,20 +55,20 @@ def populate_argument_parser(cls, parser):
 
         group.add_argument("--namespace",
                            dest="css_namespace",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_CSS_NAMESPACE', 'sprite'),
                            help="Namespace for all css classes (default: sprite)")
 
         group.add_argument("--sprite-namespace",
                            dest="css_sprite_namespace",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_CSS_SPRITE_NAMESPACE',
                                                   '{sprite_name}'),
                            help="Namespace for all sprites (default: {sprite_name})")
 
         group.add_argument("-u", "--url",
                            dest="css_url",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_CSS_URL', ''),
                            help="Prepend this string to the sprites path")
 
@@ -94,7 +95,7 @@ def populate_argument_parser(cls, parser):
 
         group.add_argument("--separator",
                            dest="css_separator",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_CSS_SEPARATOR', '-'),
                            metavar='SEPARATOR',
                            help=("Customize the separator used to join CSS class "
@@ -103,7 +104,7 @@ def populate_argument_parser(cls, parser):
 
         group.add_argument("--pseudo-class-separator",
                            dest="css_pseudo_class_separator",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_CSS_PSEUDO_CLASS_SEPARATOR', '__'),
                            metavar='SEPARATOR',
                            help=("Customize the separator glue will use in order "
@@ -163,7 +164,7 @@ def get_context(self, *args, **kwargs):
         if self.sprite.config['css_url']:
             context['sprite_path'] = '{0}{1}'.format(self.sprite.config['css_url'], context['sprite_filename'])
 
-            for r, ratio in context['ratios'].iteritems():
+            for r, ratio in iteritems(context['ratios']):
                 ratio['sprite_path'] = '{0}{1}'.format(self.sprite.config['css_url'], ratio['sprite_filename'])
 
         # Add cachebuster if required
@@ -174,7 +175,7 @@ def apply_cachebuster(path):
 
             context['sprite_path'] = apply_cachebuster(context['sprite_path'])
 
-            for r, ratio in context['ratios'].iteritems():
+            for r, ratio in iteritems(context['ratios']):
                 ratio['sprite_path'] = apply_cachebuster(ratio['sprite_path'])
 
         return context
diff --git a/glue/formats/img.py b/glue/formats/img.py
index eb72ecd..71a6417 100644
--- a/glue/formats/img.py
+++ b/glue/formats/img.py
@@ -4,6 +4,7 @@
 from PIL import PngImagePlugin
 
 from glue import __version__
+from glue.compat import text_type
 from glue.helpers import round_up, cached_property
 from .base import BaseFormat
 
@@ -19,7 +20,7 @@ def populate_argument_parser(cls, parser):
 
         group.add_argument("--img",
                            dest="img_dir",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_IMG', True),
                            metavar='DIR',
                            help="Output directory for img files")
@@ -38,13 +39,13 @@ def populate_argument_parser(cls, parser):
 
         group.add_argument("-p", "--padding",
                            dest="padding",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_PADDING', '0'),
                            help="Force this padding in all images")
 
         group.add_argument("--margin",
                            dest="margin",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_MARGIN', '0'),
                            help="Force this margin in all images")
 
@@ -57,7 +58,7 @@ def populate_argument_parser(cls, parser):
 
         group.add_argument("--ratios",
                            dest="ratios",
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_RATIOS', '1'),
                            help="Create sprites based on these ratios")
 
diff --git a/glue/formats/jsonformat.py b/glue/formats/jsonformat.py
index ea32a08..f7bdde6 100644
--- a/glue/formats/jsonformat.py
+++ b/glue/formats/jsonformat.py
@@ -1,12 +1,12 @@
 import os
-import json
 
 try:
     from collections import OrderedDict
 except ImportError:
     from ordereddict import OrderedDict
 
-from base import BaseJSONFormat
+from glue.compat import text_type
+from .base import BaseJSONFormat
 
 
 class JSONFormat(BaseJSONFormat):
@@ -29,7 +29,7 @@ def populate_argument_parser(cls, parser):
         group.add_argument("--json-format",
                            dest="json_format",
                            metavar='NAME',
-                           type=unicode,
+                           type=text_type,
                            default=os.environ.get('GLUE_JSON_FORMAT', 'array'),
                            choices=['array', 'hash'],
                            help=("JSON structure format (array, hash)"))
@@ -60,7 +60,7 @@ def get_context(self, *args, **kwargs):
                                        'height': context['height']})
 
         if self.sprite.config['json_format'] == 'array':
-            data['frames'] = frames.values()
+            data['frames'] = list(frames.values())
         else:
             data['frames'] = frames
 
diff --git a/glue/formats/less.py b/glue/formats/less.py
index dd07638..c557dca 100644
--- a/glue/formats/less.py
+++ b/glue/formats/less.py
@@ -1,6 +1,6 @@
 import os
 
-from css import CssFormat
+from .css import CssFormat
 
 
 class LessFormat(CssFormat):
diff --git a/glue/formats/scss.py b/glue/formats/scss.py
index c9bf49e..6e1c659 100644
--- a/glue/formats/scss.py
+++ b/glue/formats/scss.py
@@ -1,6 +1,6 @@
 import os
 
-from css import CssFormat
+from .css import CssFormat
 
 
 class ScssFormat(CssFormat):
diff --git a/glue/helpers.py b/glue/helpers.py
index 4d51c3b..5556d67 100644
--- a/glue/helpers.py
+++ b/glue/helpers.py
@@ -1,7 +1,9 @@
-import os
 import sys
 import contextlib
-from StringIO import StringIO
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO
 
 
 def round_up(value):
diff --git a/glue/managers/base.py b/glue/managers/base.py
index 6c658d3..6ae1edc 100644
--- a/glue/managers/base.py
+++ b/glue/managers/base.py
@@ -41,7 +41,7 @@ def save(self):
                 format = format_cls(sprite=sprite)
                 format.validate()
                 if format.needs_rebuild() or sprite.config['force']:
-                    print "Format '{0}' for sprite '{1}' needs rebuild...".format(format_name, sprite.name)
+                    print("Format '{0}' for sprite '{1}' needs rebuild...".format(format_name, sprite.name))
                     format.build()
                 else:
-                    print "Format '{0}'' for sprite '{1}' already exists...".format(format_name, sprite.name)
+                    print("Format '{0}'' for sprite '{1}' already exists...".format(format_name, sprite.name))
diff --git a/glue/managers/watch.py b/glue/managers/watch.py
index 51875eb..18e0e6a 100644
--- a/glue/managers/watch.py
+++ b/glue/managers/watch.py
@@ -39,5 +39,5 @@ def generate_hash(self):
 
     def signal_handler(self, signal, frame):
         """ Gracefully close the app if Ctrl+C is pressed."""
-        print 'You pressed Ctrl+C!'
+        print('You pressed Ctrl+C!')
         sys.exit(0)
diff --git a/setup.py b/setup.py
index 6d33ec9..405a6a3 100644
--- a/setup.py
+++ b/setup.py
@@ -57,5 +57,4 @@
         ]
     },
     zip_safe = False,
-    use_2to3=True
 )