Virgil Dupras avatar Virgil Dupras committed 1dbb76f

Removed the need for 2to3 in pyobjc-core by making the codebase compatible with both python 2.6+ and 3.

To do that, support for python < 2.6 was dropped and a couple of compatibility functions were added to objc._convenience. 3 tests fail under python3.2 and 2 under python2.7, but they already failed before the change.

Comments (0)

Files changed (52)

pyobjc-core/Lib/PyObjCTools/KeyValueCoding.py

 """
 from __future__ import unicode_literals
 import sys
+from objc._convenience import is_str_or_bytes
 
 __all__ = ("getKey", "setKey", "getKeyPath", "setKeyPath")
 if sys.version_info[0] == 2:
             pass
 
     # check for array-like objects
-    if not isinstance(obj, basestring):
+    if not is_str_or_bytes(obj):
         try:
             itr = iter(obj)
         except TypeError:
         object.__setattr__(self, attr, value)
 
     def __getitem__(self, item):
-        if not isinstance(item, basestring):
+        if not is_str_or_bytes(item):
             raise TypeError('Keys must be strings')
         return getKeyPath(self.__pyobjc_object__, item)
 
     def __setitem__(self, item, value):
-        if not isinstance(item, basestring):
+        if not is_str_or_bytes(item):
             raise TypeError('Keys must be strings')
         setKeyPath(self.__pyobjc_object__, item, value)

pyobjc-core/Lib/PyObjCTools/TestSupport.py

     """
     Return True if we're running in 32-bit mode
     """
-    if hasattr(_sys, 'maxint'):
-        # Python 2.5 or earlier
-        if _sys.maxint > 2 ** 32:
-            return False
-    else:
-        if _sys.maxsize > 2 ** 32:
-            return False
+    if _sys.maxsize > 2 ** 32:
+        return False
     return True
 
 def onlyIf(expr, message=None):

pyobjc-core/Lib/PyObjCTools/_BSCompiler.py

     print >>fp, ""
     print >>fp, "import objc, sys"
     print >>fp, ""
-    print >>fp, "try:"
-    print >>fp, "    maxsize = sys.maxsize"
-    print >>fp, "except AttributeError:"
-    print >>fp, "    maxsize = sys.maxint"
-    print >>fp, "if maxsize > 2 ** 32:"
+    print >>fp, "if sys.maxsize > 2 ** 32:"
     print >>fp, "    def sel32or64(a, b): return b"
     print >>fp, "else:"
     print >>fp, "    def sel32or64(a, b): return a"

pyobjc-core/Lib/objc/__init__.py

         import copy_reg
 
     import objc._objc as _objc
-    for k,v in _objc.__dict__.iteritems():
+    for k, v in _objc.__dict__.items():
         g.setdefault(k,v)
 _update()
 del _update

pyobjc-core/Lib/objc/_bridgesupport.py

 
 
 # Are we in a 64-bit build:
-is64Bit = (sys.maxint > 2147483647)
+is64Bit = (sys.maxsize > 2147483647)
 # Are we in a little-endian build:
 isLittleEndian = (sys.byteorder == 'little')
 
         try:
             try:
                 objc.parseBridgeSupport(data, globals, frameworkName, *args, **kwds)
-            except objc.internal_error, e:
+            except objc.internal_error as e:
                 import warnings
                 warnings.warn("Error parsing BridgeSupport data for %s: %s" % (frameworkName, e), RuntimeWarning)
         finally:

pyobjc-core/Lib/objc/_category.py

             raise TypeError("Category name must be same as class name")
 
 
-        m = [ x[1] for x in methods.iteritems() if x[0] not in cls._IGNORENAMES  and isinstance(x[1], (FunctionType, MethodType, selector, classmethod))]
-        vars = [ x for x in methods.iteritems() if x[0] not in cls._IGNORENAMES  and not isinstance(x[1], (FunctionType, MethodType, selector, classmethod))]
+        m = [ x[1] for x in methods.items() if x[0] not in cls._IGNORENAMES  and isinstance(x[1], (FunctionType, MethodType, selector, classmethod))]
+        vars = [ x for x in methods.items() if x[0] not in cls._IGNORENAMES  and not isinstance(x[1], (FunctionType, MethodType, selector, classmethod))]
         for k, v in vars:
             if isinstance(v, ivar):
                 raise TypeError("Cannot add instance variables in a Category")
     in the class definition will be added to the existing class.
     """
     if not isinstance(cls, objc_class):
-        raise TypeError, "Category can only be used on Objective-C classes"
+        raise TypeError("Category can only be used on Objective-C classes")
     retval = _CategoryMeta._newSubclass('Category', (), dict(real_class=cls))
     return retval

pyobjc-core/Lib/objc/_compat.py

         try:
             return objc.lookUpClass(name)
         except objc.nosuchclass_error:
-            raise AttributeError, name
+            raise AttributeError(name)
 
     def __eq__(self, other):
         return self is other

pyobjc-core/Lib/objc/_convenience.py

     set(['__cmp__'])
 
 """
+import collections
 from objc._objc import _setClassExtender, selector, lookUpClass, currentBundle, repythonify, splitSignature, _block_call
 from objc._objc import registerMetaDataForSelector
-from itertools import imap
 import sys
 
 __all__ = ( 'addConvenienceForSelector', 'addConvenienceForClass' )
 
     look_at_super = (super_class is not None and super_class.__name__ != 'Object')
 
-    for k, sel in type_dict.items():
+    for k, sel in list(type_dict.items()):
         if not isinstance(sel, selector):
             continue
 
             def __getattr__(self, key):
                 try:
                     return self.__object.valueForKey_(key)
-                except KeyError, msg:
+                except KeyError as msg:
                     if hasattr(msg, '_pyobjc_info_') and msg._pyobjc_info_['name'] == 'NSUnknownKeyException':
                         raise AttributeError(key)
 
             for key, value in other:
                 self[key] = value
 
-    for k, v in kwds.iteritems():
+    for k, v in kwds.items():
         self[k] = v
 
 def setdefault_setObject_forKey_(self, key, dflt=None):
         it = self.keyEnumerator()
         k = container_unwrap(it.nextObject(), StopIteration)
     except (StopIteration, IndexError):
-        raise KeyError, "popitem on an empty %s" % (type(self).__name__,)
+        raise KeyError("popitem on an empty %s" % (type(self).__name__,))
     else:
         result = (k, container_unwrap(self.objectForKey_(k), KeyError))
         self.removeObjectForKey_(k)
 
 
 
-def objc_hash(self, _max=sys.maxint, _const=((sys.maxint + 1L) * 2L)):
+def objc_hash(self, _max=sys.maxsize, _const=((sys.maxsize + 1) * 2)):
     rval = self.hash()
     if rval > _max:
         rval -= _const
             if ln == 0:
                 raise ValueError("%s.index(x): x not in list" % (type(self).__name__,))
             
-            if ln > sys.maxint:
-                ln = sys.maxint
+            if ln > sys.maxsize:
+                ln = sys.maxsize
 
             res = self.indexOfObject_inRange_(item, (start, ln))
             if res == NSNotFound:
         #    m = getattr(self, 'subarrayWithRange_', None)
         #    if m is not None:
         #        return m((start, stop - start))
-        return [self[i] for i in xrange(start, stop, step)]
+        return [self[i] for i in range(start, stop, step)]
     
     elif not isinstance(idx, (int, long)):
         raise TypeError("index must be a number")
             if m is not None:
                 m((start, stop - start))
                 return
-        r = range(start, stop, step)
+        r = list(range(start, stop, step))
         r.sort()
         r.reverse()
         for i in r:
         if not isinstance(anObject, (NSArray, list, tuple)):
             anObject = list(anObject)
 
-        slice_len = len(xrange(start, stop, step))
+        slice_len = len(range(start, stop, step))
         if slice_len != len(anObject):
             raise ValueError("Replacing extended slice with %d elements by %d elements"%(
                 slice_len, len(anObject)))
                 toAssign = list(anObject)
             else:
                 toAssign = anObject
-            for inIdx, outIdx in enumerate(xrange(start, stop, step)): 
+            for inIdx, outIdx in enumerate(range(start, stop, step)): 
                 self.replaceObjectAtIndex_withObject_(outIdx, toAssign[inIdx])
 
         elif step == 0:
             else:
                 toAssign = anObject
             #for inIdx, outIdx in reversed(enumerate(reversed(range(start, stop, step)))):
-            for inIdx, outIdx in enumerate(xrange(start, stop, step)): 
+            for inIdx, outIdx in enumerate(range(start, stop, step)): 
                 self.replaceObjectAtIndex_withObject_(outIdx, toAssign[inIdx])
 
 
     NSDictionary.items()
     """
     keys = aDict.allKeys()
-    return zip(keys, imap(aDict.__getitem__, keys))
+    return zip(keys, map(aDict.__getitem__, keys))
 
 #CONVENIENCE_METHODS[b'allKeys'] = (
 #    ('keys', lambda self: self.allKeys()),
 
     self.sortUsingFunction_context_(doCmp, cmpfunc)
 
+if sys.version_info[0] == 3:
+    import builtins
+    exec_ = getattr(builtins, "exec")
+    long = int
+    unicode = str
+    unichr = chr
+    def asunicode(s, encoding='ascii'):
+        if hasattr(s, 'decode'):
+            return s.decode(encoding)
+        else:
+            return s
+    
+    def is_str_or_bytes(s):
+        return isinstance(s, (str, bytes))
+    
+    def strstr(s):
+        # In some strange corner cases, an str-but-not-unicode argument is asked under Python 2
+        # but a str-but-not-bytes is asked under Python 3. This function always returns a str under
+        # both 2 and 3
+        if isinstance(s, bytes):
+            return s.decode('ascii')
+        else:
+            return s
+    
+else:
+    long = long
+    asunicode = unicode
+    unicode = unicode
+    unichr = unichr
+    def exec_(code, globs=None, locs=None):
+        """Execute code in a namespace."""
+        if globs is None:
+            frame = sys._getframe(1)
+            globs = frame.f_globals
+            if locs is None:
+                locs = frame.f_locals
+            del frame
+        elif locs is None:
+            locs = globs
+        exec("""exec code in globs, locs""")
+    
+    def is_str_or_bytes(s):
+        return isinstance(s, basestring)
+    
+    def strstr(s):
+        # See somment in other strstr()
+        if isinstance(s, unicode):
+            return s.encode('ascii')
+        else:
+            return s
+
+def funcname(func):
+    if hasattr(func, '__name__'):
+        return func.__name__
+    else:
+        return func.func_name
 
 registerMetaDataForSelector(b"NSObject", b"sortUsingFunction:context:",
         dict(
     except TypeError:
         return buff[:][item]
 
-
-if sys.version_info[:2] <= (2,6):
-    def NSData__str__(self):
-        return self.bytes()[:]
-
-elif sys.version_info[0] == 2:
-    def NSData__str__(self):
-        return str(self.bytes().tobytes())
-
-else:
-    def NSData__str__(self):
-        return str(self.bytes().tobytes())
+def NSData__str__(self):
+    return str(self.bytes().tobytes())
 
 
 CLASS_METHODS['NSData'] = (
     ('__call__', __call__),
 )
 
-
-if sys.version_info[0] == 3 or (sys.version_info[0] == 2 and sys.version_info[1] >= 6):
-    import collections
-
-    def all_contained_in(inner, outer):
-        """
-        Return True iff all items in ``inner`` are also in ``outer``.
-        """
-        for v in inner:
-            if v not in outer:
-                return False
-
-        return True
-
-    class nsdict_view (object):
-        __slots__ = ()
-
-        def __eq__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-
-            if len(self) == len(other):
-                return all_contained_in(self, other)
-        
-            else:
-                return False
-
-        def __ne__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-
-            if len(self) == len(other):
-                return not all_contained_in(self, other)
-        
-            else:
-                return True
-
-        def __lt__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-
-            if len(self) < len(other):
-                return all_contained_in(self, other)
-
-            else:
-                return False
-
-        def __le__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-
-            if len(self) <= len(other):
-                return all_contained_in(self, other)
-
-            else:
-                return False
-
-        def __gt__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-
-            if len(self) > len(other):
-                return all_contained_in(other, self)
-
-            else:
-                return False
-
-        def __ge__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-
-            if len(self) >= len(other):
-                return all_contained_in(other, self)
-
-            else:
-                return False
-
-        def __and__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-            result = set(self)
-            result.intersection_update(other)
-            return result
-
-        def __or__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-            result = set(self)
-            result.update(other)
-            return result
-
-        def __ror__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-            result = set(self)
-            result.update(other)
-            return result
-
-        def __sub__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-            result = set(self)
-            result.difference_update(other)
-            return result
-
-        def __xor__(self, other):
-            if not isinstance(other, collections.Set):
-                return NotImplemented
-            result = set(self)
-            result.symmetric_difference_update(other)
-            return result
-    
-    collections.Set.register(nsdict_view)
-
-    class nsdict_keys(nsdict_view):
-        __slots__=('__value')
-        def __init__(self, value):
-            self.__value =  value
-
-        def __repr__(self):
-            keys = list(self.__value)
-            keys.sort()
-
-            return "<nsdict_keys({0})>".format(keys)
-            
-
-        def __len__(self):
-            return len(self.__value)
-
-        def __iter__(self):
-            return iter(self.__value)
-
-        def __contains__(self, value):
-            return value in self.__value
-
-    class nsdict_values(nsdict_view):
-        __slots__=('__value')
-        def __init__(self, value):
-            self.__value =  value
-
-        def __repr__(self):
-            values = list(self)
-            values.sort()
-
-            return "<nsdict_values({0})>".format(values)
-
-        def __len__(self):
-            return len(self.__value)
-
-        def __iter__(self):
-            return iter(self.__value.objectEnumerator())
-
-        def __contains__(self, value):
-            for v in iter(self):
-                if value == v:
-                    return True
+def all_contained_in(inner, outer):
+    """
+    Return True iff all items in ``inner`` are also in ``outer``.
+    """
+    for v in inner:
+        if v not in outer:
             return False
 
-    class nsdict_items(nsdict_view):
+    return True
 
-        __slots__=('__value')
+class nsdict_view (object):
+    __slots__ = ()
 
-        def __init__(self, value):
-            self.__value =  value
+    def __eq__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
 
-        def __repr__(self):
-            values = list(self)
-            values.sort()
-
-            return "<nsdict_items({0})>".format(values)
-
-        def __len__(self):
-            return len(self.__value)
-
-        def __iter__(self):
-            for k in self.__value:
-                yield (k, self.__value[k])
-
-        def __contains__(self, value):
-            for v in iter(self):
-                if value == v:
-                    return True
+        if len(self) == len(other):
+            return all_contained_in(self, other)
+    
+        else:
             return False
 
-    collections.KeysView.register(nsdict_keys)
-    collections.ValuesView.register(nsdict_values)
-    collections.ItemsView.register(nsdict_items)
+    def __ne__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
 
-    collections.Mapping.register(lookUpClass('NSDictionary'))
-    collections.MutableMapping.register(lookUpClass('NSMutableDictionary'))
+        if len(self) == len(other):
+            return not all_contained_in(self, other)
+    
+        else:
+            return True
 
+    def __lt__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
 
+        if len(self) < len(other):
+            return all_contained_in(self, other)
 
-    NSDictionary = lookUpClass('NSDictionary')
-    def nsdict_fromkeys(cls, keys, value=None):
-        keys = [container_wrap(k) for k in keys]
-        values = [container_wrap(value)]*len(keys)
+        else:
+            return False
 
-        return NSDictionary.dictionaryWithObjects_forKeys_(values, keys)
+    def __le__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
 
-    NSMutableDictionary = lookUpClass('NSMutableDictionary')
-    def nsmutabledict_fromkeys(cls, keys, value=None):
-        result = NSMutableDictionary.dictionary()
-        value = container_wrap(value)
-        for k in keys:
-            result[container_wrap(k)] = value
+        if len(self) <= len(other):
+            return all_contained_in(self, other)
 
+        else:
+            return False
+
+    def __gt__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
+
+        if len(self) > len(other):
+            return all_contained_in(other, self)
+
+        else:
+            return False
+
+    def __ge__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
+
+        if len(self) >= len(other):
+            return all_contained_in(other, self)
+
+        else:
+            return False
+
+    def __and__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
+        result = set(self)
+        result.intersection_update(other)
         return result
 
-    def dict_new(cls, args, kwds):
-        if len(args) == 0:
-            pass
+    def __or__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
+        result = set(self)
+        result.update(other)
+        return result
 
-        elif len(args) == 1:
-            d = dict()
-            if isinstance(args[0], collections.Mapping):
-                items = args[0].iteritems()
-            else:
-                items = args[0]
-            for k , v in items:
-                d[container_wrap(k)] = container_wrap(v)
+    def __ror__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
+        result = set(self)
+        result.update(other)
+        return result
 
-            for k, v in kwds.iteritems():
-                d[container_wrap(k)] = container_wrap(v)
+    def __sub__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
+        result = set(self)
+        result.difference_update(other)
+        return result
 
-            return cls.dictionaryWithDictionary_(d)
+    def __xor__(self, other):
+        if not isinstance(other, collections.Set):
+            return NotImplemented
+        result = set(self)
+        result.symmetric_difference_update(other)
+        return result
 
-        else:
-            raise TypeError(
-                    "dict expected at most 1 arguments, got {0}".format(
-                        len(args)))
-        if kwds:
-            d = dict()
-            for k, v in kwds.iteritems():
-                d[container_wrap(k)] = container_wrap(v)
+collections.Set.register(nsdict_view)
 
-            return cls.dictionaryWithDictionary_(d)
+class nsdict_keys(nsdict_view):
+    __slots__=('__value')
+    def __init__(self, value):
+        self.__value =  value
 
-        return cls.dictionary()
+    def __repr__(self):
+        keys = list(self.__value)
+        keys.sort()
 
-    def nsdict_new(cls, *args, **kwds):
-        return dict_new(NSDictionary, args, kwds)
-
-    def nsmutabledict_new(cls, *args, **kwds):
-        return dict_new(NSMutableDictionary, args, kwds)
-
-
-    def nsdict__eq__(self, other):
-        if not isinstance(other, collections.Mapping):
-            return False
-
-        return self.isEqualToDictionary_(other)
-
-    def nsdict__ne__(self, other):
-        return not nsdict__eq__(self, other)
-
-    def nsdict__richcmp__(self, other):
-        return NotImplemented
+        return "<nsdict_keys({0})>".format(keys)
         
 
-    if sys.version_info[0] == 3:
-        CLASS_METHODS['NSDictionary'] = (
-            ('fromkeys', classmethod(nsdict_fromkeys)),
-            ('keys', lambda self: nsdict_keys(self)),
-            ('values', lambda self: nsdict_values(self)),
-            ('items', lambda self: nsdict_items(self)),
-        )
+    def __len__(self):
+        return len(self.__value)
 
-        CLASS_METHODS['NSMutableDictionary'] = (
-            ('fromkeys', classmethod(nsmutabledict_fromkeys)),
-        )
+    def __iter__(self):
+        return iter(self.__value)
+
+    def __contains__(self, value):
+        return value in self.__value
+
+class nsdict_values(nsdict_view):
+    __slots__=('__value')
+    def __init__(self, value):
+        self.__value =  value
+
+    def __repr__(self):
+        values = list(self)
+        values.sort()
+
+        return "<nsdict_values({0})>".format(values)
+
+    def __len__(self):
+        return len(self.__value)
+
+    def __iter__(self):
+        return iter(self.__value.objectEnumerator())
+
+    def __contains__(self, value):
+        for v in iter(self):
+            if value == v:
+                return True
+        return False
+
+class nsdict_items(nsdict_view):
+
+    __slots__=('__value')
+
+    def __init__(self, value):
+        self.__value =  value
+
+    def __repr__(self):
+        values = list(self)
+        values.sort()
+
+        return "<nsdict_items({0})>".format(values)
+
+    def __len__(self):
+        return len(self.__value)
+
+    def __iter__(self):
+        for k in self.__value:
+            yield (k, self.__value[k])
+
+    def __contains__(self, value):
+        for v in iter(self):
+            if value == v:
+                return True
+        return False
+
+collections.KeysView.register(nsdict_keys)
+collections.ValuesView.register(nsdict_values)
+collections.ItemsView.register(nsdict_items)
+
+collections.Mapping.register(lookUpClass('NSDictionary'))
+collections.MutableMapping.register(lookUpClass('NSMutableDictionary'))
+
+
+
+NSDictionary = lookUpClass('NSDictionary')
+def nsdict_fromkeys(cls, keys, value=None):
+    keys = [container_wrap(k) for k in keys]
+    values = [container_wrap(value)]*len(keys)
+
+    return NSDictionary.dictionaryWithObjects_forKeys_(values, keys)
+
+NSMutableDictionary = lookUpClass('NSMutableDictionary')
+def nsmutabledict_fromkeys(cls, keys, value=None):
+    result = NSMutableDictionary.dictionary()
+    value = container_wrap(value)
+    for k in keys:
+        result[container_wrap(k)] = value
+
+    return result
+
+def dict_new(cls, args, kwds):
+    if len(args) == 0:
+        pass
+
+    elif len(args) == 1:
+        d = dict()
+        if isinstance(args[0], collections.Mapping):
+            items = args[0].items()
+        else:
+            items = args[0]
+        for k , v in items:
+            d[container_wrap(k)] = container_wrap(v)
+
+        for k, v in kwds.items():
+            d[container_wrap(k)] = container_wrap(v)
+
+        return cls.dictionaryWithDictionary_(d)
 
     else:
-        CLASS_METHODS['NSDictionary'] = (
-            ('fromkeys', classmethod(nsdict_fromkeys)),
-            ('viewkeys', lambda self: nsdict_keys(self)),
-            ('viewvalues', lambda self: nsdict_values(self)),
-            ('viewitems', lambda self: nsdict_items(self)),
-            ('keys', lambda self: self.allKeys()),
-            ('items', lambda self: dictItems(self)),
-            ('values', lambda self: self.allValues()),
-        )
+        raise TypeError(
+                "dict expected at most 1 arguments, got {0}".format(
+                    len(args)))
+    if kwds:
+        d = dict()
+        for k, v in kwds.items():
+            d[container_wrap(k)] = container_wrap(v)
 
-    CLASS_METHODS['NSDictionary'] += (
-        ('__eq__', nsdict__eq__),
-        ('__ne__', nsdict__ne__),
-        ('__lt__', nsdict__richcmp__),
-        ('__le__', nsdict__richcmp__),
-        ('__gt__', nsdict__richcmp__),
-        ('__ge__', nsdict__richcmp__),
+        return cls.dictionaryWithDictionary_(d)
+
+    return cls.dictionary()
+
+def nsdict_new(cls, *args, **kwds):
+    return dict_new(NSDictionary, args, kwds)
+
+def nsmutabledict_new(cls, *args, **kwds):
+    return dict_new(NSMutableDictionary, args, kwds)
+
+
+def nsdict__eq__(self, other):
+    if not isinstance(other, collections.Mapping):
+        return False
+
+    return self.isEqualToDictionary_(other)
+
+def nsdict__ne__(self, other):
+    return not nsdict__eq__(self, other)
+
+def nsdict__richcmp__(self, other):
+    return NotImplemented
+    
+
+if sys.version_info[0] == 3:
+    CLASS_METHODS['NSDictionary'] = (
+        ('fromkeys', classmethod(nsdict_fromkeys)),
+        ('keys', lambda self: nsdict_keys(self)),
+        ('values', lambda self: nsdict_values(self)),
+        ('items', lambda self: nsdict_items(self)),
     )
 
-    NSDictionary.__new__ = nsdict_new
-    NSMutableDictionary.__new__ = nsmutabledict_new
+    CLASS_METHODS['NSMutableDictionary'] = (
+        ('fromkeys', classmethod(nsmutabledict_fromkeys)),
+    )
 
-    NSMutableDictionary.dictionary()
+else:
+    CLASS_METHODS['NSDictionary'] = (
+        ('fromkeys', classmethod(nsdict_fromkeys)),
+        ('viewkeys', lambda self: nsdict_keys(self)),
+        ('viewvalues', lambda self: nsdict_values(self)),
+        ('viewitems', lambda self: nsdict_items(self)),
+        ('keys', lambda self: self.allKeys()),
+        ('items', lambda self: dictItems(self)),
+        ('values', lambda self: self.allValues()),
+    )
 
-    #FIXME: This shouldn't be necessary
+CLASS_METHODS['NSDictionary'] += (
+    ('__eq__', nsdict__eq__),
+    ('__ne__', nsdict__ne__),
+    ('__lt__', nsdict__richcmp__),
+    ('__le__', nsdict__richcmp__),
+    ('__gt__', nsdict__richcmp__),
+    ('__ge__', nsdict__richcmp__),
+)
+
+NSDictionary.__new__ = nsdict_new
+NSMutableDictionary.__new__ = nsmutabledict_new
+
+NSMutableDictionary.dictionary()
+
+#FIXME: This shouldn't be necessary
 
 NSMutableArray = lookUpClass('NSMutableArray')
 def nsarray_add(self, other):
             n <<= 1
             tmp = tmp.arrayByAddingObjectsFromArray_(tmp)
 
-    #for n in xrange(other):
+    #for n in range(other):
         #result.extend(self)
     return result
 
     if not sequence:
         return NSArray.array()
 
-    elif isinstance(sequence, (str, unicode)):
+    elif is_str_or_bytes(sequence):
         return NSArray.arrayWithArray_(list(sequence))
 
     else:
     if not sequence:
         return NSMutableArray.array()
 
-    elif isinstance(sequence, (str, unicode)):
+    elif is_str_or_bytes(sequence):
         return NSMutableArray.arrayWithArray_(list(sequence))
 
     else:
     def __iter__(self):
         return self
 
-    def next(self):
+    def __next__(self):
         self._size -= 1
         return container_unwrap(self._enum.nextObject(), StopIteration)
+    next = __next__
 
 
 CLASS_METHODS['NSSet'] = (

pyobjc-core/Lib/objc/_descriptors.py

 
 __all__ = ['IBOutlet', 'IBAction', 'accessor', 'Accessor', 'typedAccessor', 'callbackFor', 'selectorFor', 'synthesize', 'namedselector', 'typedSelector', 'namedSelector' ]
 
-from objc._objc import ivar, selector, _makeClosure, selector, _C_SEL, _C_ID
+from ._objc import ivar, selector, _makeClosure, selector, _C_SEL, _C_ID
+from ._convenience import exec_, funcname
 import sys, textwrap
 
 #
         return selector(func, signature=b"v@:" + typeSignature)
 
     elif selArgs == 1:
-        if typeSignature == b'@' and func.func_name.startswith('countOf'):
+        if typeSignature == b'@' and funcname(func).startswith('countOf'):
             typeSignature = 'i'
 
         return selector(func, signature=typeSignature + b"@:")
             ''' % dict(name=name, ivar=ivarName))
 
     if readwrite:
-        exec setter in classDict
+        exec_(setter, classDict)
 
-    exec getter in classDict
+    exec_(getter, classDict)
 
     classDict[ivarName] = ivar(type=type)

pyobjc-core/Lib/objc/_dyld.py

 dyld emulation
 """
 
+from __future__ import unicode_literals
+
 __all__ = [
     'dyld_framework', 'dyld_library', 'dyld_find', 'pathForFramework',
     'infoForFramework',
 
 # These are the defaults as per man dyld(1)
 #
-DEFAULT_FRAMEWORK_FALLBACK = u':'.join([
-    os.path.expanduser(u"~/Library/Frameworks"),
-    u"/Library/Frameworks",
-    u"/Network/Library/Frameworks",
-    u"/System/Library/Frameworks",
+DEFAULT_FRAMEWORK_FALLBACK = ':'.join([
+    os.path.expanduser("~/Library/Frameworks"),
+    "/Library/Frameworks",
+    "/Network/Library/Frameworks",
+    "/System/Library/Frameworks",
 ])
 
-DEFAULT_LIBRARY_FALLBACK = u':'.join([
-    os.path.expanduser(u"~/lib"),
-    u"/usr/local/lib",
-    u"/lib",
-    u"/usr/lib",
+DEFAULT_LIBRARY_FALLBACK = ':'.join([
+    os.path.expanduser("~/lib"),
+    "/usr/local/lib",
+    "/lib",
+    "/usr/lib",
 ])
 
 def ensure_unicode(s):
     """Not all of PyObjC understands unicode paths very well yet"""
     if isinstance(s, bytes):
-        return unicode(s, 'utf8')
+        return s.decode('utf8')
     return s
 
 def injectSuffixes(iterator):
         return iterator
     def _inject(iterator=iterator,suffix=suffix):
         for path in iterator:
-            if path.endswith(u'.dylib'):
-                yield path[:-6] + suffix + u'.dylib'
+            if path.endswith('.dylib'):
+                yield path[:-6] + suffix + '.dylib'
             else:
                 yield path + suffix
             yield path
     def _search():
         spath = ensure_unicode(os.environ.get('DYLD_FRAMEWORK_PATH', None))
         if spath is not None:
-            for path in spath.split(u':'):
+            for path in spath.split(':'):
                 if version:
                     yield os.path.join(
-                        path, framework_name + u'.framework',
-                        u'Versions', version, framework_name
+                        path, framework_name + '.framework',
+                        'Versions', version, framework_name
                     )
                 else:
                     yield os.path.join(
-                        path, framework_name + u'.framework', framework_name
+                        path, framework_name + '.framework', framework_name
                     )
         yield filename
         spath = ensure_unicode(os.environ.get(
             'DYLD_FALLBACK_FRAMEWORK_PATH', DEFAULT_FRAMEWORK_FALLBACK
         ))
-        for path in spath.split(u':'):
+        for path in spath.split(':'):
             if version:
                 yield os.path.join(
-                    path, framework_name + u'.framework', u'Versions',
+                    path, framework_name + '.framework', 'Versions',
                     version, framework_name
                 )
             else:
                 yield os.path.join(
-                    path, framework_name + u'.framework', framework_name
+                    path, framework_name + '.framework', framework_name
                 )
 
 
     def _search():
         spath = ensure_unicode(os.environ.get('DYLD_LIBRARY_PATH', None))
         if spath is not None:
-            for path in spath.split(u':'):
+            for path in spath.split(':'):
                 yield os.path.join(path, libname)
         yield filename
         spath = ensure_unicode(os.environ.get(
             'DYLD_FALLBACK_LIBRARY_PATH', DEFAULT_LIBRARY_FALLBACK
         ))
-        for path in spath.split(u':'):
+        for path in spath.split(':'):
             yield os.path.join(path, libname)
     for f in injectSuffixes(_search()):
         if os.path.exists(f):
             return f
-    raise ValueError, "dylib %s could not be found" % (filename,)
-
-# Python version upto (at least) 2.5 do not propertly convert unicode
-# arguments to os.readlink, the code below works around that.
-if sys.version_info[:3] >= (2,6,0):
-    _realpath = os.path.realpath
-
-else:
-    def _realpath(path):
-        """
-        Unicode-safe version of os.path.realpath.
-        """
-        if isinstance(path, unicode):
-            fsenc = sys.getfilesystemencoding()
-            return os.path.realpath(path.encode(fsenc)).decode(fsenc)
-
-        return os.path.realpath(path)
-
+    raise ValueError("dylib %s could not be found" % (filename,))
 
 def dyld_find(filename):
     """Generic way to locate a dyld framework or dyld"""
 #            filename,
 #            os.path.basename(filename)[:-len(os.path.splitext(filename)[-1])]
 #        )
-    filename = _realpath(filename)
+    filename = os.path.realpath(filename)
     res = infoForFramework(filename)
     if res:
         framework_loc, framework_name, version = res
 
 def pathForFramework(path):
     fpath, name, version = infoForFramework(dyld_find(path))
-    return os.path.join(fpath, name + u'.framework')
+    return os.path.join(fpath, name + '.framework')

pyobjc-core/Lib/objc/_framework.py

 Generic framework path manipulation
 """
 
+from __future__ import unicode_literals
+
 __all__ = ['infoForFramework']
 
 # This regexp should find:
 #   \2 - framework name
 #   \3 - framework version (optional)
 #
-FRAMEWORK_RE_STR = ur"""(^.*)(?:^|/)(\w+).framework(?:/(?:Versions/([^/]+)/)?\2)?$"""
+FRAMEWORK_RE_STR = r"""(^.*)(?:^|/)(\w+).framework(?:/(?:Versions/([^/]+)/)?\2)?$"""
 FRAMEWORK_RE = None
 
 def infoForFramework(filename):

pyobjc-core/Lib/objc/_properties.py

         if isinstance(index, slice):
             result = NSMutableIndexSet.alloc().init()
             start, stop, step = index.indices(len(self._wrapped))
-            for i in xrange(start, stop, step):
+            for i in range(start, stop, step):
                 result.addIndex_(i)
 
             return result

pyobjc-core/Lib/objc/_protocols.py

 from objc import _objc
+from objc._convenience import asunicode
 
 __all__ = ['protocolNamed', 'ProtocolError']
 
     equivalent of @protocol(name) in Objective-C.
     Raises objc.ProtocolError when the protocol does not exist.
     """
-    name = unicode(name)
+    name = asunicode(name)
     try:
         return PROTOCOL_CACHE[name]
     except KeyError:

pyobjc-core/Lib/objc/_pycoder.py

 object itself, which is why we need a 'setValue' callback for the
 load_* functions below.
 """
+from __future__ import unicode_literals
+
 import sys
 import objc
 from types import *
-import copy_reg
+try:
+    import copyreg
+except ImportError:
+    import copy_reg as copyreg
 import copy
+from pickle import PicklingError, UnpicklingError, whichmodule
 
-from pickle import PicklingError, UnpicklingError, whichmodule
+from ._convenience import long, asunicode
 
 if hasattr(sys, 'intern'):
     intern = sys.intern
 
-
 # FIXME: This requires manual wrappers from the Foundation bindings
 def setupPythonObject():
     OC_PythonObject = objc.lookUpClass("OC_PythonObject")
     kOP_GLOBAL_EXT=13
     kOP_FLOAT_STR=14
 
-    kKIND = NSString.stringWithString_(u"kind")
-    kFUNC = NSString.stringWithString_(u"func")
-    kARGS = NSString.stringWithString_(u"args")
-    kLIST = NSString.stringWithString_(u"list")
-    kDICT = NSString.stringWithString_(u"dict")
-    kSTATE = NSString.stringWithString_(u"state")
-    kCLASS = NSString.stringWithString_(u"class")
-    kVALUE = NSString.stringWithString_(u"value")
-    kNAME = NSString.stringWithString_(u"name")
-    kMODULE = NSString.stringWithString_(u"module")
-    kCODE = NSString.stringWithString_(u"code")
+    kKIND = NSString.stringWithString_("kind")
+    kFUNC = NSString.stringWithString_("func")
+    kARGS = NSString.stringWithString_("args")
+    kLIST = NSString.stringWithString_("list")
+    kDICT = NSString.stringWithString_("dict")
+    kSTATE = NSString.stringWithString_("state")
+    kCLASS = NSString.stringWithString_("class")
+    kVALUE = NSString.stringWithString_("value")
+    kNAME = NSString.stringWithString_("name")
+    kMODULE = NSString.stringWithString_("module")
+    kCODE = NSString.stringWithString_("code")
 
     class _EmptyClass:
         pass
         def save_long(coder, obj):
             if coder.allowsKeyedCoding():
                 coder.encodeInt_forKey_(kOP_LONG, kKIND)
-                coder.encodeObject_forKey_(unicode(repr(obj)), kVALUE)
+                coder.encodeObject_forKey_(asunicode(repr(obj)), kVALUE)
             else:
                 coder.__pyobjc__encodeInt_(kOP_LONG)
-                coder.encodeObject_(unicode(repr(obj)))
+                coder.encodeObject_(asunicode(repr(obj)))
 
         encode_dispatch[long] = save_long
 
         def save_int(coder, obj):
             if coder.allowsKeyedCoding():
                 coder.encodeInt_forKey_(kOP_LONG, kKIND)
-                coder.encodeObject_forKey_(unicode(repr(obj)), kVALUE)
+                coder.encodeObject_forKey_(repr(obj), kVALUE)
             else:
                 coder.__pyobjc__encodeInt_(kOP_LONG)
-                coder.encodeObject_(unicode(repr(obj)))
+                coder.encodeObject_(repr(obj))
         encode_dispatch[int] = save_int
 
     def save_float(coder, obj):
         # 100% reliable round-trips.
         if coder.allowsKeyedCoding():
             coder.encodeInt_forKey_(kOP_FLOAT_STR, kKIND)
-            coder.encodeObject_forKey_(unicode(repr(obj)), kVALUE)
+            coder.encodeObject_forKey_(asunicode(repr(obj)), kVALUE)
         else:
             coder.__pyobjc__encodeInt_(kOP_FLOAT_STR)
-            coder.encodeObject_(unicode(repr(obj)))
+            coder.encodeObject_(asunicode(repr(obj)))
         #coder.encodeDouble_forKey_(obj, kVALUE)
     encode_dispatch[float] = save_float
 
                     "Can't pickle %r: it's not the same object as %s.%s" %
                     (obj, module, name))
 
-        code = copy_reg._extension_registry.get((module, name))
+        code = copyreg._extension_registry.get((module, name))
 
         if coder.allowsKeyedCoding():
             if code:
 
             else:
                 coder.encodeInt_forKey_(kOP_GLOBAL, kKIND)
-                coder.encodeObject_forKey_(unicode(module), kMODULE)
-                coder.encodeObject_forKey_(unicode(name), kNAME)
+                coder.encodeObject_forKey_(asunicode(module), kMODULE)
+                coder.encodeObject_forKey_(asunicode(name), kNAME)
 
         else:
             if code:
 
             else:
                 coder.__pyobjc__encodeInt_(kOP_GLOBAL)
-                coder.encodeObject_(unicode(module))
-                coder.encodeObject_(unicode(name))
+                coder.encodeObject_(asunicode(module))
+                coder.encodeObject_(asunicode(name))
 
     if sys.version_info[0] == 2:
         encode_dispatch[ClassType] = save_global
         else:
             code = coder.__pyobjc__decodeInt()
         nil = []
-        obj = copy_reg._extension_cache.get(code, nil)
+        obj = copyreg._extension_cache.get(code, nil)
         if obj is not nil:
             return obj
-        key = copy_reg._inverted_registry.get(code)
+        key = copyreg._inverted_registry.get(code)
         if not key:
             raise ValueError("unregistered extension code %d" % code)
 
         if not instantiated:
             try:
                 value = cls(*initargs)
-            except TypeError, err:
-                raise TypeError, "in constructor for %s: %s" % (
-                    cls.__name__, str(err)), sys.exc_info()[2]
+            except TypeError as err:
+                raise TypeError("in constructor for %s: %s" % (
+                    cls.__name__, str(err)), sys.exc_info()[2])
 
             
         # We now have the object, but haven't set the correct
         if state:
             try:
                 inst_dict = value.__dict__
-                for k, v in state.iteritems():
+                for k, v in state.items():
                     if type(k) == str:
                         inst_dict[intern(k)] = v
                     else:
             try:
                 inst_dict = value.__dict__
 
-                for k, v in state.iteritems():
+                for k, v in state.items():
                     if type(k) == str:
                         inst_dict[intern(k)] = v
                     else:
             save_global(coder, self)
             return
 
-        # Check copy_reg.dispatch_table
-        reduce = copy_reg.dispatch_table.get(t)
+        # Check copyreg.dispatch_table
+        reduce = copyreg.dispatch_table.get(t)
         if reduce is not None:
             rv = reduce(self)
 

pyobjc-core/Lib/objc/_pythonify.py

         # one part of the effect of __slots__: don't allow setting of attributes.
         def __setattr__(self, attr, value):
             if attr != '__pyobjc_object__':
-                raise AttributeError, "'%s' object has no attribute '%s')"%(self.__class__.__name__, attr)
+                raise AttributeError("'%s' object has no attribute '%s')"%(self.__class__.__name__, attr))
             self.__dict__['__pyobjc_object__'] = value
 
         def __reduce__(self):
     class OC_PythonLong(int):
 
         def __new__(cls, obj, value):
-            self = long.__new__(cls, value)
+            self = int.__new__(cls, value)
             self.__pyobjc_object__ = obj
             return self
 
         # one part of the effect of __slots__: don't allow setting of attributes.
         def __setattr__(self, attr, value):
             if attr != '__pyobjc_object__':
-                raise AttributeError, "'%s' object has no attribute '%s')"%(self.__class__.__name__, attr)
+                raise AttributeError("'%s' object has no attribute '%s')"%(self.__class__.__name__, attr))
             self.__dict__['__pyobjc_object__'] = value
 
         def __reduce__(self):
-            return (long, (long(self),))
+            return (int, (int(self),))
 
 NSNumber = _objc.lookUpClass('NSNumber')
 NSDecimalNumber = _objc.lookUpClass('NSDecimalNumber')

pyobjc-core/PyObjCTest/test_archive_python.py

 
             self.assertEqual(len(v), 1)
             self.assertEqual(dir(v[0]), dir(i))
-            self.assertEqual(v[0].attr.keys(), [1])
+            self.assertEqual(list(v[0].attr.keys()), [1])
             self.assertIs(v[0].attr[1], v)
 
             buf = self.archiverClass.archivedDataWithRootObject_(d)

pyobjc-core/PyObjCTest/test_arrays.py

 """
 from PyObjCTools.TestSupport import *
 import objc
+from objc._convenience import strstr
 import array
 from PyObjCTest.arrays import *
 from PyObjCTest.fnd import NSObject
         v = o.arrayOf4Ints_([0, 1, 2, 3])
         self.assertEqual(v, [0, 1, 2, 3])
 
-        a = array.array('i', [9, 10, 11, 12])
+        a = array.array(strstr('i'), [9, 10, 11, 12])
         v = o.arrayOf4Ints_(a)
         self.assertEqual(v, [9, 10, 11, 12])
 
         v = o.arrayOf4IntsIn_([0, 1, 2, 3])
         self.assertEqual(v, [0, 1, 2, 3])
 
-        a = array.array('i', [9, 10, 11, 12])
+        a = array.array(strstr('i'), [9, 10, 11, 12])
         v = o.arrayOf4IntsIn_(a)
         self.assertEqual(v, [9, 10, 11, 12])
 
         self.assertEqual(v, (0, 1, 2, 3))
         self.assertEqual(r, (0+42, 1+42, 2+42, 3+42))
 
-        a = array.array('i', [9, 10, 11, 12])
+        a = array.array(strstr('i'), [9, 10, 11, 12])
         v, r = o.arrayOf4IntsInOut_(a)
         self.assertEqual(v, [9, 10, 11, 12])
         self.assertIs(r, a)
         v = o.arrayOf4IntsOut_(None)
         self.assertEqual(v, (99, 100, 102, 110))
 
-        a = array.array('i', [9, 10, 11, 12])
+        a = array.array(strstr('i'), [9, 10, 11, 12])
         v = o.arrayOf4IntsOut_(a)
         self.assertIs(a, v)
         self.assertEqual(a[0], 99)
         v = o.arrayOf4Structs_([(0, 1), (10, 20), (-10, -20), (7, 8)])
         self.assertEqual(v, [(0, 1), (10, 20), (-10, -20), (7, 8)])
 
-        a = array.array('i', [9, 10, 11, 12, -1, -2, -3, -4])
+        a = array.array(strstr('i'), [9, 10, 11, 12, -1, -2, -3, -4])
         v = o.arrayOf4Structs_(a)
         self.assertEqual(v, [(9, 10), (11, 12), (-1, -2), (-3, -4)])
 
         v = o.arrayOf4StructsIn_([(0, 1), (2, 3), (-1, -2), (-3, -4)])
         self.assertEqual(v, [(0, 1), (2, 3), (-1, -2), (-3, -4)])
 
-        a = array.array('i', [9, 10, 11, 12, -1, -2, -3, -4])
+        a = array.array(strstr('i'), [9, 10, 11, 12, -1, -2, -3, -4])
         v = o.arrayOf4StructsIn_(a)
         self.assertEqual(v, [(9, 10), (11, 12), (-1, -2), (-3, -4)])
 
         self.assertEqual(v, ((0,1), (2,3), (4,5), (6,7)))
         self.assertEqual(r, ((0+42, 1-42), (2+42,3-42), (4+42, 5-42), (6+42, 7-42)))
 
-        a = array.array('i', [9, 10, 11, 12, 14, 15, 16, 17])
+        a = array.array(strstr('i'), [9, 10, 11, 12, 14, 15, 16, 17])
         v, r = o.arrayOf4StructsInOut_(a)
         self.assertEqual(v, [(9, 10), (11, 12), (14, 15), (16, 17)])
         self.assertIs(r, a)
         v = o.arrayOf4StructsOut_(None)
         self.assertEqual(list(v), [ (1+i*i, -4 - i*i*i) for i in range(4) ])
 
-        a = array.array('i', [0]*8)
+        a = array.array(strstr('i'), [0]*8)
         v = o.arrayOf4StructsOut_(a)
         self.assertIs(a, v)
         l = []

pyobjc-core/PyObjCTest/test_conversion.py

 from .testbndl import DBL_MAX, DBL_MIN, DBL_EPSILON
 from .testbndl import FLT_MAX, FLT_MIN, FLT_EPSILON
 import objc
+from objc._convenience import strstr
 import array, sys
 
 
         self.assertRaises(ValueError, carrayMaker, objc._C_SHT, ["a", "b"], 1)
 
     def testShortArray(self):
-        arr = array.array('h', [1,2,3,4,5])
-        arr2 = array.array('f', [1,2,3,4,5])
+        arr = array.array(strstr('h'), [1,2,3,4,5])
+        arr2 = array.array(strstr('f'), [1,2,3,4,5])
 
         res = carrayMaker(objc._C_SHT, arr, None)
         self.assertEqual(res, tuple(arr))
         self.assertRaises(ValueError, carrayMaker, objc._C_INT, ["a", "b"], 1)
 
     def testIntArray(self):
-        arr = array.array('i', [1,2,3,4,5])
-        arr2 = array.array('f', [1,2,3,4,5])
-        arr3 = array.array('h', [1,2,3,4,5])
+        arr = array.array(strstr('i'), [1,2,3,4,5])
+        arr2 = array.array(strstr('f'), [1,2,3,4,5])
+        arr3 = array.array(strstr('h'), [1,2,3,4,5])
 
         res = carrayMaker(objc._C_INT, arr, None)
         self.assertEqual(res, tuple(arr))
         self.assertRaises(ValueError, carrayMaker, objc._C_INT, ["a", "b"], 1)
 
     def testFloatArray(self):
-        arr = array.array('f', [1.5,2.5,3.5,4.5,5.5])
-        arr2 = array.array('i', [1,2,3,4,5])
+        arr = array.array(strstr('f'), [1.5,2.5,3.5,4.5,5.5])
+        arr2 = array.array(strstr('i'), [1,2,3,4,5])
 
         res = carrayMaker(objc._C_FLT, arr, None)
         self.assertEqual(res, tuple(arr))
         self.assertRaises(TypeError, carrayMaker, b'{Point=ff}', arr2, None)
 
     def testPointArray(self):
-        arr = array.array('f', [
+        arr = array.array(strstr('f'), [
             1.0, 1.5,
             2.0, 2.5,
             3.0, 3.5,
             5.0, 5.5])
         lst = ((1.0, 1.5), (2.0, 2.5), (3.0, 3.5), (4.0, 4.5), (5.0, 5.5))
 
-        arr2 = array.array('i', [
+        arr2 = array.array(strstr('i'), [
             1, 1,
             2, 2,
             3, 3,
         self.assertRaises(ValueError, carrayMaker, b'{Point=ff}', arr2, None)
 
     def testRectArray(self):
-        arr = array.array('f', [
+        arr = array.array(strstr('f'), [
             1.0, 1.5, -1.0, -1.5,
             2.0, 2.5, -2.0, -2.5,
             3.0, 3.5, -3.0, -3.5,
                 ((5.0, 5.5),  (-5.0, -5.5)),
             )
 
-        arr2 = array.array('i', [
+        arr2 = array.array(strstr('i'), [
             1, 1, 1, 1,
             2, 2, 2, 2,
             3, 3, 3, 3,
         self.assertRaises(ValueError, carrayMaker, b'{Rect={P=ff}{S=ff}}', arr2, None)
 
     def testMixedArray(self):
-        arr = array.array('f', [
+        arr = array.array(strstr('f'), [
             1.0, 1.5, -1.0, -1.5,
             2.0, 2.5, -2.0, -2.5,
             3.0, 3.5, -3.0, -3.5,

pyobjc-core/PyObjCTest/test_ctests.py

 unitest.m file as its methods.
 """
 import sys, platform
+from objc._convenience import exec_
 from PyObjCTools.TestSupport import *
 from  PyObjCTest import ctests
 
 
         return test_CheckNSInvoke
 
-    exec  """\
+    exec_("""\
 def test_%s(self):
     meth()
-"""%(name,) in result
+"""%(name,), result)
 
     return result['test_%s'%(name,)]
 

pyobjc-core/PyObjCTest/test_exceptions.py

 # XXX: we should centralize all exception handling tests into this file, this
 #      is now mostly used to check general unicode support in exceptions.
 #
+from __future__ import unicode_literals
+
 from PyObjCTest.exceptions import *
 
 from PyObjCTools.TestSupport import *
 
         except objc.error as e:
             self.assertEqual(str(e), 'SimpleException - hello world')
-            self.assertEqual(e._pyobjc_info_['name'], u'SimpleException')
-            self.assertEqual(e._pyobjc_info_['reason'], u'hello world')
+            self.assertEqual(e._pyobjc_info_['name'], 'SimpleException')
+            self.assertEqual(e._pyobjc_info_['reason'], 'hello world')
             self.assertEqual(e._pyobjc_info_['userInfo'], None)
 
     def testSimpleWithInfo(self):
 
         except objc.error as e:
             self.assertEqual(str(e), 'InfoException - Reason string')
-            self.assertEqual(e._pyobjc_info_['name'], u'InfoException')
-            self.assertEqual(e._pyobjc_info_['reason'], u'Reason string')
+            self.assertEqual(e._pyobjc_info_['name'], 'InfoException')
+            self.assertEqual(e._pyobjc_info_['reason'], 'Reason string')
             self.assertEqual(e._pyobjc_info_['userInfo'], {
                 'key1': 'value1',
                 'key2': 'value2',
 
         except objc.error as e:
             if sys.version_info[0] == 2:
-                self.assertEqual(str(e), u'SimpleException\u1234\u2049 - hello world'.encode('utf-8'))
+                self.assertEqual(str(e), 'SimpleException\u1234\u2049 - hello world'.encode('utf-8'))
             else:
-                self.assertEqual(str(e), u'SimpleException\u1234\u2049 - hello world')
-            self.assertEqual(e._pyobjc_info_['name'], u'SimpleException\u1234\u2049')
-            self.assertEqual(e._pyobjc_info_['reason'], u'hello world')
+                self.assertEqual(str(e), 'SimpleException\u1234\u2049 - hello world')
+            self.assertEqual(e._pyobjc_info_['name'], 'SimpleException\u1234\u2049')
+            self.assertEqual(e._pyobjc_info_['reason'], 'hello world')
             self.assertEqual(e._pyobjc_info_['userInfo'], None)
 
     def testUnicodeReason(self):
 
         except objc.error as e:
             if sys.version_info[0] == 2:
-                self.assertEqual(str(e), u'SimpleException - hello world\u1234\u2049'.encode('utf-8'))
+                self.assertEqual(str(e), 'SimpleException - hello world\u1234\u2049'.encode('utf-8'))
             else:
-                self.assertEqual(str(e), u'SimpleException - hello world\u1234\u2049')
-            self.assertEqual(e._pyobjc_info_['name'], u'SimpleException')
-            self.assertEqual(e._pyobjc_info_['reason'], u'hello world\u1234\u2049')
+                self.assertEqual(str(e), 'SimpleException - hello world\u1234\u2049')
+            self.assertEqual(e._pyobjc_info_['name'], 'SimpleException')
+            self.assertEqual(e._pyobjc_info_['reason'], 'hello world\u1234\u2049')
             self.assertEqual(e._pyobjc_info_['userInfo'], None)
 
     def testUnicodeWithInfo(self):
 
         except objc.error as e:
             if sys.version_info[0] == 2:
-                self.assertEqual(str(e), u'InfoException\u1234\u2049 - Reason string\u1234\u2049'.encode('utf-8'))
+                self.assertEqual(str(e), 'InfoException\u1234\u2049 - Reason string\u1234\u2049'.encode('utf-8'))
             else:
-                self.assertEqual(str(e), u'InfoException\u1234\u2049 - Reason string\u1234\u2049')
-            self.assertEqual(e._pyobjc_info_['name'], u'InfoException\u1234\u2049')
-            self.assertEqual(e._pyobjc_info_['reason'], u'Reason string\u1234\u2049')
+                self.assertEqual(str(e), 'InfoException\u1234\u2049 - Reason string\u1234\u2049')
+            self.assertEqual(e._pyobjc_info_['name'], 'InfoException\u1234\u2049')
+            self.assertEqual(e._pyobjc_info_['reason'], 'Reason string\u1234\u2049')
             self.assertEqual(e._pyobjc_info_['userInfo'], {
-                u'key1\u1234\u2049': u'value1\u1234\u2049',
-                u'key2\u1234\u2049': u'value2\u1234\u2049',
+                'key1\u1234\u2049': 'value1\u1234\u2049',
+                'key2\u1234\u2049': 'value2\u1234\u2049',
             })
 
     def testRaisingStringsInObjectiveC(self):
             o.raiseAString()
 
         except objc.error as e:
-            self.assertEqual(e._pyobjc_exc_, u"thrown string")
+            self.assertEqual(e._pyobjc_exc_, "thrown string")
 
 if __name__ == "__main__":
     main()

pyobjc-core/PyObjCTest/test_fsref.py

+from __future__ import unicode_literals
+
 from PyObjCTools.TestSupport import *
+from objc._convenience import unicode
 import objc
 
 from PyObjCTest.fsref import *
 
     def testResult(self):
         o = OC_TestFSRefHelper.alloc().init()
-        ref = o.fsrefForPath_(u"/Library")
+        ref = o.fsrefForPath_("/Library")
         self.assertIsInstance(ref, objc.FSRef)
 
         self.assertIsInstance(ref.data, bytes)
 
     def testArg(self):
         o = OC_TestFSRefHelper.alloc().init()
-        ref = o.fsrefForPath_(u"/Library")
+        ref = o.fsrefForPath_("/Library")
         self.assertIsInstance(ref, objc.FSRef)
 
         p = o.stringForFSRef_(ref)
         self.assertIsInstance(p, unicode)
-        self.assertEqual(p, u"/Library")
+        self.assertEqual(p, "/Library")
 
     def testInput(self):
         o = OC_TestFSRefHelper.alloc().init()
-        ref = o.fsrefForPath_(u"/Library")
+        ref = o.fsrefForPath_("/Library")
         self.assertIsInstance(ref, objc.FSRef)
 
         p = o.pathForFSRef_(ref)
         self.assertIsInstance(p, unicode)
-        self.assertEqual(p, u"/Library")
+        self.assertEqual(p, "/Library")
 
     def testOutput(self):
         o = OC_TestFSRefHelper.alloc().init()
-        ref = o.getFSRef_forPath_(None, u"/Library")
+        ref = o.getFSRef_forPath_(None, "/Library")
         self.assertIsInstance(ref, objc.FSRef)
 
         # Verify the fsref contents:
         p = o.stringForFSRef_(ref)
         self.assertIsInstance(p, unicode)
-        self.assertEqual(p, u"/Library")
+        self.assertEqual(p, "/Library")
 
 
 if __name__ == "__main__":

pyobjc-core/PyObjCTest/test_identity.py

 #   to plists, ...)
 # - Implement the required functionality
 
+from __future__ import unicode_literals
+
 import sys, os
 import objc
 from PyObjCTest.identity import *
 from PyObjCTools.TestSupport import *
+from objc._convenience import unicode
 
 class TestPythonRoundTrip (TestCase):
     # TODO: verify
 
         container = OC_TestIdentity.alloc().init()
 
-        for v in ( u"Hello world", "Hello world" ):
+        for v in ( "Hello world", b"Hello world" ):
             container.setStoredObject_(v)
             self.assertTrue(v is container.storedObject(), repr(v))
 
         # to fix (but not now)
         container = OC_TestIdentity.alloc().init()
 
-        for v in (99999, 99999L, 10.0):
+        for v in (99999, 10.0):
             container.setStoredObject_(v)
             self.assertTrue(v is container.storedObject, repr(v))
 
         self.assertTrue(container.isSameObjectAsStored_(v), repr(v))
         self.assertTrue(isinstance(v, objc.formal_protocol))
 
-    if sys.maxint < 2 ** 32:
+    if sys.maxsize < 2 ** 32:
         def testObject(self):
             container = OC_TestIdentity.alloc().init()
             cls = objc.lookUpClass("Object")
         v = container.storedObject()
         self.assertTrue(container.isSameObjectAsStored_(v), repr(v))
 
-        if sys.maxint < 2 ** 32:
-            container.setStoredObjectToLongLong_(sys.maxint * 2)
+        if sys.maxsize < 2 ** 32:
+            container.setStoredObjectToLongLong_(sys.maxsize * 2)
             v = container.storedObject()
             self.assertTrue(container.isSameObjectAsStored_(v), repr(v))
 
-        container.setStoredObjectToLongLong_(-sys.maxint)
+        container.setStoredObjectToLongLong_(-sys.maxsize)
         v = container.storedObject()
         self.assertTrue(container.isSameObjectAsStored_(v), repr(v))
 
-        container.setStoredObjectToUnsignedLongLong_(sys.maxint * 2)
+        container.setStoredObjectToUnsignedLongLong_(sys.maxsize * 2)
         v = container.storedObject()
         self.assertTrue(container.isSameObjectAsStored_(v), repr(v))
 
         v = container.storedObject()
         self.assertFetchingTwice(container, "protocol")
 
-    if sys.maxint < 2**32:
+    if sys.maxsize < 2**32:
         def testObject(self):
             container = OC_TestIdentity.alloc().init()
 
         container.setStoredObjectToUnsignedInteger_(40)
         self.assertFetchingTwice(container, "unsigned int 40")
 
-        container.setStoredObjectToUnsignedInteger_(sys.maxint * 2)
-        self.assertFetchingTwice(container, "unsigned int sys.maxint*2")
+        container.setStoredObjectToUnsignedInteger_(sys.maxsize * 2)
+        self.assertFetchingTwice(container, "unsigned int sys.maxsize*2")
 
-        container.setStoredObjectToLongLong_(sys.maxint * 2)
-        self.assertFetchingTwice(container, "long long sys.maxint*2")
+        container.setStoredObjectToLongLong_(sys.maxsize * 2)
+        self.assertFetchingTwice(container, "long long sys.maxsize*2")
 
-        container.setStoredObjectToLongLong_(-sys.maxint)
-        self.assertFetchingTwice(container, "long long -sys.maxint")
+        container.setStoredObjectToLongLong_(-sys.maxsize)
+        self.assertFetchingTwice(container, "long long -sys.maxsize")
 
-        container.setStoredObjectToUnsignedLongLong_(sys.maxint * 2)
-        self.assertFetchingTwice(container, "unsigned long long sys.maxint*2")
+        container.setStoredObjectToUnsignedLongLong_(sys.maxsize * 2)
+        self.assertFetchingTwice(container, "unsigned long long sys.maxsize*2")
 
         container.setStoredObjectToFloat_(10.0)
         self.assertFetchingTwice(container, "float")
         # These get converted, not proxied
         container = OC_TestIdentity.alloc().init()
 
-        for v in ("hello world", u"a unicode string"):
+        for v in (b"hello world", "a unicode string"):
             container.setStoredObject_(v)
 
             self.assertTrue(container.isSameObjectAsStored_(v), repr(v))
         # These get converted, not proxied
         container = OC_TestIdentity.alloc().init()
 
-        for v in (1, 666666, 1L, 66666L, 1.0,):
+        for v in (1, 666666, 1.0,):
             container.setStoredObject_(v)
 
             self.assertTrue(container.isSameObjectAsStored_(v), repr(v))
     def testMakePlist(self):
         container = OC_TestIdentity.alloc().init()
 
-        value = [ 1, 2, 3, [ u"hello", [u"world", (u"in", 9 ) ], True, {u"aap":3}]]
+        value = [ 1, 2, 3, [ "hello", ["world", ("in", 9 ) ], True, {"aap":3}]]
         value.append(value[3])
 
         container.setStoredObject_(value)
-        container.writeStoredObjectToFile_(u"/tmp/pyPyObjCTest.identity")
+        container.writeStoredObjectToFile_("/tmp/pyPyObjCTest.identity")
 
         value = {
-            u"hello": [ 1, 2, 3],
-            u"world": {
-                u"nl": u"wereld",
-                u"de": u"Welt",
+            "hello": [ 1, 2, 3],
+            "world": {
+                "nl": "wereld",
+                "de": "Welt",
             }
         }
         container.setStoredObject_(value)
-        container.writeStoredObjectToFile_(u"/tmp/pyPyObjCTest.identity")
+        container.writeStoredObjectToFile_("/tmp/pyPyObjCTest.identity")
 
         
 

pyobjc-core/PyObjCTest/test_initialized.py

+from __future__ import unicode_literals
+
 from PyObjCTools.TestSupport import *
 from PyObjCTest.initialize import OC_TestInitialize
 
         self.assertEqual(v, start)
 
         s = o.dummy()
-        self.assertEqual(s, u"hello")
+        self.assertEqual(s, "hello")
         v = OC_TestInitialize.numUninitialized()
         self.assertEqual(v, start)
 
         self.assertEqual(v, start)
 
         s = o.dummy()
-        self.assertEqual(s, u"hello")
+        self.assertEqual(s, "hello")
         v = OC_TestInitialize.numUninitialized()
         self.assertEqual(v, start)
 
         self.assertEqual(v, start)
 
         s = o.dummy()
-        self.assertEqual(s, u"hello")
+        self.assertEqual(s, "hello")
         v = OC_TestInitialize.numUninitialized()
         self.assertEqual(v, start)
 
         self.assertEqual(v, start)
 
         s = o.dummy()
-        self.assertEqual(s, u"hello")
+        self.assertEqual(s, "hello")
         v = OC_TestInitialize.numUninitialized()
         self.assertEqual(v, start)
 

pyobjc-core/PyObjCTest/test_ivar.py

+from __future__ import unicode_literals
+
 from PyObjCTools.TestSupport import *
 
 import objc
         self.assertIs(self.object.idVar, o)
         self.assertIs(self.object.idVar2, o)
 
-        self.object.idVar = u"hello"
-        self.assertEqual(self.object.idVar, u"hello")
+        self.object.idVar = "hello"
+        self.assertEqual(self.object.idVar, "hello")
 
     def testInt(self):
         # Check that we can set and query attributes of type 'int'
 
         # Can't rely on this for doubles...
         #self.assertEqual(self.object.doubleVar, 0.0)
-        self.assertRaises(ValueError, lambda x: setattr(self.object, 'doubleVar', x), u"h")
+        self.assertRaises(ValueError, lambda x: setattr(self.object, 'doubleVar', x), "h")
         self.object.doubleVar = 42.0
         self.assertAlmostEqual(self.object.doubleVar, 42.0)
 

pyobjc-core/PyObjCTest/test_keyvalue.py

 NOTE: Testcases here should be synchronized with the Key-Value Coding tests
 in PyObjCTools.test.test_keyvalue and Foundation.test.test_keyvalue.
 """
+from __future__ import unicode_literals
+
 import objc
 from PyObjCTools.TestSupport import *
 from PyObjCTest.fnd import *
 class KeyValueClass2 (object):
     def __init__(self):
         self.key3 = 3
-        self._key4 = u"4"
-        self._pythonConvention = u'BAD'
-        self._pythonConventionValue = u'GOOD'
-        self.__private = u'private'
+        self._key4 = "4"
+        self._pythonConvention = 'BAD'
+        self._pythonConventionValue = 'GOOD'
+        self.__private = 'private'
 
     def addMultiple(self):
         self.multiple = KeyValueClass2()
         self.multiple.level2 = KeyValueClass2()
         self.multiple.level2.level3 = KeyValueClass2()
-        self.multiple.level2.level3.keyA = u"hello"
-        self.multiple.level2.level3.keyB = u"world"
+        self.multiple.level2.level3.keyA = "hello"
+        self.multiple.level2.level3.keyB = "world"
 
     def pythonConvention(self):
         return self._pythonConventionValue
     __slots__ = ('foo', )
 
     def __init__(self):
-        self.foo = u"foobar"
+        self.foo = "foobar"