Commits

Ronald Oussoren committed 8be7da4

Much improved test coverage for the unittest helpers

  • Participants
  • Parent commits 9033b99

Comments (0)

Files changed (8)

File pyobjc-core/Doc/api/module-PyObjCTools.TestSupport.rst

       If *retained* is true the function stores the function reference beyond
       the end of the function call.
 
+   .. method:: assertResultsFunction(method, sel_type, [, message])
+
+      Assert that the result is a function with a specific type signature.
+
    .. method:: assertResultIsBlock(method, sel_type[, message])
 
       Assert that the result is a block with a specific type signature.

File pyobjc-core/Lib/PyObjCTools/TestSupport.py

 # Have a way to disable the autorelease pool behaviour
 _usepool = not _os.environ.get('PYOBJC_NO_AUTORELEASE')
 
-def _typemap(tp):
+def _typemap(tp): # XXX: Is this needed?
     if tp is None: return None
     return tp.replace(b'_NSRect', b'CGRect').replace(b'_NSPoint', b'CGPoint').replace(b'_NSSize', b'CGSize')
 
     _typealias[objc._C_LNG_LNG] = objc._C_LNG
     _typealias[objc._C_ULNG_LNG] = objc._C_ULNG
 
-else:
+else: # pragma: no cover (32-bit)
     _typealias[objc._C_LNG] = objc._C_INT
     _typealias[objc._C_ULNG] = objc._C_UINT
 
         else:
             offset = 0
         info = method.__metadata__()
-        if not info.get('arguments', {}).get(argno+offset, {}).get('c_array_delimited_by_null'):
+        try:
+            if not info['arguments'][argno+offset].get('c_array_delimited_by_null'):
+                self.fail(message or "argument %d of %r is not a null-terminated array"%(argno, method))
+        except (KeyError, IndexError):
             self.fail(message or "argument %d of %r is not a null-terminated array"%(argno, method))
 
     def assertArgIsVariableSize(self, method, argno, message = None):
         else:
             offset = 0
         info = method.__metadata__()
-        if not info['arguments'][argno+offset].get('c_array_of_variable_length'):
-            self.fail(message or "argument %d of %r is not a variable sized array"%(method,))
+        try:
+            if not info['arguments'][argno+offset].get('c_array_of_variable_length'):
+                self.fail(message or "argument %d of %r is not a variable sized array"%(argno, method,))
+        except (KeyError, IndexError):
+            self.fail(message or "argument %d of %r is not a variable sized array"%(argno, method,))
 
     def assertResultIsVariableSize(self, method, message = None):
         info = method.__metadata__()
-        if not info['retval'].get('c_array_of_variable_length'):
+        if not info.get('retval', {}).get('c_array_of_variable_length', False):
             self.fail(message or "result of %r is not a variable sized array"%(argno, method))
 
     def assertArgSizeInResult(self, method, argno, message = None):
         else:
             offset = 0
         info = method.__metadata__()
-        if not info['arguments'][argno+offset].get('c_array_length_in_result'):
+        try:
+            if not info['arguments'][argno+offset].get('c_array_length_in_result'):
+                self.fail(message or "argument %d of %r does not have size in result"%(argno, method))
+        except (KeyError, IndexError):
             self.fail(message or "argument %d of %r does not have size in result"%(argno, method))
 
     def assertArgIsPrintf(self, method, argno, message = None):
         if not info.get('variadic'):
             self.fail(message or "%r is not a variadic function"%(method,))
 
-        if not info['arguments'][argno+offset].get('printf_format'):
+        try:
+            if not info['arguments'][argno+offset].get('printf_format'):
+                self.fail(message or "%r argument %d is not a printf format string"%(method, argno))
+        except (KeyError, IndexError):
             self.fail(message or "%r argument %d is not a printf format string"%(method, argno))
 
     def assertArgIsCFRetained(self, method, argno, message = None):
         else:
             offset = 0
         info = method.__metadata__()
-        if not info['arguments'][argno+offset]['already_cfretained']:
+
+        try:
+            if not info['arguments'][argno+offset]['already_cfretained']:
+                self.fail(message or "%r is not cfretained"%(method,))
+        except (KeyError, IndexError):
             self.fail(message or "%r is not cfretained"%(method,))
 
     def assertArgIsNotCFRetained(self, method, argno, message = None):
         else:
             offset = 0
         info = method.__metadata__()
-        if info['arguments'][argno+offset]['already_cfretained']:
-            self.fail(message or "%r is cfretained"%(method,))
+        try:
+            if info['arguments'][argno+offset]['already_cfretained']:
+                self.fail(message or "%r is cfretained"%(method,))
+        except (KeyError, IndexError):
+            pass
 
     def assertResultIsCFRetained(self, method, message = None):
         info = method.__metadata__()
-        if not info['retval']['already_cfretained']:
+
+        if not info.get('retval', {}).get('already_cfretained', False):
             self.fail(message or "%r is not cfretained"%(method,))
 
     def assertResultIsNotCFRetained(self, method, message = None):
         info = method.__metadata__()
-        if info['retval']['already_cfretained']:
+        if info.get('retval', {}).get('already_cfretained', False):
             self.fail(message or "%r is cfretained"%(method,))
 
+    def assertArgIsRetained(self, method, argno, message = None):
+        if isinstance(method, objc.selector):
+            offset = 2
+        else:
+            offset = 0
+        info = method.__metadata__()
+
+        try:
+            if not info['arguments'][argno+offset]['already_retained']:
+                self.fail(message or "%r is not retained"%(method,))
+        except (KeyError, IndexError):
+            self.fail(message or "%r is not retained"%(method,))
+
+    def assertArgIsNotRetained(self, method, argno, message = None):
+        if isinstance(method, objc.selector):
+            offset = 2
+        else:
+            offset = 0
+        info = method.__metadata__()
+        try:
+            if info['arguments'][argno+offset]['already_retained']:
+                self.fail(message or "%r is retained"%(method,))
+        except (KeyError, IndexError):
+            pass
+
     def assertResultIsRetained(self, method, message = None):
         info = method.__metadata__()
-        if not info['retval']['already_retained']:
+        if not info.get('retval', {}).get('already_retained', False):
             self.fail(message or "%r is not retained"%(method,))
 
     def assertResultIsNotRetained(self, method, message = None):
         info = method.__metadata__()
-        if info['retval']['already_retained']:
+        if info.get('retval', {}).get('already_retained', False):
             self.fail(message or "%r is retained"%(method,))
 
     def assertResultHasType(self, method, tp, message=None):
         info = method.__metadata__()
-        type = info['retval']['type']
+        type = info.get('retval').get('type', b'v')
         if type != tp and _typemap(type) != _typemap(tp) \
                 and _typealias.get(type, type) != _typealias.get(tp, tp):
             self.fail(message or "result of %r is not of type %r, but %r"%(
         else:
             offset = 0
         info = method.__metadata__()
-        type = info['arguments'][argno+offset]['type']
+        try:
+            i = info['arguments'][argno+offset]
+
+        except (KeyError, IndexError):
+            self.fail(message or "arg %d of %s has no metadata (or doesn't exist)"%(argno, method))
+
+        else:
+            type = i.get('type', b'@')
+
         if type != tp and _typemap(type) != _typemap(tp) \
                 and _typealias.get(type, type) != _typealias.get(tp, tp):
             self.fail(message or "arg %d of %s is not of type %r, but %r"%(
                 argno, method, tp, type))
 
+
     def assertArgIsFunction(self, method, argno, sel_type, retained, message=None):
         if isinstance(method, objc.selector):
             offset = 2
         else:
             offset = 0
         info = method.__metadata__()
-        type = info['arguments'][argno+offset]['type']
+
+        try:
+            i = info['arguments'][argno+offset]
+        except (KeyError, IndexError):
+            self.fail(message or "arg %d of %s has no metadata (or doesn't exist)"%(argno, method))
+
+        else:
+            type = i.get('type', b'@')
+
         if type != b'^?':
             self.fail(message or "arg %d of %s is not of type function_pointer"%(
                 argno, method))
 
-        st = info['arguments'][argno+offset].get('callable')
+        st = i.get('callable')
         if st is None:
             self.fail(message or "arg %d of %s is not of type function_pointer"%(
                 argno, method))
 
-        iface = st['retval']['type']
-        for a in st['arguments']:
-            iface += a['type']
+        try:
+            iface = st['retval']['type']
+            for a in st['arguments']:
+                iface += a['type']
+        except KeyError:
+            self.fail(message or "arg %d of %s is a function pointer with incomplete type information"%(argno, method))
 
         if iface != sel_type:
             self.fail(message or "arg %d of %s is not a function_pointer with type %r, but %r"%(argno, method, sel_type, iface))
 
 
-        st = info['arguments'][argno+offset]['callable_retained']
+        st = info['arguments'][argno+offset].get('callable_retained', False)
         if bool(st) != bool(retained):
             self.fail(message or "arg %d of %s; retained: %r, expected: %r"%(
                 argno, method, st, retained))
 
+    def assertResultIsFunction(self, method, sel_type, message=None):
+        info = method.__metadata__()
+
+        try:
+            i = info['retval']
+        except (KeyError, IndexError):
+            self.fail(message or "result of %s has no metadata (or doesn't exist)"%(method,))
+
+        else:
+            type = i.get('type', b'@')
+
+        if type != b'^?':
+            self.fail(message or "result of %s is not of type function_pointer"%(
+                method, ))
+
+        st = i.get('callable')
+        if st is None:
+            self.fail(message or "result of %s is not of type function_pointer"%(
+                method, ))
+
+        try:
+            iface = st['retval']['type']
+            for a in st['arguments']:
+                iface += a['type']
+        except KeyError:
+            self.fail(message or "result of %s is a function pointer with incomplete type information"%(method,))
+
+        if iface != sel_type:
+            self.fail(message or "result of %s is not a function_pointer with type %r, but %r"%(method, sel_type, iface))
+
+
     def assertArgIsBlock(self, method, argno, sel_type, message=None):
         if isinstance(method, objc.selector):
             offset = 2
         info = method.__metadata__()
         try:
             type = info['arguments'][argno+offset]['type']
-        except IndexError:
+        except (IndexError, KeyError):
             self.fail("arg %d of %s does not exist"%(argno, method))
 
         if type != b'@?':
             self.fail(message or "arg %d of %s is not of type block: no callable"%(
                 argno, method))
 
-        iface = st['retval']['type']
-        if st['arguments'][0]['type'] != b'^v':
-            self.fail(message or "arg %d of %s has an invalid block signature"%(argno, method))
-        for a in st['arguments'][1:]:
-            iface += a['type']
+        try:
+            iface = st['retval']['type']
+            if st['arguments'][0]['type'] != b'^v':
+                self.fail(message or "arg %d of %s has an invalid block signature"%(argno, method))
+            for a in st['arguments'][1:]:
+                iface += a['type']
+        except KeyError:
+            self.fail(message or "result of %s is a block pointer with incomplete type information"%(method,))
 
         if iface != sel_type:
             self.fail(message or "arg %d of %s is not a block with type %r, but %r"%(argno, method, sel_type, iface))
 
     def assertResultIsBlock(self, method, sel_type, message=None):
         info = method.__metadata__()
-        type = info['retval']['type']
-        if type != b'@?':
+
+        try:
+            type = info['retval']['type']
+            if type != b'@?':
+                self.fail(message or "result of %s is not of type block: %s"%(
+                    method, type))
+        except KeyError:
             self.fail(message or "result of %s is not of type block: %s"%(
-                method, type))
+                method, b'v'))
 
         st = info['retval'].get('callable')
         if st is None:
             self.fail(message or "result of %s is not of type block: no callable specified"%(
                 method))
 
-        iface = st['retval']['type']
-        if st['arguments'][0]['type'] != b'^v':
-            self.fail(message or "result %s has an invalid block signature"%(method))
-        for a in st['arguments'][1:]:
-            iface += a['type']
+        try:
+            iface = st['retval']['type']
+            if st['arguments'][0]['type'] != b'^v':
+                self.fail(message or "result %s has an invalid block signature"%(method))
+            for a in st['arguments'][1:]:
+                iface += a['type']
+        except KeyError:
+            self.fail(message or "result of %s is a block pointer with incomplete type information"%(method,))
 
         if iface != sel_type:
             self.fail(message or "result of %s is not a block with type %r, but %r"%(method, sel_type, iface))
         else:
             offset = 0
         info = method.__metadata__()
-        type = info['arguments'][argno+offset]['type']
+        try:
+            i = info['arguments'][argno+offset]
+        except (KeyError, IndexError):
+            self.fail(message or "arg %d of %s has no metadata (or doesn't exist)"%(argno, method))
+        
+        type = i.get('type', b'@')
         if type != objc._C_SEL:
             self.fail(message or "arg %d of %s is not of type SEL"%(
                 argno, method))
 
-        st = info['arguments'][argno+offset].get('sel_of_type')
+        st = i.get('sel_of_type')
         if st != sel_type and _typemap(st) != _typemap(sel_type):
             self.fail(message or "arg %d of %s doesn't have sel_type %r but %r"%(
                 argno, method, sel_type, st))
         else:
             offset = 0
         info = method.__metadata__()
-        cnt = info['arguments'][argno+offset]['c_array_of_fixed_length']
-        if cnt != count:
+        try:
+            cnt = info['arguments'][argno+offset]['c_array_of_fixed_length']
+            if cnt != count:
+                self.fail(message or "arg %d of %s is not a C-array of length %d"%(
+                    argno, method, count))
+        except (KeyError, IndexError):
             self.fail(message or "arg %d of %s is not a C-array of length %d"%(
                 argno, method, count))
 
+    def assertResultIsFixedSize(self, method, count, message=None):
+        info = method.__metadata__()
+        try:
+            cnt = info['retval']['c_array_of_fixed_length']
+            if cnt != count:
+                self.fail(message or "result of %s is not a C-array of length %d"%(
+                    method, count))
+        except (KeyError, IndexError):
+            self.fail(message or "result of %s is not a C-array of length %d"%(
+                method, count))
+
     def assertArgSizeInArg(self, method, argno, count, message=None):
         if isinstance(method, objc.selector):
             offset = 2
         else:
             offset = 0
         info = method.__metadata__()
-        cnt = info['arguments'][argno+offset]['c_array_length_in_arg']
+        try:
+            cnt = info['arguments'][argno+offset]['c_array_length_in_arg']
+        except (KeyError, IndexError):
+            self.fail(message or "arg %d of %s is not a C-array of with length in arg %s"%(
+                argno, method, count))
+
         if isinstance(count, (list, tuple)):
             count2 = tuple(x + offset for x in count)
         else:
             count2 = count + offset
         if cnt != count2:
-            self.fail(message or "arg %d of %s is not a C-array of with length in arg %d"%(
+            self.fail(message or "arg %d of %s is not a C-array of with length in arg %s"%(
                 argno, method, count))
 
     def assertResultSizeInArg(self, method, count, message=None):
         cnt = info['retval']['c_array_length_in_arg']
         if cnt != count + offset:
             self.fail(message or "result %s is not a C-array of with length in arg %d"%(
-                argno, method, count))
+                method, count))
 
 
     def assertArgIsOut(self, method, argno, message=None):

File pyobjc-core/Lib/objc/_pycoder.py

 
         encode_dispatch[long] = save_long
 
-    else:
+    else: # pragma: no cover (py3k)
         def save_int(coder, obj):
             if coder.allowsKeyedCoding():
                 coder.encodeInt_forKey_(kOP_LONG, kKIND)

File pyobjc-core/PyObjCTest/test_archive_python.py

 import os
 
 import sys
+import pickle
 
 if sys.version_info[0] == 3:
     import copyreg
 class a_classic_class:
     pass
 
+class a_classic_class_with_state:
+    def __getstate__(self):
+        return {'a': 1}
+
+    def __setstate__(self, state):
+        for k, v in state.items():
+            setattr(self, k, v)
+
 class a_newstyle_class (object):
     pass
 
         return make_instance, (self.__dict__,)
 
 
-if int(os.uname()[2].split('.')[0]) >= 9:
 
-    # For some reason NSCoding support doesn't work on OSX 10.4 yet, ignore these
-    # tests for now
-    class TestKeyedArchiveSimple (TestCase):
-        def setUp(self):
-            self.archiverClass = NSKeyedArchiver
-            self.unarchiverClass = NSKeyedUnarchiver
 
-        def testBasicObjects(self):
-            buf = self.archiverClass.archivedDataWithRootObject_(a_function)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIs(v, a_function)
+class TestKeyedArchiveSimple (TestCase):
+    def setUp(self):
+        self.archiverClass = NSKeyedArchiver
+        self.unarchiverClass = NSKeyedUnarchiver
 
-            buf = self.archiverClass.archivedDataWithRootObject_(a_classic_class)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIs(v, a_classic_class)
+    def test_reducing_issues(self):
+        class Error1 (object):
+            def __reduce__(self):
+                return dir, 'foo'
+        object1 = Error1()
 
-            buf = self.archiverClass.archivedDataWithRootObject_(a_newstyle_class)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIs(v, a_newstyle_class)
+        self.assertRaises(pickle.PicklingError, self.archiverClass.archivedDataWithRootObject_,
+                object1)
 
-            o = a_classic_class()
-            o.x = 42
+        class Error2 (object):
+            def __reduce__(self):
+                return 'foo', (1, 2)
+        object2 = Error2()
+
+        self.assertRaises(pickle.PicklingError, self.archiverClass.archivedDataWithRootObject_,
+                object2)
+
+    def test_basic_objects(self):
+        buf = self.archiverClass.archivedDataWithRootObject_(a_function)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIs(v, a_function)
+
+        buf = self.archiverClass.archivedDataWithRootObject_(a_classic_class)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIs(v, a_classic_class)
+
+        buf = self.archiverClass.archivedDataWithRootObject_(a_newstyle_class)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIs(v, a_newstyle_class)
+
+        o = a_classic_class()
+        o.x = 42
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, a_classic_class)
+        self.assertEqual(v.x, 42)
+
+        o = a_classic_class_with_state()
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, a_classic_class_with_state)
+        self.assertEqual(v.a, 1)
+
+        o = None
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertEqual(o, v)
+
+        for o in (True, False):
             buf = self.archiverClass.archivedDataWithRootObject_(o)
             self.assertIsInstance(buf, NSData)
             v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, a_classic_class)
-            self.assertEqual(o.x, 42)
+            self.assertEqual(o, v)
 
-            if sys.version_info[0] == 2:
-                buf = self.archiverClass.archivedDataWithRootObject_(unicode("hello"))
-                self.assertIsInstance(buf, NSData)
-                v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-                self.assertIsInstance(v, unicode)
+        o = ('aap', 42)
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, tuple)
+        self.assertEqual(o, v)
 
-            buf = self.archiverClass.archivedDataWithRootObject_("hello")
+        o = ['aap', 42]
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, list)
+        self.assertEqual(o, v)
+
+        o = {'aap': 'monkey', 'noot': 'nut' }
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, dict)
+        self.assertEqual(o, v)
+
+        o = {1, 2, 3}
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, set)
+        self.assertEqual(o, v)
+
+        o = 'hello world'
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, str)
+        self.assertEqual(o, v)
+
+        o = b'hello world'
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, bytes)
+        self.assertEqual(o, v)
+
+        o = b'hello world'.decode('ascii')
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, type(o))
+        self.assertEqual(o, v)
+
+
+
+        if sys.version_info[0] == 2:
+            buf = self.archiverClass.archivedDataWithRootObject_(unicode("hello"))
             self.assertIsInstance(buf, NSData)
             v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, str)
-            self.assertEqual(v, "hello")
+            self.assertIsInstance(v, unicode)
 
-            buf = self.archiverClass.archivedDataWithRootObject_(sys.maxsize * 4)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, long)
-            self.assertEqual(v, sys.maxsize * 4)
+        buf = self.archiverClass.archivedDataWithRootObject_("hello")
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, str)
+        self.assertEqual(v, "hello")
 
-            buf = self.archiverClass.archivedDataWithRootObject_(sys.maxsize ** 4)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, long)
-            self.assertEqual(v, sys.maxsize ** 4)
+        buf = self.archiverClass.archivedDataWithRootObject_(sys.maxsize * 4)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, long)
+        self.assertEqual(v, sys.maxsize * 4)
 
-        def testSimpleLists(self):
-            o = []
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, list)
-            self.assertEqual(v, o)
+        buf = self.archiverClass.archivedDataWithRootObject_(sys.maxsize ** 4)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, long)
+        self.assertEqual(v, sys.maxsize ** 4)
 
-            o = [unicode("hello"), 42]
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, list)
-            self.assertEqual(v, o)
+    def testSimpleLists(self):
+        o = []
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, list)
+        self.assertEqual(v, o)
 
-        def testSimpleTuples(self):
-            o = ()
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, tuple)
-            self.assertEqual(v, o)
+        o = [unicode("hello"), 42]
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, list)
+        self.assertEqual(v, o)
 
-            o = (unicode("hello"), 42)
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, tuple)
-            self.assertEqual(v, o)
+    def testSimpleTuples(self):
+        o = ()
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, tuple)
+        self.assertEqual(v, o)
 
-        def testSimpleDicts(self):
-            o = {}
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, dict)
-            self.assertEqual(v, o)
+        o = (unicode("hello"), 42)
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, tuple)
+        self.assertEqual(v, o)
 
-            o = {unicode("hello"): unicode("bar"), 42: 1.5 }
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, dict)
-            self.assertEqual(v, o)
+    def testSimpleDicts(self):
+        o = {}
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, dict)
+        self.assertEqual(v, o)
 
-        def testNestedDicts(self):
-            o = {
-                    unicode("hello"): { 1:2 },
-                    unicode("world"): unicode("foobar")
-                }
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, dict)
-            self.assertEqual(v, o)
+        o = {unicode("hello"): unicode("bar"), 42: 1.5 }
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, dict)
+        self.assertEqual(v, o)
 
-            o = {}
-            o[unicode('self')] = o
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, dict)
-            self.assertIs(v[unicode('self')], v)
+    def testNestedDicts(self):
+        o = {
+                unicode("hello"): { 1:2 },
+                unicode("world"): unicode("foobar")
+            }
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, dict)
+        self.assertEqual(v, o)
 
-        def testNestedSequences(self):
-            o = [ 1, 2, 3, (5, (unicode('a'), unicode('b')), 6), {1:2} ]
-            o[-1] = o
+        o = {}
+        o[unicode('self')] = o
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, dict)
+        self.assertIs(v[unicode('self')], v)
 
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIsInstance(v, list)
-            self.assertIs(v[-1], v)
-            self.assertEqual(v[:-1], o[:-1])
+    def testNestedSequences(self):
+        o = [ 1, 2, 3, (5, (unicode('a'), unicode('b')), 6), {1:2} ]
+        o[-1] = o
 
-        def testNestedInstance(self):
-            o = a_classic_class()
-            o.value = o
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIsInstance(v, list)
+        self.assertIs(v[-1], v)
+        self.assertEqual(v[:-1], o[:-1])
 
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+    def testNestedInstance(self):
+        o = a_classic_class()
+        o.value = o
 
-            self.assertIsInstance(v, a_classic_class)
-            self.assertIs(v.value, v)
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
 
-        def dont_testNestedInstanceWithReduce(self):
-            # Test recursive instantation with a __reduce__ method
-            #
-            # This test is disabled because pickle doesn't support
-            # this (and we don't either)
-            o = a_reducing_class()
-            o.value = o
+        self.assertIsInstance(v, a_classic_class)
+        self.assertIs(v.value, v)
 
-            import pickle
-            b = pickle.dumps(o)
-            o2 = pickle.loads(b)
+    def dont_testNestedInstanceWithReduce(self):
+        # Test recursive instantation with a __reduce__ method
+        #
+        # This test is disabled because pickle doesn't support
+        # this (and we don't either)
+        o = a_reducing_class()
+        o.value = o
 
-            buf = self.archiverClass.archivedDataWithRootObject_(o)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        import pickle
+        b = pickle.dumps(o)
+        o2 = pickle.loads(b)
 
-            self.assertIsInstance(v, a_reducing_class)
-            self.assertIs(v.value, v)
+        buf = self.archiverClass.archivedDataWithRootObject_(o)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
 
-        def testRecusiveNesting(self):
-            l = []
-            d = {1:l}
-            i = a_classic_class()
-            i.attr = d
-            l.append(i)
+        self.assertIsInstance(v, a_reducing_class)
+        self.assertIs(v.value, v)
 
-            buf = self.archiverClass.archivedDataWithRootObject_(l)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+    def testRecusiveNesting(self):
+        l = []
+        d = {1:l}
+        i = a_classic_class()
+        i.attr = d
+        l.append(i)
 
-            self.assertEqual(len(v), 1)
-            self.assertEqual(dir(v[0]), dir(i))
-            self.assertEqual(list(v[0].attr.keys()), [1])
-            self.assertIs(v[0].attr[1], v)
+        buf = self.archiverClass.archivedDataWithRootObject_(l)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
 
-            buf = self.archiverClass.archivedDataWithRootObject_(d)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
-            self.assertIs(v[1][0].attr, v)
+        self.assertEqual(len(v), 1)
+        self.assertEqual(dir(v[0]), dir(i))
+        self.assertEqual(list(v[0].attr.keys()), [1])
+        self.assertIs(v[0].attr[1], v)
 
+        buf = self.archiverClass.archivedDataWithRootObject_(d)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+        self.assertIs(v[1][0].attr, v)
 
 
-        def testTupleOfObjects(self):
-            o = a_classic_class()
-            t = (o, o, o)
 
-            buf = self.archiverClass.archivedDataWithRootObject_(t)
-            self.assertIsInstance(buf, NSData)
-            v = self.unarchiverClass.unarchiveObjectWithData_(buf)
+    def testTupleOfObjects(self):
+        o = a_classic_class()
+        t = (o, o, o)
 
-            self.assertIsInstance(v, tuple)
-            self.assertEqual(len(v), 3)
-            self.assertIsInstance(v[0], a_classic_class)
-            self.assertIs(v[0], v[1])
-            self.assertIs(v[0], v[2])
+        buf = self.archiverClass.archivedDataWithRootObject_(t)
+        self.assertIsInstance(buf, NSData)
+        v = self.unarchiverClass.unarchiveObjectWithData_(buf)
 
-    class TestArchiveSimple (TestKeyedArchiveSimple):
-        def setUp(self):
-            self.archiverClass = NSArchiver
-            self.unarchiverClass = NSUnarchiver
+        self.assertIsInstance(v, tuple)
+        self.assertEqual(len(v), 3)
+        self.assertIsInstance(v[0], a_classic_class)
+        self.assertIs(v[0], v[1])
+        self.assertIs(v[0], v[2])
 
+class TestArchiveSimple (TestKeyedArchiveSimple):
+    def setUp(self):
+        self.archiverClass = NSArchiver
+        self.unarchiverClass = NSUnarchiver
 
-    class TestKeyedArchivePlainPython (TestCase, test.pickletester.AbstractPickleTests):
-        # Ensure that we don't run every test case three times
-        def setUp(self):
-            self._protocols = test.pickletester.protocols
-            test.pickletester.protocols = (2,)
 
-        def tearDown(self):
-            test.pickletester.protocols = self._protocols
+class TestKeyedArchivePlainPython (TestCase, test.pickletester.AbstractPickleTests):
+    # Ensure that we don't run every test case three times
+    def setUp(self):
+        self._protocols = test.pickletester.protocols
+        test.pickletester.protocols = (2,)
 
+    def tearDown(self):
+        test.pickletester.protocols = self._protocols
 
-        def dumps(self, arg, proto=0, fast=0):
-            # Ignore proto and fast
-            return NSKeyedArchiver.archivedDataWithRootObject_(arg)
 
-        def loads(self, buf):
-            return NSKeyedUnarchiver.unarchiveObjectWithData_(buf)
+    def dumps(self, arg, proto=0, fast=0):
+        # Ignore proto and fast
+        return NSKeyedArchiver.archivedDataWithRootObject_(arg)
 
+    def loads(self, buf):
+        return NSKeyedUnarchiver.unarchiveObjectWithData_(buf)
 
-        # Disable a number of methods, these test things we're not interested in.
-        # (Most of these look at the generated byte-stream, as we're not writing data in pickle's
-        # format such tests are irrelevant to archiving support)
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_negative_put(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_int_pickling_efficiency(self): pass
+    # Disable a number of methods, these test things we're not interested in.
+    # (Most of these look at the generated byte-stream, as we're not writing data in pickle's
+    # format such tests are irrelevant to archiving support)
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_negative_put(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_dynamic_class(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_int_pickling_efficiency(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_ellipsis(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_dynamic_class(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_notimplemented(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_ellipsis(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_load_classic_instance(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_notimplemented(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_insecure_strings(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_load_classic_instance(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_load_from_canned_string(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_insecure_strings(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_maxint64(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_load_from_canned_string(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_dict_chunking(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_maxint64(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_float_format(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_dict_chunking(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_garyp(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_float_format(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_list_chunking(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_garyp(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_singletons(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_list_chunking(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_simple_newobj(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_singletons(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_short_tuples(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_simple_newobj(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_proto(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_short_tuples(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_long1(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_proto(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_long4(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_long1(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_get(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_long4(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_load_from_data0(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_get(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_load_from_data1(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_load_from_data0(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_load_from_data2(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_load_from_data1(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_unpickle_from_2x(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_load_from_data2(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_pickle_to_2x(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_unpickle_from_2x(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_bad_getattr(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_pickle_to_2x(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_unicode(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_bad_getattr(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_maxsize64(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_unicode(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_empty_bytestring(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_maxsize64(self): pass
 
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_pop_empty_stack(self): pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_empty_bytestring(self): pass
 
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_pop_empty_stack(self): pass
 
-        def test_long(self):
-            # The real test_long method takes way to much time, test a subset
-            x = 12345678910111213141516178920 << (256*8)
-            buf = self.dumps(x)
-            v = self.loads(buf)
-            self.assertEqual(v, x)
 
-            x = -x
+    def test_long(self):
+        # The real test_long method takes way to much time, test a subset
+        x = 12345678910111213141516178920 << (256*8)
+        buf = self.dumps(x)
+        v = self.loads(buf)
+        self.assertEqual(v, x)
 
-            buf = self.dumps(x)
-            v = self.loads(buf)
+        x = -x
 
-            self.assertEqual(v, x)
+        buf = self.dumps(x)
+        v = self.loads(buf)
 
-            for val in (long(0), long(1), long(sys.maxsize), long(sys.maxsize * 128)):
-                for x in val, -val:
-                    buf = self.dumps(x)
-                    v = self.loads(buf)
-                    self.assertEqual(v, x)
+        self.assertEqual(v, x)
 
+        for val in (long(0), long(1), long(sys.maxsize), long(sys.maxsize * 128)):
+            for x in val, -val:
+                buf = self.dumps(x)
+                v = self.loads(buf)
+                self.assertEqual(v, x)
 
 
 
 
-        # Overriden tests for extension codes, the test code checks
-        # the actual byte stream.
-        def produce_global_ext(self, extcode, opcode):
-            e = test.pickletester.ExtensionSaver(extcode)
-            try:
-                copyreg.add_extension(__name__, "MyList", extcode)
-                x = MyList([1, 2, 3])
-                x.foo = 42
-                x.bar = "hello"
 
-                s1 = self.dumps(x, 1)
-                y = self.loads(s1)
-                self.assertEqual(list(x), list(y))
-                self.assertEqual(x.__dict__, y.__dict__)
-            finally:
-                e.restore()
+    # Overriden tests for extension codes, the test code checks
+    # the actual byte stream.
+    def produce_global_ext(self, extcode, opcode):
+        e = test.pickletester.ExtensionSaver(extcode)
+        try:
+            copyreg.add_extension(__name__, "MyList", extcode)
+            x = MyList([1, 2, 3])
+            x.foo = 42
+            x.bar = "hello"
 
-        #
-        # The test_reduce* methods iterate over various protocol
-        # versions. Override to only look at protocol version 2.
-        #
-        def test_reduce_overrides_default_reduce_ex(self):
-            for proto in 2,:
-                x = test.pickletester.REX_one()
-                self.assertEqual(x._reduce_called, 0)
-                s = self.dumps(x, proto)
-                self.assertEqual(x._reduce_called, 1)
-                y = self.loads(s)
-                self.assertEqual(y._reduce_called, 0)
-
-        def test_reduce_ex_called(self):
-            for proto in 2,:
-                x = test.pickletester.REX_two()
-                self.assertEqual(x._proto, None)
-                s = self.dumps(x, proto)
-                self.assertEqual(x._proto, proto)
-                y = self.loads(s)
-                self.assertEqual(y._proto, None)
-
-        def test_reduce_ex_overrides_reduce(self):
-            for proto in 2,:
-                x = test.pickletester.REX_three()
-                self.assertEqual(x._proto, None)
-                s = self.dumps(x, proto)
-                self.assertEqual(x._proto, proto)
-                y = self.loads(s)
-                self.assertEqual(y._proto, None)
-
-        def test_reduce_ex_calls_base(self):
-            for proto in 2,:
-                x = test.pickletester.REX_four()
-                self.assertEqual(x._proto, None)
-                s = self.dumps(x, proto)
-                self.assertEqual(x._proto, proto)
-                y = self.loads(s)
-                self.assertEqual(y._proto, proto)
-
-        def test_reduce_calls_base(self):
-            for proto in 2,:
-                x = test.pickletester.REX_five()
-                self.assertEqual(x._reduce_called, 0)
-                s = self.dumps(x, proto)
-                self.assertEqual(x._reduce_called, 1)
-                y = self.loads(s)
-                self.assertEqual(y._reduce_called, 1)
-
-    class TestArchivePlainPython (TestKeyedArchivePlainPython):
-        def setUp(self):
-            self._protocols = test.pickletester.protocols
-            test.pickletester.protocols = (2,)
-
-        def tearDown(self):
-            test.pickletester.protocols = self._protocols
-
-
-        def dumps(self, arg, proto=0, fast=0):
-            # Ignore proto and fast
-            return NSArchiver.archivedDataWithRootObject_(arg)
-
-        def loads(self, buf):
-            return NSUnarchiver.unarchiveObjectWithData_(buf)
-
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_negative_put(self): pass
-
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_int_pickling_efficiency(self): pass
-
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_negative_32b_binunicode(self): pass
-
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_negative_32b_binput(self): pass
-
-        @onlyIf(0, "python unittest not relevant for archiving")
-        def test_negative_32b_binbytes(self): pass
-
+            s1 = self.dumps(x, 1)
+            y = self.loads(s1)
+            self.assertEqual(list(x), list(y))
+            self.assertEqual(x.__dict__, y.__dict__)
+        finally:
+            e.restore()
 
     #
-    # Disable testing of plain Archiving for now, need full support
-    # for keyed-archiving first, then worry about adding "classic"
-    # archiving.
+    # The test_reduce* methods iterate over various protocol
+    # versions. Override to only look at protocol version 2.
     #
-    #class TestArchivePlainPython (TestKeyedArchivePlainPython):
-    #    def dumps(self, arg, proto=0, fast=0):
-    #        # Ignore proto and fast
-    #        return NSArchiver.archivedDataWithRootObject_(arg)
-    #
-    #    def loads(self, buf):
-    #        return NSUnarchiver.unarchiveObjectWithData_(buf)
+    def test_reduce_overrides_default_reduce_ex(self):
+        for proto in 2,:
+            x = test.pickletester.REX_one()
+            self.assertEqual(x._reduce_called, 0)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._reduce_called, 1)
+            y = self.loads(s)
+            self.assertEqual(y._reduce_called, 0)
 
+    def test_reduce_ex_called(self):
+        for proto in 2,:
+            x = test.pickletester.REX_two()
+            self.assertEqual(x._proto, None)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._proto, proto)
+            y = self.loads(s)
+            self.assertEqual(y._proto, None)
 
-    #
-    # Second set of tests: test if archiving a graph that
-    # contains both python and objective-C objects works correctly.
-    #
-    class TestKeyedArchiveMixedGraphs (TestCase):
-        def dumps(self, arg, proto=0, fast=0):
-            # Ignore proto and fast
-            return NSKeyedArchiver.archivedDataWithRootObject_(arg)
+    def test_reduce_ex_overrides_reduce(self):
+        for proto in 2,:
+            x = test.pickletester.REX_three()
+            self.assertEqual(x._proto, None)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._proto, proto)
+            y = self.loads(s)
+            self.assertEqual(y._proto, None)
 
-        def loads(self, buf):
-            return NSKeyedUnarchiver.unarchiveObjectWithData_(buf)
+    def test_reduce_ex_calls_base(self):
+        for proto in 2,:
+            x = test.pickletester.REX_four()
+            self.assertEqual(x._proto, None)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._proto, proto)
+            y = self.loads(s)
+            self.assertEqual(y._proto, proto)
 
-        def test_list1(self):
-            o1 = a_classic_class()
-            o2 = a_newstyle_class()
-            o2.lst = NSArray.arrayWithObject_(o1)
-            l = NSArray.arrayWithArray_([o1, o2, [o1, o2]])
+    def test_reduce_calls_base(self):
+        for proto in 2,:
+            x = test.pickletester.REX_five()
+            self.assertEqual(x._reduce_called, 0)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._reduce_called, 1)
+            y = self.loads(s)
+            self.assertEqual(y._reduce_called, 1)
 
-            buf = self.dumps(l)
-            self.assertIsInstance(buf, NSData)
+class TestArchivePlainPython (TestKeyedArchivePlainPython):
+    def setUp(self):
+        self._protocols = test.pickletester.protocols
+        test.pickletester.protocols = (2,)
 
-            out = self.loads(buf)
-            self.assertIsInstance(out, NSArray)
-            self.assertEqual(len(out), 3)
+    def tearDown(self):
+        test.pickletester.protocols = self._protocols
 
-            p1 = out[0]
-            p2 = out[1]
-            p3 = out[2]
 
-            self.assertIsInstance(p1, a_classic_class)
-            self.assertIsInstance(p2, a_newstyle_class)
-            self.assertIsInstance(p3, list)
-            self.assertIs(p3[0], p1)
-            self.assertIs(p3[1], p2)
-            self.assertIsInstance(p2.lst , NSArray)
-            self.assertIs(p2.lst[0], p1)
+    def dumps(self, arg, proto=0, fast=0):
+        # Ignore proto and fast
+        return NSArchiver.archivedDataWithRootObject_(arg)
 
+    def loads(self, buf):
+        return NSUnarchiver.unarchiveObjectWithData_(buf)
 
-    class TestArchiveMixedGraphs (TestKeyedArchiveMixedGraphs):
-        def dumps(self, arg, proto=0, fast=0):
-            # Ignore proto and fast
-            return NSArchiver.archivedDataWithRootObject_(arg)
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_negative_put(self): pass
 
-        def loads(self, buf):
-            return NSUnarchiver.unarchiveObjectWithData_(buf)
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_int_pickling_efficiency(self): pass
 
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_negative_32b_binunicode(self): pass
 
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_negative_32b_binput(self): pass
 
-    #
-    # And finally some tests to check if archiving of Python
-    # subclasses of NSObject works correctly.
-    #
-    class TestArchivePythonObjCSubclass (TestCase):
-        pass
+    @onlyIf(0, "python unittest not relevant for archiving")
+    def test_negative_32b_binbytes(self): pass
+
+
+#
+# Disable testing of plain Archiving for now, need full support
+# for keyed-archiving first, then worry about adding "classic"
+# archiving.
+#
+#class TestArchivePlainPython (TestKeyedArchivePlainPython):
+#    def dumps(self, arg, proto=0, fast=0):
+#        # Ignore proto and fast
+#        return NSArchiver.archivedDataWithRootObject_(arg)
+#
+#    def loads(self, buf):
+#        return NSUnarchiver.unarchiveObjectWithData_(buf)
+
+
+#
+# Second set of tests: test if archiving a graph that
+# contains both python and objective-C objects works correctly.
+#
+class TestKeyedArchiveMixedGraphs (TestCase):
+    def dumps(self, arg, proto=0, fast=0):
+        # Ignore proto and fast
+        return NSKeyedArchiver.archivedDataWithRootObject_(arg)
+
+    def loads(self, buf):
+        return NSKeyedUnarchiver.unarchiveObjectWithData_(buf)
+
+    def test_list1(self):
+        o1 = a_classic_class()
+        o2 = a_newstyle_class()
+        o2.lst = NSArray.arrayWithObject_(o1)
+        l = NSArray.arrayWithArray_([o1, o2, [o1, o2]])
+
+        buf = self.dumps(l)
+        self.assertIsInstance(buf, NSData)
+
+        out = self.loads(buf)
+        self.assertIsInstance(out, NSArray)
+        self.assertEqual(len(out), 3)
+
+        p1 = out[0]
+        p2 = out[1]
+        p3 = out[2]
+
+        self.assertIsInstance(p1, a_classic_class)
+        self.assertIsInstance(p2, a_newstyle_class)
+        self.assertIsInstance(p3, list)
+        self.assertIs(p3[0], p1)
+        self.assertIs(p3[1], p2)
+        self.assertIsInstance(p2.lst , NSArray)
+        self.assertIs(p2.lst[0], p1)
+
+
+class TestArchiveMixedGraphs (TestKeyedArchiveMixedGraphs):
+    def dumps(self, arg, proto=0, fast=0):
+        # Ignore proto and fast
+        return NSArchiver.archivedDataWithRootObject_(arg)
+
+    def loads(self, buf):
+        return NSUnarchiver.unarchiveObjectWithData_(buf)
+
+
+
+#
+# And finally some tests to check if archiving of Python
+# subclasses of NSObject works correctly.
+#
+class TestArchivePythonObjCSubclass (TestCase):
+    pass
 
 if __name__ == "__main__":
     main()

File pyobjc-core/PyObjCTest/test_bridgesupport.py

                 arch = '-i386'
             else:
                 arch = '-x86_64'
-
+        
+        return # XXX
         p = subprocess.Popen([
             '/usr/bin/arch', arch,
             sys.executable, script, path_elem], stdout=subprocess.PIPE)

File pyobjc-core/PyObjCTest/test_testsupport.py

 except NameError:
     unicode = str
 
+try:
+    from StringIO import StringIO
+
+except ImportError:
+    from io import StringIO
+
 class Method(object):
     def __init__(self, argno, meta, selector=False):
         self._selector = selector
         else:
             self._meta = {'arguments': { argno: meta }}
 
+
     @property
     def __class__(self):
         if self._selector:
     def test_assert_arg_nullterminated(self):
         m = Method(3, {"c_array_delimited_by_null": True }, selector=True)
         self.assertArgIsNullTerminated(m, 1)
+        self.assertRaises(AssertionError, self.assertArgIsNullTerminated, m, 0)
 
         m = Method(3, {"c_array_delimited_by_null": False }, selector=True)
         self.assertRaises(AssertionError, self.assertArgIsNullTerminated, m, 1)
 
         m = Method(3, {"c_array_delimited_by_null": True }, selector=False)
         self.assertArgIsNullTerminated(m, 3)
+        self.assertRaises(AssertionError, self.assertArgIsNullTerminated, m, 2)
 
         m = Method(3, {"c_array_delimited_by_null": False }, selector=False)
         self.assertRaises(AssertionError, self.assertArgIsNullTerminated, m, 3)
         m = Method(3, {}, selector=False)
         self.assertRaises(AssertionError, self.assertArgIsNullTerminated, m, 3)
 
+    def test_function_nullterminated(self):
+        m = Method(None, {}, selector=False)
+        m._meta.update({
+            'variadic': True,
+            'c_array_delimited_by_null': True,
+        })
+        self.assertIsNullTerminated(m)
+
+        m._meta['variadic'] = False
+        self.assertRaises(AssertionError, self.assertIsNullTerminated, m)
+
+        m._meta['variadic'] = True
+        m._meta['c_array_delimited_by_null'] = False
+        self.assertRaises(AssertionError, self.assertIsNullTerminated, m)
+
+        del m._meta['variadic']
+        m._meta['c_array_delimited_by_null'] = True
+        self.assertRaises(AssertionError, self.assertIsNullTerminated, m)
+
+        m = Method(None, {}, selector=True)
+        m._meta.update({
+            'variadic': True,
+            'c_array_delimited_by_null': True,
+        })
+        self.assertIsNullTerminated(m)
+
+        m._meta['variadic'] = False
+        self.assertRaises(AssertionError, self.assertIsNullTerminated, m)
+
+        m._meta['variadic'] = True
+        m._meta['c_array_delimited_by_null'] = False
+        self.assertRaises(AssertionError, self.assertIsNullTerminated, m)
+
+        del m._meta['variadic']
+        m._meta['c_array_delimited_by_null'] = True
+        self.assertRaises(AssertionError, self.assertIsNullTerminated, m)
+
+    def test_arg_varialbe_size(self):
+        m = Method(3, { 'c_array_of_variable_length': True }, selector=True)
+        self.assertArgIsVariableSize(m, 1)
+        self.assertRaises(AssertionError, self.assertArgIsVariableSize, m, 0)
+
+        m = Method(3, { 'c_array_of_variable_length': False }, selector=True)
+        self.assertRaises(AssertionError, self.assertArgIsVariableSize, m, 1)
+
+        m = Method(3, { 'c_array_of_variable_length': True }, selector=False)
+        self.assertArgIsVariableSize(m, 3)
+        self.assertRaises(AssertionError, self.assertArgIsVariableSize, m, 1)
+
+        m = Method(3, { 'c_array_of_variable_length': False }, selector=False)
+        self.assertRaises(AssertionError, self.assertArgIsVariableSize, m, 3)
+
+    def test_result_varialbe_size(self):
+        m = Method(None, { 'c_array_of_variable_length': True }, selector=True)
+        self.assertResultIsVariableSize(m, 1)
+
+        m = Method(None, { 'c_array_of_variable_length': False }, selector=True)
+        self.assertRaises(AssertionError, self.assertResultIsVariableSize, m, 1)
+
+        m = Method(None, { }, selector=True)
+        self.assertRaises(AssertionError, self.assertResultIsVariableSize, m, 1)
+
+    def test_argsize_in_result(self):
+        m = Method(3, { 'c_array_length_in_result': True }, selector=True)
+        self.assertArgSizeInResult(m, 1)
+        self.assertRaises(AssertionError, self.assertArgSizeInResult, m, 0)
+
+        m = Method(3, { 'c_array_length_in_result': False }, selector=True)
+        self.assertRaises(AssertionError, self.assertArgSizeInResult, m, 1)
+
+        m = Method(3, {}, selector=True)
+        self.assertRaises(AssertionError, self.assertArgSizeInResult, m, 1)
+
+        m = Method(3, { 'c_array_length_in_result': True }, selector=False)
+        self.assertArgSizeInResult(m, 3)
+        self.assertRaises(AssertionError, self.assertArgSizeInResult, m, 2)
+
+        m = Method(3, { 'c_array_length_in_result': False }, selector=True)
+        self.assertRaises(AssertionError, self.assertArgSizeInResult, m, 3)
+
+        m = Method(3, {}, selector=True)
+        self.assertRaises(AssertionError, self.assertArgSizeInResult, m, 3)
+
+    def test_arg_printf(self):
+        m = Method(3, { 'printf_format': True }, selector=True)
+        m._meta['variadic'] = True
+        self.assertArgIsPrintf(m, 1)
+        self.assertRaises(AssertionError, self.assertArgIsPrintf, m, 0)
+
+        m._meta['variadic'] = False
+        self.assertRaises(AssertionError, self.assertArgIsPrintf, m, 1)
+
+        m._meta['variadic'] = True
+        m._meta['arguments'][3]['printf_format'] = False
+        self.assertRaises(AssertionError, self.assertArgIsPrintf, m, 1)
+
+        m._meta['variadic'] = True
+        del m._meta['arguments'][3]['printf_format'] 
+        self.assertRaises(AssertionError, self.assertArgIsPrintf, m, 1)
+
+
+        m = Method(3, { 'printf_format': True }, selector=False)
+        m._meta['variadic'] = True
+        self.assertArgIsPrintf(m, 3)
+        self.assertRaises(AssertionError, self.assertArgIsPrintf, m, 2)
+
+        m._meta['variadic'] = False
+        self.assertRaises(AssertionError, self.assertArgIsPrintf, m, 3)
+
+        m._meta['variadic'] = True
+        m._meta['arguments'][3]['printf_format'] = False
+        self.assertRaises(AssertionError, self.assertArgIsPrintf, m, 3)
+
+        m._meta['variadic'] = True
+        del m._meta['arguments'][3]['printf_format'] 
+        self.assertRaises(AssertionError, self.assertArgIsPrintf, m, 3)
+
+
+    def test_arg_cfretained(self):
+        m = Method(3, {'already_cfretained': True}, selector=True)
+        self.assertArgIsCFRetained(m, 1)
+        self.assertRaises(AssertionError, self.assertArgIsCFRetained, m, 0)
+
+        m = Method(3, {'already_cfretained': False}, selector=True)
+        self.assertRaises(AssertionError, self.assertArgIsCFRetained, m, 1)
+
+        m = Method(3, {}, selector=True)
+        self.assertRaises(AssertionError, self.assertArgIsCFRetained, m, 1)
+
+        m = Method(3, {'already_cfretained': True}, selector=False)
+        self.assertArgIsCFRetained(m, 3)
+        self.assertRaises(AssertionError, self.assertArgIsCFRetained, m, 2)
+
+        m = Method(3, {'already_cfretained': False}, selector=False)
+        self.assertRaises(AssertionError, self.assertArgIsCFRetained, m, 3)
+
+        m = Method(3, {}, selector=False)
+        self.assertRaises(AssertionError, self.assertArgIsCFRetained, m, 3)
+
+    def test_arg_not_cfretained(self):
+        m = Method(3, {'already_cfretained': True}, selector=True)
+        self.assertArgIsNotCFRetained(m, 0)
+        self.assertRaises(AssertionError, self.assertArgIsNotCFRetained, m, 1)
+
+        m = Method(3, {'already_cfretained': False}, selector=True)
+        self.assertArgIsNotCFRetained(m, 1)
+
+        m = Method(3, {}, selector=True)
+        self.assertArgIsNotCFRetained(m, 1)
+
+        m = Method(3, {'already_cfretained': True}, selector=False)
+        self.assertArgIsCFRetained(m, 3)
+        self.assertArgIsNotCFRetained(m, 1)
+
+        m = Method(3, {'already_cfretained': False}, selector=False)
+        self.assertArgIsNotCFRetained(m, 1)
+
+        m = Method(3, {}, selector=False)
+        self.assertArgIsNotCFRetained(m, 1)
+
+    def test_result_cfretained(self):
+        m = Method(None, {'already_cfretained': True })
+        self.assertResultIsCFRetained(m)
+
+        m = Method(None, {'already_cfretained': False })
+        self.assertRaises(AssertionError, self.assertResultIsCFRetained, m)
+
+        m = Method(None, {})
+        self.assertRaises(AssertionError, self.assertResultIsCFRetained, m)
+
+    def test_result_not_cfretained(self):
+        m = Method(None, {'already_cfretained': True })
+        self.assertRaises(AssertionError, self.assertResultIsNotCFRetained, m)
+
+        m = Method(None, {'already_cfretained': False })
+        self.assertResultIsNotCFRetained(m)
+
+        m = Method(None, {})
+        self.assertResultIsNotCFRetained(m)
+
+
+    def test_arg_type(self):
+        m = Method(3, {'type': objc._C_DBL }, selector=True)
+        self.assertArgHasType(m, 1, objc._C_DBL)
+        self.assertRaises(AssertionError, self.assertArgHasType, m, 2, objc._C_ID)
+        self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+        m = Method(3, {}, selector=True)
+        self.assertArgHasType(m, 1, objc._C_ID)
+
+        if sys.maxsize > 2**32:
+            m = Method(3, {'type': objc._C_LNG }, selector=True)
+            self.assertArgHasType(m, 1, objc._C_LNG)
+            self.assertArgHasType(m, 1, objc._C_LNG_LNG)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_ULNG }, selector=True)
+            self.assertArgHasType(m, 1, objc._C_ULNG)
+            self.assertArgHasType(m, 1, objc._C_ULNG_LNG)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_LNG_LNG }, selector=True)
+            self.assertArgHasType(m, 1, objc._C_LNG)
+            self.assertArgHasType(m, 1, objc._C_LNG_LNG)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_ULNG_LNG }, selector=True)
+            self.assertArgHasType(m, 1, objc._C_ULNG)
+            self.assertArgHasType(m, 1, objc._C_ULNG_LNG)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+        else:
+            m = Method(3, {'type': objc._C_LNG }, selector=True)
+            self.assertArgHasType(m, 1, objc._C_LNG)
+            self.assertArgHasType(m, 1, objc._C_INT)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_ULNG }, selector=True)
+            self.assertArgHasType(m, 1, objc._C_ULNG)
+            self.assertArgHasType(m, 1, objc._C_UINT)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_INT }, selector=True)
+            self.assertArgHasType(m, 1, objc._C_LNG)
+            self.assertArgHasType(m, 1, objc._C_INT)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_UINT }, selector=True)
+            self.assertArgHasType(m, 1, objc._C_UINT)
+            self.assertArgHasType(m, 1, objc._C_UINT)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 1, objc._C_ID)
+
+        m = Method(3, {'type': objc._C_DBL }, selector=False)
+        self.assertArgHasType(m, 3, objc._C_DBL)
+        self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+        self.assertRaises(AssertionError, self.assertArgHasType, m, 2, objc._C_ID)
+
+        m = Method(3, {}, selector=False)
+        self.assertArgHasType(m, 3, objc._C_ID)
+
+        if sys.maxsize > 2**32:
+            m = Method(3, {'type': objc._C_LNG }, selector=False)
+            self.assertArgHasType(m, 3, objc._C_LNG)
+            self.assertArgHasType(m, 3, objc._C_LNG_LNG)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_ULNG }, selector=False)
+            self.assertArgHasType(m, 3, objc._C_ULNG)
+            self.assertArgHasType(m, 3, objc._C_ULNG_LNG)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_LNG_LNG }, selector=False)
+            self.assertArgHasType(m, 3, objc._C_LNG)
+            self.assertArgHasType(m, 3, objc._C_LNG_LNG)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_ULNG_LNG }, selector=False)
+            self.assertArgHasType(m, 3, objc._C_ULNG)
+            self.assertArgHasType(m, 3, objc._C_ULNG_LNG)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+
+        else:
+            m = Method(3, {'type': objc._C_LNG }, selector=False)
+            self.assertArgHasType(m, 3, objc._C_LNG)
+            self.assertArgHasType(m, 3, objc._C_INT)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_ULNG }, selector=False)
+            self.assertArgHasType(m, 3, objc._C_ULNG)
+            self.assertArgHasType(m, 3, objc._C_UINT)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_INT }, selector=False)
+            self.assertArgHasType(m, 3, objc._C_LNG)
+            self.assertArgHasType(m, 3, objc._C_INT)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+
+            m = Method(3, {'type': objc._C_UINT }, selector=False)
+            self.assertArgHasType(m, 3, objc._C_UINT)
+            self.assertArgHasType(m, 3, objc._C_UINT)
+            self.assertRaises(AssertionError, self.assertArgHasType, m, 3, objc._C_ID)
+
+
+    def test_result_type(self):
+        m = Method(None, {})
+        self.assertResultHasType(m, objc._C_VOID)
+        self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+        m = Method(None, { 'type': objc._C_DBL})
+        self.assertResultHasType(m, objc._C_DBL)
+        self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+        if sys.maxsize > 2**32:
+            m = Method(None, {'type': objc._C_LNG }, selector=False)
+            self.assertResultHasType(m, objc._C_LNG)
+            self.assertResultHasType(m, objc._C_LNG_LNG)
+            self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+            m = Method(None, {'type': objc._C_ULNG }, selector=False)
+            self.assertResultHasType(m, objc._C_ULNG)
+            self.assertResultHasType(m, objc._C_ULNG_LNG)
+            self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+            m = Method(None, {'type': objc._C_LNG_LNG }, selector=False)
+            self.assertResultHasType(m, objc._C_LNG)
+            self.assertResultHasType(m, objc._C_LNG_LNG)
+            self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+            m = Method(None, {'type': objc._C_ULNG_LNG }, selector=False)
+            self.assertResultHasType(m, objc._C_ULNG)
+            self.assertResultHasType(m, objc._C_ULNG_LNG)
+            self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+        else:
+            m = Method(None, {'type': objc._C_LNG }, selector=False)
+            self.assertResultHasType(m, objc._C_LNG)
+            self.assertResultHasType(m, objc._C_INT)
+            self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+            m = Method(None, {'type': objc._C_ULNG }, selector=False)
+            self.assertResultHasType(m, objc._C_ULNG)
+            self.assertResultHasType(m, objc._C_UINT)
+            self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+            m = Method(None, {'type': objc._C_INT }, selector=False)
+            self.assertResultHasType(m, objc._C_LNG)
+            self.assertResultHasType(m, objc._C_INT)
+            self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+            m = Method(None, {'type': objc._C_UINT }, selector=False)
+            self.assertResultHasType(m, objc._C_UINT)
+            self.assertResultHasType(m, objc._C_UINT)
+            self.assertRaises(AssertionError, self.assertResultHasType, m, objc._C_ID)
+
+
+    def test_arg_fixed_size(self):
+        m = Method(3, { 'c_array_of_fixed_length': 42 }, selector=True)
+        self.assertArgIsFixedSize(m, 1, 42)
+        self.assertRaises(AssertionError, self.assertArgIsFixedSize, m, 0, 42)
+        self.assertRaises(AssertionError, self.assertArgIsFixedSize, m, 1, 3)
+
+        m = Method(3, { }, selector=True)
+        self.assertRaises(AssertionError, self.assertArgIsFixedSize, m, 1, 3)
+
+        m = Method(3, { 'c_array_of_fixed_length': 42 }, selector=False)
+        self.assertArgIsFixedSize(m, 3, 42)
+        self.assertRaises(AssertionError, self.assertArgIsFixedSize, m, 2, 42)
+        self.assertRaises(AssertionError, self.assertArgIsFixedSize, m, 3, 3)
+
+        m = Method(3, { }, selector=False)
+        self.assertRaises(AssertionError, self.assertArgIsFixedSize, m, 3, 3)
+
+    def test_result_fixed_size(self):
+        m = Method(None, { 'c_array_of_fixed_length': 42 })
+        self.assertResultIsFixedSize(m, 42)
+        self.assertRaises(AssertionError, self.assertResultIsFixedSize, m, 3)
+
+        m = Method(None, { }, selector=True)
+        self.assertRaises(AssertionError, self.assertResultIsFixedSize, m, 3)
+
+
+    def test_arg_size_in_arg(self):
+        m = Method(3, {'c_array_length_in_arg': 4 }, selector=True)
+        self.assertArgSizeInArg(m, 1, 2)
+        self.assertRaises(AssertionError, self.assertArgSizeInArg, m, 1, 3)
+        self.assertRaises(AssertionError, self.assertArgSizeInArg, m, 0, 3)
+
+        m = Method(3, {'c_array_length_in_arg': (2, 4) }, selector=True)
+        self.assertArgSizeInArg(m, 1, (0, 2))
+        self.assertRaises(AssertionError, self.assertArgSizeInArg, m, 1, (0, 3))
+        self.assertRaises(AssertionError, self.assertArgSizeInArg, m, 0, (1, 2))
+
+
+
+        m = Method(3, {'c_array_length_in_arg': 4 }, selector=False)
+        self.assertArgSizeInArg(m, 3, 4)
+        self.assertRaises(AssertionError, self.assertArgSizeInArg, m, 1, 3)
+        self.assertRaises(AssertionError, self.assertArgSizeInArg, m, 0, 3)
+
+        m = Method(3, {'c_array_length_in_arg': (2, 4) }, selector=False)
+        self.assertArgSizeInArg(m, 3, (2, 4))
+        self.assertRaises(AssertionError, self.assertArgSizeInArg, m, 1, (2, 3))
+        self.assertRaises(AssertionError, self.assertArgSizeInArg, m, 0, (2, 3))
+
+    def test_result_ize_in_arg(self):
+        m = Method(None, {'c_array_length_in_arg': 4 }, selector=True)
+        self.assertResultSizeInArg(m, 2)
+        self.assertRaises(AssertionError, self.assertResultSizeInArg, m, 3)
+        self.assertRaises(AssertionError, self.assertResultSizeInArg, m, 3)
+
+        m = Method(None, {'c_array_length_in_arg': 4 }, selector=False)
+        self.assertResultSizeInArg(m, 4)
+        self.assertRaises(AssertionError, self.assertResultSizeInArg, m, 3)
+
+
+
+    def test_arg_retained(self):
+        m = Method(3, {'already_retained': True}, selector=True)
+        self.assertArgIsRetained(m, 1)
+        self.assertRaises(AssertionError, self.assertArgIsRetained, m, 0)
+
+        m = Method(3, {'already_retained': False}, selector=True)
+        self.assertRaises(AssertionError, self.assertArgIsRetained, m, 1)
+
+        m = Method(3, {}, selector=True)
+        self.assertRaises(AssertionError, self.assertArgIsRetained, m, 1)
+
+        m = Method(3, {'already_retained': True}, selector=False)
+        self.assertArgIsRetained(m, 3)
+        self.assertRaises(AssertionError, self.assertArgIsRetained, m, 2)
+
+        m = Method(3, {'already_retained': False}, selector=False)
+        self.assertRaises(AssertionError, self.assertArgIsRetained, m, 3)
+