Commits

Ronald Oussoren  committed f1a3622

- Class methods are no longer callable through instances
- Use PyObjC_PythonToCArray for more method implementations in Foundation
- Slightly smarter code generators
- Fix for bug 854294, by restructering some code we can make sure that
ObjC classes are fully initialized before we use them. Before this checkin
some classes were not fully initialized during subclassing :-(

  • Participants
  • Parent commits 4c11fd0

Comments (0)

Files changed (22)

File pyobjc/Lib/AppKit/test/test_nsview.py

 
     def test_knowsPageRange(self):
         method = ObjCTestNSView_KnowPageRange.knowsPageRange_
-        self.assertEquals(method.signature, "C@:o^{_NSRange=II}")
+        self.assertEquals(method.signature, "c@:o^{_NSRange=II}")
 
 if __name__ == "__main__":
     unittest.main()

File pyobjc/Lib/Foundation/test/test_globals.py

+import unittest
+
+import Foundation
+
+class GlobalFunctionTest (unittest.TestCase):
+    
+    def testMakeNSRect(self):
+        self.assert_(hasattr(Foundation, 'NSMakeRect'))
+
+        self.assertEquals(
+                Foundation.NSMakeRect(1.5, 2.5, 3.5, 4.5), 
+                ((1.5, 2.5), (3.5, 4.5))
+        )
+        self.assertEquals(
+                Foundation.NSMakeRect(1, 2, 3, 4), 
+                ((1.0, 2.0), (3.0, 4.0))
+        )
+
+        self.assertRaises(TypeError, Foundation.NSMakeRect, 1.0, 2.0, 3.0, '4')
+
+    def testMisc(self):
+        self.assert_(hasattr(Foundation, 'NSLogPageSize'))
+        self.assert_(hasattr(Foundation, 'NSRangeFromString'))
+        self.assert_(hasattr(Foundation, 'NSTemporaryDirectory'))
+        self.assert_(hasattr(Foundation, 'NSDecrementExtraRefCountWasZero'))
+
+class GlobalVariablesTest (unittest.TestCase):
+    def testMisc(self):
+        # enum
+        self.assert_(hasattr(Foundation, 'NS_LittleEndian'))
+        self.assert_(hasattr(Foundation, 'NSXMLParserExtraContentError'))
+
+        # NSString
+        self.assert_(hasattr(Foundation, 'NSAppleScriptErrorNumber'))
+        self.assert_(hasattr(Foundation, 'NSConnectionReplyMode'))
+
+        # VAR
+        self.assert_(hasattr(Foundation, 'NSFoundationVersionNumber'))
+
+if __name__ == "__main__":
+    unittest.main()
+

File pyobjc/Lib/Foundation/test/test_nsset.py

         x = NSSet.alloc().initWithObjects_(0,1,2,3,None)
         y = NSSet.setWithObjects_count_(range(10), 4)
         z = NSSet.alloc().initWithObjects_count_(range(10), 4)
+        a = NSSet.alloc().initWithObjects_count_(range(4), None)
 
         self.assert_(len(w) == 4)
         self.assert_(len(x) == 4)
         self.assert_(len(y) == 4)
         self.assert_(len(z) == 4)
+        self.assert_(len(a) == 4)
 
         self.assert_(0 in w)
         self.assert_(1 in x)
         self.assert_(2 in y)
         self.assert_(3 in z)
+        self.assert_(3 in a)
 
     def test_varargsConstruction2(self):
         w = NSMutableSet.setWithObjects_(0,1,2,3,None)

File pyobjc/Lib/objc/test/test_classandinst.py

         self.assertEquals(PyObjC_TestClassAndInstanceClassOverride.alloc().init().isInstance(), objc.YES)
 
     def testClassAndInstanceInstanceOverride(self):
-        self.assertEquals(PyObjC_TestClassAndInstanceInstanceOverride.isInstance(), objc.NO)
+        # Having the next line true would be nice:
+        #self.assertEquals(PyObjC_TestClassAndInstanceInstanceOverride.isInstance(), objc.NO)
+        # But we'll have to settle for this one instead:
+        self.assertEquals(PyObjC_TestClassAndInstanceInstanceOverride.pyobjc_classMethods.isInstance(), objc.NO)
         self.assertEquals(PyObjC_TestClassAndInstanceInstanceOverride.alloc().init().isInstance(), objc.NO)
 
     def testClassAndInstanceSubclass(self):
-        self.assertEquals(PyObjC_TestClassAndInstanceSubclass.isInstance(), objc.NO)
+        # Having the next line true would be nice:
+        #self.assertEquals(PyObjC_TestClassAndInstanceSubclass.isInstance(), objc.NO)
+        # But we'll have to settle for this one instead:
+        self.assertEquals(PyObjC_TestClassAndInstanceSubclass.pyobjc_classMethods.isInstance(), objc.NO)
         self.assertEquals(PyObjC_TestClassAndInstanceSubclass.alloc().init().isInstance(), objc.YES)
 
     def testClassAndInstance(self):
-        self.assertEquals(PyObjC_TestClassAndInstance.isInstance(), objc.NO)
+
+        # Having the next line true would be nice:
+        #self.assertEquals(PyObjC_TestClassAndInstance.isInstance(), objc.NO)
+        # But we'll have to settle for this one instead:
+        self.assertEquals(PyObjC_TestClassAndInstance.pyobjc_classMethods.isInstance(), objc.NO)
         self.assertEquals(PyObjC_TestClassAndInstance.alloc().init().isInstance(), objc.YES)
 
 if __name__ == '__main__':

File pyobjc/Lib/objc/test/test_methodaccess.py

         self.assert_(len(d) > 10)
         self.assert_("init" in d)
 
-        d = dir(o.pyobjc_classMethods)
-        self.assert_(len(d) > 10)
-        self.assert_("alloc" in d)
+        #d = dir(o.pyobjc_classMethods)
+        #self.assert_(len(d) > 10)
+        #self.assert_("alloc" in d)
 
         d = dir(objc.runtime.NSObject.pyobjc_classMethods)
         self.assert_(len(d) > 10)
         self.assert_(len(d) > 10)
         self.assert_("alloc" in d)
 
-        d = o.pyobjc_classMethods.__dict__.keys()
-        self.assert_(len(d) > 10)
-        self.assert_("alloc" in d)
+        #d = o.pyobjc_classMethods.__dict__.keys()
+        #self.assert_(len(d) > 10)
+        #self.assert_("alloc" in d)
 
     def testAttributes(self):
         o = objc.runtime.NSObject.new()
 
         self.assert_(hasattr(o.pyobjc_instanceMethods, "init"))
-        self.assert_(hasattr(o.pyobjc_classMethods, "alloc"))
+        #self.assert_(hasattr(o.pyobjc_classMethods, "alloc"))
 
         self.assert_(hasattr(objc.runtime.NSObject.pyobjc_classMethods, "alloc"))
 
+class ClassAndInstanceMethods(unittest.TestCase):
+    def testClassThroughInstance(self):
+        # Class methods are not accessible through instances.
+        self.assertRaises(AttributeError, getattr, objc.runtime.NSObject.new(), 'alloc')
+
 if __name__ == "__main__":
     unittest.main()

File pyobjc/Lib/objc/test/test_methods.py

     def testFloat(self):
         # Fails, possibly rounding error
         obj = OC_TestClass1.new()
-        obj.clsReset()
+        obj.reset()
         self.assertEquals(obj.floatFunc(), makeCFloat(0.128))
         self.assertEquals(obj.floatFunc(), makeCFloat(1.0))
         self.assertEquals(obj.floatFunc(), makeCFloat(42.0))
 
     def testDouble(self):
         obj = OC_TestClass1.new()
-        obj.clsReset()
+        obj.reset()
         self.assertEquals(obj.doubleFunc(), 0.128)
         self.assertEquals(obj.doubleFunc(), 1.0)
         self.assertEquals(obj.doubleFunc(), 42.0)
     def testCharp(self):
         obj = OC_TestClass1.new()
         obj.reset()
-        self.assertEquals(obj.charpClsFunc(), 'hello')
-        self.assertEquals(obj.charpClsFunc(), 'world')
-        self.assertEquals(obj.charpClsFunc(), 'foobar')
+        self.assertEquals(obj.charpFunc(), 'hello')
+        self.assertEquals(obj.charpFunc(), 'world')
+        self.assertEquals(obj.charpFunc(), 'foobar')
 
     def testID(self):
         obj = OC_TestClass1.new()
         obj.reset()
-        self.assertEquals(len(obj.idClsFunc()), 0)
-        self.assertEquals(type(obj.idClsFunc()).__name__, 'NSHost')
-        self.assertEquals(str(obj.idClsFunc()), '{}')
-        self.assertEquals(obj.idClsFunc(), None)
+        self.assertEquals(len(obj.idFunc()), 0)
+        self.assertEquals(type(obj.idFunc()).__name__, 'NSHost')
+        self.assertEquals(str(obj.idFunc()), '{}')
+        self.assertEquals(obj.idFunc(), None)
 
     def testStruct1(self):
         obj = OC_TestClass1.new()

File pyobjc/Lib/objc/test/testbndl.m

 	PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN));
 	PyModule_AddObject(m, "FLT_EPSILON", PyFloat_FromDouble(FLT_EPSILON));
 }
+

File pyobjc/Modules/Foundation/_Foundation.m

 	return 0;
 }
 
+
+static PyObject* call_objWithObjects_count_(
+		PyObject* method, PyObject* self, PyObject* arguments)
+{
+	PyObject* result;
+	struct objc_super super;
+	PyObject* objectList;
+	PyObject* objectCount;
+	id* objects;
+	int count;
+	int arrayToken;
+	id  res;
+
+	if  (!PyArg_ParseTuple(arguments, "OO", &objectList, &objectCount)) {
+		return NULL;
+	}
+
+	arrayToken = PyObjC_PythonToCArray(@encode(id),
+			objectList, objectCount,
+			(void**)&objects, &count);
+	if (arrayToken == -1) {
+		return NULL;
+	}
+
+	NS_DURING
+		PyObjC_InitSuper(&super, 
+			PyObjCSelector_GetClass(method),
+			PyObjCObject_GetObject(self));
+
+		res = objc_msgSendSuper(&super,
+				PyObjCSelector_GetSelector(method),
+				objects, count);
+	NS_HANDLER
+		PyObjCErr_FromObjC(localException);
+		res = nil;
+	NS_ENDHANDLER
+
+	PyObjC_FreeCArray(arrayToken, objects);
+
+	if (res == nil && PyErr_Occurred()) {
+		return NULL;
+	}
+	
+	result = PyObjC_IdToPython(res);
+
+	return result;
+}
+
+static id imp_objWithObjects_count_(id self, SEL sel, id* objects, int count)
+{
+	PyObject* result;
+	PyObject* arglist;
+	PyObject* v;
+	id  returnValue;
+
+	PyGILState_STATE state = PyGILState_Ensure();
+
+	arglist = PyTuple_New(3);
+	if (arglist == NULL) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+
+	v = PyObjC_IdToPython(self);
+	if (v == NULL) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+
+	PyTuple_SET_ITEM(arglist, 0, v);
+
+	v = PyObjC_CArrayToPython(@encode(id), objects, count);
+	if (v == NULL) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+	PyTuple_SET_ITEM(arglist, 1, v);
+
+	v = PyInt_FromLong(count);
+	if (v == NULL) {	
+		Py_DECREF(arglist);
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+	PyTuple_SET_ITEM(arglist, 2,  v);
+
+	result = PyObjC_CallPython(self, sel, arglist, NULL);
+	Py_DECREF(arglist);
+	if (result == NULL) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+
+	returnValue = PyObjC_PythonToId(result);
+	Py_DECREF(result);
+	if (PyErr_Occurred()) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+	PyGILState_Release(state);
+	return returnValue;
+}
+
+
+static PyObject* call_clsWithObjects_count_(
+		PyObject* method, PyObject* self, PyObject* arguments)
+{
+	PyObject* result;
+	struct objc_super super;
+	PyObject* objectList;
+	PyObject* objectCount;
+	id* objects;
+	int count;
+	int arrayToken;
+	id  res;
+
+	if  (!PyArg_ParseTuple(arguments, "OO", &objectList, &objectCount)) {
+		return NULL;
+	}
+
+	arrayToken = PyObjC_PythonToCArray(
+			@encode(id), 
+			objectList, objectCount,
+			(void**)&objects, &count);
+	if (arrayToken == -1) {
+		return NULL;
+	}
+
+	NS_DURING
+		PyObjC_InitSuperCls(&super, 
+			PyObjCSelector_GetClass(method),
+			PyObjCClass_GetClass(self));
+
+		res = objc_msgSendSuper(&super,
+				PyObjCSelector_GetSelector(method),
+				objects, count);
+	NS_HANDLER
+		PyObjCErr_FromObjC(localException);
+		res = nil;
+	NS_ENDHANDLER
+
+	PyObjC_FreeCArray(arrayToken, objects);
+
+	if (res == nil && PyErr_Occurred()) {
+		return NULL;
+	}
+	
+	result = PyObjC_IdToPython(res);
+
+	return result;
+}
+
+static id imp_clsWithObjects_count_(id self, SEL sel, id* objects, int count)
+{
+	PyObject* result;
+	PyObject* arglist;
+	PyObject* v;
+	id  returnValue;
+	PyGILState_STATE state = PyGILState_Ensure();
+
+	arglist = PyTuple_New(3);
+	if (arglist == NULL) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+
+	v = PyObjC_IdToPython(self);
+	if (v == NULL) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+
+	PyTuple_SET_ITEM(arglist, 0, v);
+
+	v = PyObjC_CArrayToPython(@encode(id), objects, count);
+	if (v == NULL) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+
+	PyTuple_SET_ITEM(arglist, 1, v);
+
+	v = PyInt_FromLong(count);
+	if (v == NULL) {	
+		Py_DECREF(arglist);
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+	PyTuple_SET_ITEM(arglist, 2,  v);
+
+	result = PyObjC_CallPython(self, sel, arglist, NULL);
+	Py_DECREF(arglist);
+	if (result == NULL) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+
+	returnValue = PyObjC_PythonToId(result);
+	Py_DECREF(result);
+	if (PyErr_Occurred()) {
+		PyObjCErr_ToObjCWithGILState(&state);
+		return nil;
+	}
+	PyGILState_Release(state);
+	return returnValue;
+}
+
+
 /*
  * Include the implementation of difficult methods.
  */

File pyobjc/Modules/Foundation/_FoundationMapping_NSArray.m

 }
 #endif
 
-static PyObject* call_NSArray_arrayWithObjects_count_(
-		PyObject* method, PyObject* self, PyObject* arguments)
-{
-	PyObject* result;
-	int err;
-	struct objc_super super;
-	PyObject* objectList;
-	PyObject* objectSeq;
-	id* objects;
-	int count;
-	int i;
-	id  res;
-
-	if  (!PyArg_ParseTuple(arguments, "Oi", &objectList, &count)) {
-		return NULL;
-	}
-
-	objectSeq = PySequence_Fast(objectList, "objects not a sequence");
-	if (objectSeq == NULL) {
-		return NULL;
-	}
-
-	if (PySequence_Fast_GET_SIZE(objectSeq) < count) {
-		PyErr_SetString(PyExc_ValueError, "too few objects");
-		Py_DECREF(objectSeq);
-		return NULL;
-	}
-
-	objects = alloca(sizeof(id) * count);
-	if (objects == NULL) {
-		Py_DECREF(objectSeq);
-		PyErr_NoMemory();
-		return NULL;
-	}
-
-	for (i = 0; i < count; i++) {
-		err = PyObjC_PythonToObjC(@encode(id), 
-			PySequence_Fast_GET_ITEM(objectSeq, i), objects + i);
-		if (err == -1) {
-			Py_DECREF(objectSeq);
-			PyErr_NoMemory();
-			return NULL;
-		}
-	}
-
-	NS_DURING
-		PyObjC_InitSuperCls(&super, 
-			PyObjCSelector_GetClass(method),
-			PyObjCClass_GetClass(self));
-
-			
-		res = objc_msgSendSuper(&super,
-				PyObjCSelector_GetSelector(method),
-				objects, count);
-	NS_HANDLER
-		PyObjCErr_FromObjC(localException);
-		res = nil;
-	NS_ENDHANDLER
-
-	Py_DECREF(objectSeq);
-
-	if (res == nil && PyErr_Occurred()) {
-		return NULL;
-	}
-	
-	result = PyObjC_IdToPython(res);
-
-	return result;
-}
-
-static id imp_NSArray_arrayWithObjects_count_(id self, SEL sel,
-		id* objects, int count)
-{
-	PyObject* result;
-	PyObject* arglist;
-	PyObject* v;
-	int i;
-	id  returnValue;
-	PyGILState_STATE state = PyGILState_Ensure();
-
-	arglist = PyTuple_New(3);
-	if (arglist == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	v = PyObjC_IdToPython(self);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	PyTuple_SET_ITEM(arglist, 0, v);
-
-	v = PyTuple_New(count);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	for (i = 0; i < count; i++) {
-		PyTuple_SET_ITEM(v, i, PyObjC_IdToPython(objects[i]));
-		if (PyTuple_GET_ITEM(v, i) == NULL) {
-			Py_DECREF(v);
-			Py_DECREF(arglist);
-			PyObjCErr_ToObjCWithGILState(&state);
-			return nil;
-		}
-	}
-	PyTuple_SET_ITEM(arglist, 1, v);
-
-	v = PyInt_FromLong(count);
-	if (v == NULL) {	
-		Py_DECREF(arglist);
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyTuple_SET_ITEM(arglist, 2,  v);
-
-	result = PyObjC_CallPython(self, sel, arglist, NULL);
-	Py_DECREF(arglist);
-	if (result == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	returnValue = PyObjC_PythonToId(result);
-	Py_DECREF(result);
-	if (PyErr_Occurred()) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyGILState_Release(state);
-	return returnValue;
-}
-
-static PyObject* call_NSArray_arrayByAddingObjects_count_(
-		PyObject* method, PyObject* self, PyObject* arguments)
-{
-	PyObject* result;
-	int err;
-	struct objc_super super;
-	PyObject* objectList;
-	PyObject* objectSeq;
-	id* objects;
-	int count;
-	int i;
-	id  res;
-
-	if  (!PyArg_ParseTuple(arguments, "Oi", &objectList, &count)) {
-		return NULL;
-	}
-
-	objectSeq = PySequence_Fast(objectList, "objects not a sequence");
-	if (objectSeq == NULL) {
-		return NULL;
-	}
-
-	if (PySequence_Fast_GET_SIZE(objectSeq) < count) {
-		PyErr_SetString(PyExc_ValueError, "too few objects");
-		Py_DECREF(objectSeq);
-		return NULL;
-	}
-
-	objects = alloca(sizeof(id) * count);
-	if (objects == NULL) {
-		Py_DECREF(objectSeq);
-		PyErr_NoMemory();
-		return NULL;
-	}
-
-	for (i = 0; i < count; i++) {
-		err = PyObjC_PythonToObjC(@encode(id), 
-			PySequence_Fast_GET_ITEM(objectSeq, i), objects + i);
-		if (err == -1) {
-			Py_DECREF(objectSeq);
-			PyErr_NoMemory();
-			return NULL;
-		}
-	}
-
-	NS_DURING
-		PyObjC_InitSuper(&super, 
-			PyObjCSelector_GetClass(method),
-			PyObjCObject_GetObject(self));
-
-			
-		res = objc_msgSendSuper(&super,
-				PyObjCSelector_GetSelector(method),
-				objects, count);
-	NS_HANDLER
-		PyObjCErr_FromObjC(localException);
-		res = nil;
-	NS_ENDHANDLER
-
-	Py_DECREF(objectSeq);
-
-	if (res == nil && PyErr_Occurred()) {
-		return NULL;
-	}
-	
-	result = PyObjC_IdToPython(res);
-
-	return result;
-}
-
-static id imp_NSArray_arrayByAddingObjects_count_(id self, SEL sel,
-		id* objects, int count)
-{
-	PyObject* result;
-	PyObject* arglist;
-	PyObject* v;
-	int i;
-	id  returnValue;
-
-	PyGILState_STATE state = PyGILState_Ensure();
-
-	arglist = PyTuple_New(3);
-	if (arglist == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	v = PyObjC_IdToPython(self);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	PyTuple_SET_ITEM(arglist, 0, v);
-
-	v = PyTuple_New(count);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	for (i = 0; i < count; i++) {
-		PyTuple_SET_ITEM(v, i, PyObjC_IdToPython(objects[i]));
-		if (PyTuple_GET_ITEM(v, i) == NULL) {
-			Py_DECREF(v);
-			Py_DECREF(arglist);
-			PyObjCErr_ToObjCWithGILState(&state);
-			return nil;
-		}
-	}
-	PyTuple_SET_ITEM(arglist, 1, v);
-
-	v = PyInt_FromLong(count);
-	if (v == NULL) {	
-		Py_DECREF(arglist);
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyTuple_SET_ITEM(arglist, 2,  v);
-
-	result = PyObjC_CallPython(self, sel, arglist, NULL);
-	Py_DECREF(arglist);
-	if (result == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	returnValue = PyObjC_PythonToId(result);
-	Py_DECREF(result);
-	if (PyErr_Occurred()) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyGILState_Release(state);
-	return returnValue;
-}
-
-static PyObject* call_NSArray_initWithObjects_count_(
-		PyObject* method, PyObject* self, PyObject* arguments)
-{
-	PyObject* result;
-	int err;
-	struct objc_super super;
-	PyObject* objectList;
-	PyObject* objectSeq;
-	id* objects;
-	int count;
-	int i;
-	id  res;
-
-	if  (!PyArg_ParseTuple(arguments, "Oi", &objectList, &count)) {
-		return NULL;
-	}
-
-	objectSeq = PySequence_Fast(objectList, "objects not a sequence");
-	if (objectSeq == NULL) {
-		return NULL;
-	}
-
-	if (PySequence_Fast_GET_SIZE(objectSeq) < count) {
-		PyErr_SetString(PyExc_ValueError, "too few objects");
-		Py_DECREF(objectSeq);
-		return NULL;
-	}
-
-	objects = alloca(sizeof(id) * count);
-	if (objects == NULL) {
-		Py_DECREF(objectSeq);
-		PyErr_NoMemory();
-		return NULL;
-	}
-
-	for (i = 0; i < count; i++) {
-		err = PyObjC_PythonToObjC(@encode(id), 
-			PySequence_Fast_GET_ITEM(objectSeq, i), objects + i);
-		if (err == -1) {
-			Py_DECREF(objectSeq);
-			PyErr_NoMemory();
-			return NULL;
-		}
-	}
-
-	NS_DURING
-		PyObjC_InitSuper(&super, 
-			PyObjCSelector_GetClass(method),
-			PyObjCObject_GetObject(self));
-
-			
-		res = objc_msgSendSuper(&super,
-				PyObjCSelector_GetSelector(method),
-				objects, count);
-	NS_HANDLER
-		PyObjCErr_FromObjC(localException);
-		res = nil;
-	NS_ENDHANDLER
-
-	Py_DECREF(objectSeq);
-
-	if (res == nil && PyErr_Occurred()) {
-		return NULL;
-	}
-	
-	result = PyObjC_IdToPython(res);
-
-	return result;
-}
-
-static id imp_NSArray_initWithObjects_count_(id self, SEL sel,
-		id* objects, int count)
-{
-	PyObject* result;
-	PyObject* arglist;
-	PyObject* v;
-	int i;
-	id  returnValue;
-
-	PyGILState_STATE state = PyGILState_Ensure();
-
-	arglist = PyTuple_New(3);
-	if (arglist == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	v = PyObjC_IdToPython(self);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	PyTuple_SET_ITEM(arglist, 0, v);
-
-	v = PyTuple_New(count);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	for (i = 0; i < count; i++) {
-		PyTuple_SET_ITEM(v, i, PyObjC_IdToPython(objects[i]));
-		if (PyTuple_GET_ITEM(v, i) == NULL) {
-			Py_DECREF(v);
-			Py_DECREF(arglist);
-			PyObjCErr_ToObjCWithGILState(&state);
-			return nil;
-		}
-	}
-	PyTuple_SET_ITEM(arglist, 1, v);
-
-	v = PyInt_FromLong(count);
-	if (v == NULL) {	
-		Py_DECREF(arglist);
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyTuple_SET_ITEM(arglist, 2,  v);
-
-	result = PyObjC_CallPython(self, sel, arglist, NULL);
-	Py_DECREF(arglist);
-	if (result == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	returnValue = PyObjC_PythonToId(result);
-	Py_DECREF(result);
-	if (PyErr_Occurred()) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyGILState_Release(state);
-	return returnValue;
-}
 
 static int 
 _pyobjc_install_NSArray(void)
 	if (PyObjC_RegisterMethodMapping(
 		classNSArray,
 		@selector(arrayByAddingObjects:count:),
-		call_NSArray_arrayByAddingObjects_count_,
-		(IMP)imp_NSArray_arrayByAddingObjects_count_) < 0) {
+		call_objWithObjects_count_,
+		(IMP)imp_objWithObjects_count_) < 0) {
 
 		return -1;
 	}
 	if (PyObjC_RegisterMethodMapping(
 		classNSArray,
 		@selector(arrayWithObjects:count:),
-		call_NSArray_arrayWithObjects_count_,
-		(IMP)imp_NSArray_arrayWithObjects_count_) < 0) {
+		call_clsWithObjects_count_,
+		(IMP)imp_clsWithObjects_count_) < 0) {
 
 		return -1;
 	}
 	if (PyObjC_RegisterMethodMapping(
 		classNSArray,
 		@selector(initWithObjects:count:),
-		call_NSArray_initWithObjects_count_,
-		(IMP)imp_NSArray_initWithObjects_count_) < 0) {
+		call_objWithObjects_count_,
+		(IMP)imp_objWithObjects_count_)) {
 
 		return -1;
 	}

File pyobjc/Modules/Foundation/_FoundationMapping_NSSet.m

 #include <Foundation/Foundation.h>
 #include "pyobjc-api.h"
 
-static PyObject* call_NSSet_setWithObjects_count_(
-		PyObject* method, PyObject* self, PyObject* arguments)
-{
-	PyObject* result;
-	int err;
-	struct objc_super super;
-	PyObject* objectList;
-	PyObject* objectSeq;
-	id* objects;
-	int count;
-	int i;
-	id  res;
-
-	if  (!PyArg_ParseTuple(arguments, "Oi", &objectList, &count)) {
-		return NULL;
-	}
-
-	objectSeq = PySequence_Fast(objectList, "objects not a sequence");
-	if (objectSeq == NULL) {
-		return NULL;
-	}
-
-	if (PySequence_Fast_GET_SIZE(objectSeq) < count) {
-		PyErr_SetString(PyExc_ValueError, "too few objects");
-		Py_DECREF(objectSeq);
-		return NULL;
-	}
-
-	objects = alloca(sizeof(id) * count);
-	if (objects == NULL) {
-		Py_DECREF(objectSeq);
-		PyErr_NoMemory();
-		return NULL;
-	}
-
-	for (i = 0; i < count; i++) {
-		err = PyObjC_PythonToObjC(@encode(id), 
-			PySequence_Fast_GET_ITEM(objectSeq, i), objects + i);
-		if (err == -1) {
-			Py_DECREF(objectSeq);
-			PyErr_NoMemory();
-			return NULL;
-		}
-	}
-
-	NS_DURING
-		PyObjC_InitSuperCls(&super, 
-			PyObjCSelector_GetClass(method),
-			PyObjCClass_GetClass(self));
-
-			
-		res = objc_msgSendSuper(&super,
-				@selector(setWithObjects:count:),
-				objects, count);
-	NS_HANDLER
-		PyObjCErr_FromObjC(localException);
-		res = nil;
-	NS_ENDHANDLER
-
-	Py_DECREF(objectSeq);
-
-	if (res == nil && PyErr_Occurred()) {
-		return NULL;
-	}
-	
-	result = PyObjC_IdToPython(res);
-
-	return result;
-}
-
-static id imp_NSSet_setWithObjects_count_(id self, SEL sel,
-		id* objects, int count)
-{
-	PyObject* result;
-	PyObject* arglist;
-	PyObject* v;
-	int i;
-	id  returnValue;
-
-	PyGILState_STATE state = PyGILState_Ensure();
-
-	arglist = PyTuple_New(3);
-	if (arglist == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	v = PyObjC_IdToPython(self);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	PyTuple_SET_ITEM(arglist, 0, v);
-
-	v = PyTuple_New(count);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	for (i = 0; i < count; i++) {
-		PyTuple_SET_ITEM(v, i, PyObjC_IdToPython(objects[i]));
-		if (PyTuple_GET_ITEM(v, i) == NULL) {
-			Py_DECREF(v);
-			Py_DECREF(arglist);
-			PyObjCErr_ToObjCWithGILState(&state);
-			return nil;
-		}
-	}
-	PyTuple_SET_ITEM(arglist, 1, v);
-
-	v = PyInt_FromLong(count);
-	if (v == NULL) {	
-		Py_DECREF(arglist);
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyTuple_SET_ITEM(arglist, 2,  v);
-
-	result = PyObjC_CallPython(self, sel, arglist, NULL);
-	Py_DECREF(arglist);
-	if (result == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	returnValue = PyObjC_PythonToId(result);
-	Py_DECREF(result);
-	if (PyErr_Occurred()) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyGILState_Release(state);
-	return returnValue;
-}
-
-static PyObject* call_NSSet_initWithObjects_count_(
-		PyObject* method, PyObject* self, PyObject* arguments)
-{
-	PyObject* result;
-	int err;
-	struct objc_super super;
-	PyObject* objectList;
-	PyObject* objectSeq;
-	id* objects;
-	int count;
-	int i;
-	id  res;
-
-	if  (!PyArg_ParseTuple(arguments, "Oi", &objectList, &count)) {
-		return NULL;
-	}
-
-	objectSeq = PySequence_Fast(objectList, "objects not a sequence");
-	if (objectSeq == NULL) {
-		return NULL;
-	}
-
-	if (PySequence_Fast_GET_SIZE(objectSeq) < count) {
-		PyErr_SetString(PyExc_ValueError, "too few objects");
-		Py_DECREF(objectSeq);
-		return NULL;
-	}
-
-	objects = alloca(sizeof(id) * count);
-	if (objects == NULL) {
-		Py_DECREF(objectSeq);
-		PyErr_NoMemory();
-		return NULL;
-	}
-
-	for (i = 0; i < count; i++) {
-		err = PyObjC_PythonToObjC(@encode(id), 
-			PySequence_Fast_GET_ITEM(objectSeq, i), objects + i);
-		if (err == -1) {
-			Py_DECREF(objectSeq);
-			PyErr_NoMemory();
-			return NULL;
-		}
-	}
-
-	NS_DURING
-		PyObjC_InitSuper(&super, 
-			PyObjCSelector_GetClass(method),
-			PyObjCObject_GetObject(self));
-
-			
-		res = objc_msgSendSuper(&super,
-				@selector(initWithObjects:count:),
-				objects, count);
-	NS_HANDLER
-		PyObjCErr_FromObjC(localException);
-		res = nil;
-	NS_ENDHANDLER
-
-	Py_DECREF(objectSeq);
-
-	if (res == nil && PyErr_Occurred()) {
-		return NULL;
-	}
-	
-	result = PyObjC_IdToPython(res);
-
-	return result;
-}
-
-static id imp_NSSet_initWithObjects_count_(id self, SEL sel,
-		id* objects, int count)
-{
-	PyObject* result;
-	PyObject* arglist;
-	PyObject* v;
-	int i;
-	id  returnValue;
-
-	PyGILState_STATE state = PyGILState_Ensure();
-
-	arglist = PyTuple_New(3);
-	if (arglist == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	v = PyObjC_IdToPython(self);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	PyTuple_SET_ITEM(arglist, 0, v);
-
-	v = PyTuple_New(count);
-	if (v == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	for (i = 0; i < count; i++) {
-		PyTuple_SET_ITEM(v, i, PyObjC_IdToPython(objects[i]));
-		if (PyTuple_GET_ITEM(v, i) == NULL) {
-			Py_DECREF(v);
-			Py_DECREF(arglist);
-			PyObjCErr_ToObjCWithGILState(&state);
-			return nil;
-		}
-	}
-	PyTuple_SET_ITEM(arglist, 1, v);
-
-	v = PyInt_FromLong(count);
-	if (v == NULL) {	
-		Py_DECREF(arglist);
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyTuple_SET_ITEM(arglist, 2,  v);
-
-	result = PyObjC_CallPython(self, sel, arglist, NULL);
-	Py_DECREF(arglist);
-	if (result == NULL) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-
-	returnValue = PyObjC_PythonToId(result);
-	Py_DECREF(result);
-	if (PyErr_Occurred()) {
-		PyObjCErr_ToObjCWithGILState(&state);
-		return nil;
-	}
-	PyGILState_Release(state);
-	return returnValue;
-}
-
 static int 
 _pyobjc_install_NSSet(void)
 {
 	if (PyObjC_RegisterMethodMapping(
 		classNSSet,
 		@selector(setWithObjects:count:),
-		call_NSSet_setWithObjects_count_,
-		(IMP)imp_NSSet_setWithObjects_count_) < 0) {
+		call_clsWithObjects_count_,
+		(IMP)imp_clsWithObjects_count_) < 0) {
 
 		return -1;
 	}
 	if (PyObjC_RegisterMethodMapping(
 		classNSSet,
 		@selector(initWithObjects:count:),
-		call_NSSet_initWithObjects_count_,
-		(IMP)imp_NSSet_initWithObjects_count_) < 0) {
+		call_objWithObjects_count_,
+		(IMP)imp_objWithObjects_count_) < 0) {
 
 		return -1;
 	}

File pyobjc/Modules/Foundation/_FoundationMapping_NSStream.m

 static PyObject* call_NSInputStream_read_maxLength_(
 		PyObject* method, PyObject* self, PyObject* arguments)
 {
-	char* buf;
 	int   bytes_len;
 	int	  bytes_read;
 	PyObject*	result;
 		return NULL;
 	}
 
-    result = PyString_FromStringAndSize((char *)0, bytes_len);
+	result = PyString_FromStringAndSize((char *)0, bytes_len);
 	if (result == NULL)
 		return NULL;
 	

File pyobjc/Modules/objc/libffi_support.m

 	}
 }
 
+
 PyObject *
 ObjC_FFICaller(PyObject *aMeth, PyObject* self, PyObject *args)
 {
 
 	/* First count the number of by reference parameters, and the number
 	 * of bytes of storage needed for them. Note that arguments 0 and 1
-	 * are self and the selector, no need to count counted or checked those.
+	 * are self and the selector, no need to count those.
 	 */
 	argbuf_len = resultSize;
 

File pyobjc/Modules/objc/module.m

 
 void init_objc(void);
 
-
 void init_objc(void)
 {
 	PyObject *m, *d;

File pyobjc/Modules/objc/objc-class.m

 
 	Py_DECREF(attributes);
 
+	/* If all else fails, ask the actual class (getattro also does this) */
+	NS_DURING
+		result = PyObjCSelector_FindNative(cls, 
+				PyObjCRT_SELName(selector));
+	NS_HANDLER
+		PyObjCErr_FromObjC(localException);
+		result = NULL;
+	NS_ENDHANDLER
+
+	if (result) {
+		return result;
+	}
+
 	ObjCErr_Set(PyExc_AttributeError,
 		"No selector %s", PyObjCRT_SELName(selector));
 	PyDict_SetItemString(info->sel_to_py, 

File pyobjc/Modules/objc/objc-object.m

 		     "'%.50s' object has no attribute '%.400s'",
 		     tp->tp_name, namestr);
   done:
+	if (res != NULL) {
+		/* class methods cannot be accessed through instances */
+		if (PyObjCSelector_Check(res) 
+				&& PyObjCSelector_IsClassMethod(res)) {
+			PyErr_Format(PyExc_AttributeError,
+			     "'%.50s' object has no attribute '%.400s'",
+			     tp->tp_name, PyString_AS_STRING(name));
+			Py_DECREF(res);
+			res = NULL;
+		}
+	}
+
 	Py_DECREF(name);
 	return res;
 }
 }
 
 static PyGetSetDef obj_getset[] = {
+#if 0
 	{
 		"pyobjc_classMethods",
 		(getter)obj_get_classMethods,
 		obj_get_classMethods_doc,
 		0
 	},
+#endif
 	{
 		"pyobjc_instanceMethods",
 		(getter)obj_get_instanceMethods,

File pyobjc/Modules/objc/selector.m

 	int       is_class_method = 0;
 	Class     oc_class = PyObjCClass_GetClass(template_class);
 	PyObject* value;
+	PyObject* super_sel;
 
 	if (oc_class == NULL) {
 		return NULL;
 		selector = PyObjCSelector_DefaultSelector(oc_name);
 	}
 
+	/* XXX: This seriously fails if a class method has a different signature
+	 * than an instance method of the same name!
+	 *
+	 *
+	 * We eagerly call PyObjCClass_FindSelector because some ObjC
+	 * classes are not fully initialized until they are actually used,
+	 * and the code below doesn't seem to count but PyObjCClass_FindSelector
+	 * is.
+	 */
+	super_sel = PyObjCClass_FindSelector(template_class, selector);
+
 	if (is_class_method) {
 		meth = class_getClassMethod(oc_class, selector);
 	} else {
 		 * the user may have specified a more exact
 		 * signature!
 		 */
-		PyObject* super_sel = PyObjCClass_FindSelector(
-			template_class, selector);
 		if (super_sel == NULL) {
 			return NULL;
 		}
 	} else {
 		char* signature = NULL;
 
+		PyErr_Clear(); /* The call to PyObjCClass_FindSelector failed */
 		if (protocols != NULL) {
 			signature = find_protocol_signature(
 					protocols, selector);

File pyobjc/Modules/objc/unittest.m

 	ASSERT_STREQUALS("@@:{_NSPoint=ff}i", b);
 END_UNITTEST
 
+
 static PyMethodDef unittest_methods[] = {
 	TESTDEF(CheckNSInvoke),
+
 	TESTDEF(StructSize),	
 	TESTDEF(StructAlign),	
 	TESTDEF(FillStruct1),	
 Version "Panther" (Off-CVS)
 ---------------------------
 
+- Backward incompatible change: class methods are no longer callable through
+  the instances.
+
 - Integrates full support for MacOS X 10.3 (aka Panther)
 
 - Adds a convenience/wrapper module for SecurityInterface

File pyobjc/Scripts/CodeGenerators/cocoa_generator.py

         func_builder.FUNC_MAP['NSBeginCriticalAlertSheet'] = BeginSheetMapper
 
         fd = dupfile('build/codegen/_Fnd_Functions.inc', 'w')
-        structs = ['NSPoint', 'NSSize', 'NSRect', 'NSRange', 'NSSwappedDouble', 'NSSwappedFloat']
+        structs = ['NSPoint', 'NSSize', 'NSRect', 'NSRange', 'NSSwappedFloat', 'NSSwappedDouble']
         for s in structs:
             func_builder.SIMPLE_TYPES[s] = (
                 '\tresult = PyObjC_ObjCToPython(@encode(%s), (void*)&%%(varname)s); \n\tif (result == NULL) return NULL;'%s,

File pyobjc/Scripts/CodeGenerators/func_builder.py

 
 # Function mapping
 FUNC_MAP = {}
+DEFAULT_FUNCMAP=None
+
+# FUNCMAPS can set an argument-type to this value ('is' not '==') to remove
+# the argument from the python interface and force it to a specific value.
+FORCE_VALUE="ForceValue"
 
 HDR="""\
 /*
     )
 
 def hidden_from_python(typestr):
+    if typestr is FORCE_VALUE: return 1
     if typestr.startswith('const ') or typestr.startswith('const\t'):
         typestr = typestr[6:].strip()
 
 
     if FUNC_MAP.has_key(funcname):
         arguments = FUNC_MAP[funcname](funcname, arguments)
+    elif DEFAULT_FUNCMAP is not None:
+        arguments = DEFAULT_FUNCMAP(funcname, arguments)
 
 
     for tp, name in arguments:
+        if tp is FORCE_VALUE: continue
         if not is_simple_type(tp):
             raise ValueError, "Complex function (arg of type %s)"%(tp,)
 
     fmt = ''
     arglist = ''
     for tp, name in arguments:
+        if tp is FORCE_VALUE: continue
         fmt += parsetuple_fmt(tp)
         v =parsetuple_arguments(tp, "objc_%s"%name)
         if v:
         fp.write("\t\tobjc_result = %s(\n"%funcname,)
     else:
         fp.write("\t\t%s(\n"%funcname,)
-    sep = ""
+    sep = "\t\t\t\t"
     for tp, name in arguments:
-        fp.write("%sobjc_%s"%(sep, name))
-        sep = ", "
+        if tp is FORCE_VALUE:
+            fp.write("%s%s"%(sep, name))
+        else:
+            fp.write("%sobjc_%s"%(sep, name))
+        sep = ",\n\t\t\t\t"
     fp.write(");\n")
     fp.write("\tNS_HANDLER\n")
     fp.write("\t\tPyObjCErr_FromObjC(localException);\n")
             sys.stderr.write("Converting '%s' ..."%l.strip())
             sys.stderr.write("failed: %s\n"%msg)
             sys.stderr.flush()
-            raise
 
     fp.write("\n")
 

File pyobjc/Scripts/CodeGenerators/func_collector.py

 
 def process_file(outfp, filename, match_prefix='', ignore_list=()):
 
-    MATCH_RE=re.compile('%(match_prefix)s(.+\s+.+\(.*\)\s*[;{])'%{
+    MATCH_RE=re.compile('%(match_prefix)s(.+\s+.+\([^);{]+\)\s*[;{])'%{
             'match_prefix':match_prefix, 'IDENT':IDENT})
 
     fp = open(filename, 'r')

File pyobjc/setup.py

             print >>sys.stderr, "LIBFFI can not build correctly in a path that contains spaces."
             print >>sys.stderr, "This limitation includes the entire path (all parents, etc.)"
             print >>sys.stderr, "Move the PyObjC and libffi source to a path without spaces and build again."
-            sys.exit(1)
+            #sys.exit(1)
 
         inst_dir = inst_dir.replace("'", "'\"'\"'")
         src_path = src_path.replace("'", "'\"'\"'")
         "Modules/objc/module.m",
         "Modules/objc/libffi_support.m",
         "Modules/objc/pointer-support.m",
+        #"Modules/objc/generic-callable.m",
 ]
 
 # On GNUstep we can read some configuration from the environment.