Commits

lakka committed dc3848a Merge

Merging upstream

Comments (0)

Files changed (21)

pyobjc-core/Modules/objc/OC_PythonArray.m

  */
 -(void)pyobjcSetValue:(NSObject*)other
 {
-	PyObject* v = PyObjC_IdToPython(other);
-	Py_XDECREF(value);
-	value = v;
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* v = PyObjC_IdToPython(other);
+		Py_XDECREF(value);
+		value = v;
+	PyObjC_END_WITH_GIL
 }
 
 -(id)initWithCoder:(NSCoder*)coder
 	PyObject* t;
 	int code;
         int size;
+
 	if ([coder allowsKeyedCoding]) {
 		code = [coder decodeInt32ForKey:@"pytype"];
 	} else {
 				if (proxy == NULL) {
 					PyObjC_RegisterObjCProxy(value, self);
 				} else {
+					[proxy retain];
 					[self release];
-					[proxy retain];
 					self = (OC_PythonArray*)proxy;
 				}
 

pyobjc-core/Modules/objc/OC_PythonDate.m

  */
 -(void)pyobjcSetValue:(NSObject*)other
 {
-	PyObject* v = PyObjC_IdToPython(other);
-	Py_XDECREF(value);
-	value = v;
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* v = PyObjC_IdToPython(other);
+		Py_XDECREF(value);
+		value = v;
+	PyObjC_END_WITH_GIL
 }
 
 -(id)initWithCoder:(NSCoder*)coder

pyobjc-core/Modules/objc/OC_PythonDictionary.m

  */
 -(void)pyobjcSetValue:(NSObject*)other
 {
-	PyObject* v = PyObjC_IdToPython(other);
-	Py_XDECREF(value);
-	value = v;
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* v = PyObjC_IdToPython(other);
+		Py_XDECREF(value);
+		value = v;
+	PyObjC_END_WITH_GIL
 }
 
 - (id)initWithCoder:(NSCoder*)coder

pyobjc-core/Modules/objc/OC_PythonNumber.m

  */
 -(void)pyobjcSetValue:(NSObject*)other
 {
-	PyObject* v = PyObjC_IdToPython(other);
-	Py_XDECREF(value);
-	value = v;
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* v = PyObjC_IdToPython(other);
+		Py_XDECREF(value);
+		value = v;
+	PyObjC_END_WITH_GIL
 }
 
 - (id)initWithCoder:(NSCoder*)coder

pyobjc-core/Modules/objc/OC_PythonObject.m

  */
 -(void)pyobjcSetValue:(NSObject*)other
 {
-	PyObject* value = PyObjC_IdToPython(other);
-	Py_XDECREF(pyObject);
-	pyObject = value;
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* value = PyObjC_IdToPython(other);
+		Py_XDECREF(pyObject);
+		pyObject = value;
+	PyObjC_END_WITH_GIL
 }
 
 -(id)initWithCoder:(NSCoder*)coder

pyobjc-core/Modules/objc/OC_PythonSet.m

  */
 -(void)pyobjcSetValue:(NSObject*)other
 {
-	PyObject* v = PyObjC_IdToPython(other);
-	Py_XDECREF(value);
-	value = v;
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* v = PyObjC_IdToPython(other);
+		Py_XDECREF(value);
+		value = v;
+	PyObjC_END_WITH_GIL
 }
 
 - (id)initWithCoder:(NSCoder*)coder

pyobjc-core/Modules/objc/OC_PythonString.m

  */
 -(void)pyobjcSetValue:(NSObject*)other
 {
-	PyObject* v = PyObjC_IdToPython(other);
-	Py_XDECREF(value);
-	value = v;
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* v = PyObjC_IdToPython(other);
+		Py_XDECREF(value);
+		value = v;
+	PyObjC_END_WITH_GIL
 }
 
 - (id)initWithCoder:(NSCoder*)coder

pyobjc-core/Modules/objc/OC_PythonUnicode.m

  */
 -(void)pyobjcSetValue:(NSObject*)other
 {
-	PyObject* v = PyObjC_IdToPython(other);
-	Py_XDECREF(value);
-	value = v;
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* v = PyObjC_IdToPython(other);
+		Py_XDECREF(value);
+		value = v;
+	PyObjC_END_WITH_GIL
 }
 
 -(id)initWithCoder:(NSCoder*)coder

pyobjc-core/Modules/objc/formal-protocol.m

 	for (i = 0; i < len; i++) {
 		PyObject* sel = PySequence_Fast_GET_ITEM(selectors, i);
 		SEL theSel = PyObjCSelector_GetSelector(sel);
-		const char* theSignature = strdup(PyObjCSelector_Signature(sel));
+		const char* theSignature = PyObjCSelector_Signature(sel);
 		if (theSignature == NULL) {
 			goto error;
 		}
 			theSel, 
 			theSignature, 
 			(BOOL)PyObjCSelector_Required(sel), 
-			(BOOL)!PyObjCSelector_IsClassMethod(sel));
+			PyObjCSelector_IsClassMethod(sel)?NO:YES);
 	}
 
 	objc_registerProtocol(theProtocol);
 	}
 }
 
+static int
+append_method_list(PyObject* lst, Protocol* protocol, BOOL isRequired, BOOL isInstance)
+{
+	struct objc_method_description * methods;
+	unsigned int method_count, i;
+
+	methods = protocol_copyMethodDescriptionList(protocol, isRequired, isInstance, &method_count);
+	if (!methods) {
+		return 0;
+	}
+
+	for (i = 0; i < method_count; i++) {
+		char buf[512];
+		PyObjCRT_SimplifySignature(methods[i].types, buf, sizeof(buf));
+		PyObject* item = Py_BuildValue(
+#if PY_MAJOR_VERSION == 2
+			"{sssssO}",
+#else
+			"{sysysO}",
+#endif
+			"selector", sel_getName(methods[i].name),
+			"typestr",  buf,
+			"required", isRequired?Py_True:Py_False);
+		if (item == NULL) {
+			free(methods);
+			return -1;
+		}
+		if (PyList_Append(lst, item) < 0) {
+			Py_DECREF(item);
+			free(methods);
+			return -1;
+		}
+		Py_DECREF(item);
+	}
+
+	free(methods);
+	return 0;
+}
+
+
+static PyObject* 
+instanceMethods(PyObject* object)
+{
+	PyObjCFormalProtocol* self = (PyObjCFormalProtocol*)object;	
+	int r;
+
+	PyObject* result = PyList_New(0);
+	if (result == NULL) {
+		return NULL;
+	}
+
+	r = append_method_list(result, self->objc, YES, YES);
+	if (r == -1) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	r = append_method_list(result, self->objc, NO, YES);
+	if (r == -1) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	return result;
+
+}
+
+static PyObject* 
+classMethods(PyObject* object)
+{
+	PyObjCFormalProtocol* self = (PyObjCFormalProtocol*)object;	
+	int r;
+
+	PyObject* result = PyList_New(0);
+	if (result == NULL) {
+		return NULL;
+	}
+
+	r = append_method_list(result, self->objc, YES, NO);
+	if (r == -1) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	r = append_method_list(result, self->objc, NO, NO);
+	if (r == -1) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	return result;
+
+}
+
 static PyObject*
 descriptionForInstanceMethod_(PyObject* object, PyObject* sel)
 {
 
 	if (PyObjCSelector_Check(sel)) {
 		aSelector = PyObjCSelector_GetSelector(sel);
+#if PY_MAJOR_VERSION == 2
 	} else if (PyUnicode_Check(sel)) {
 		PyObject* bytes = PyUnicode_AsEncodedString(sel, NULL, NULL);
 		if (bytes == NULL) {
 		aSelector = sel_getUid(s);
 		Py_DECREF(bytes);
 
-#if PY_MAJOR_VERSION == 2
-	} else if (PyString_Check(sel)) {
-		char* s = PyString_AsString(sel);
+#endif
+	} else if (PyBytes_Check(sel)) {
+		char* s = PyBytes_AsString(sel);
 		if (*s == '\0') {
 			PyErr_SetString(PyExc_ValueError, 
 					"empty selector name");
 		}
 
 		aSelector = sel_getUid(s);
-#endif
 	} else {
 		PyErr_Format(PyExc_TypeError, "expecting a SEL, got instance of '%s'",
 				Py_TYPE(sel)->tp_name);
 		return Py_None;
 
 	} else {
-		return Py_BuildValue("(ss)",
-				sel_getName(descr.name),
-				descr.types);
+		char buf[512];
+		PyObjCRT_SimplifySignature(descr.types, buf, sizeof(buf));
+		return Py_BuildValue(
+#if PY_MAJOR_VERSION == 2
+			"(ss)",
+#else
+			"(yy)",
+#endif
+			sel_getName(descr.name),
+			buf);
 	}
 }
 
 
 	if (PyObjCSelector_Check(sel)) {
 		aSelector = PyObjCSelector_GetSelector(sel);
+#if PY_MAJOR_VERSION == 2
 	} else if (PyUnicode_Check(sel)) {
 		PyObject* bytes = PyUnicode_AsEncodedString(sel, NULL, NULL);
 		if (bytes == NULL) {
 		aSelector = sel_getUid(s);
 		Py_DECREF(bytes);
 
-#if PY_MAJOR_VERSION == 2
-	} else if (PyString_Check(sel)) {
-		char* s = PyString_AsString(sel);
+#endif
+	} else if (PyBytes_Check(sel)) {
+		char* s = PyBytes_AsString(sel);
 		if (*s == '\0') {
 			PyErr_SetString(PyExc_ValueError, 
 					"empty selector name");
 		}
 
 		aSelector = sel_getUid(s);
-#endif
 	} else {
 		PyErr_Format(PyExc_TypeError, "expecting a SEL, got instance of '%s'",
 				Py_TYPE(sel)->tp_name);
 		Py_INCREF(Py_None);
 		return Py_None;
 	} else {
-		return Py_BuildValue("(ss)",
+		char buf[256];
+		PyObjCRT_SimplifySignature(descr.types, buf, sizeof(buf));
+		return Py_BuildValue(
+#if PY_MAJOR_VERSION == 2
+			"(ss)",
+#else
+			"(yy)",
+#endif
 			sel_getName(descr.name),
-			descr.types);
+			buf);
 	}
 }
 
 		METH_O,
 		"Description for a class method in the protocol"
 	},
+	{
+		"instanceMethods",
+		(PyCFunction)instanceMethods,
+		METH_NOARGS,
+		"List of instance methods in this protocol"
+	},
+	{
+		"classMethods",
+		(PyCFunction)classMethods,
+		METH_NOARGS,
+		"List of class methods in this protocol"
+	},
 	{ 0, 0, 0, 0 }
 };
 

pyobjc-core/Modules/objc/objc-runtime-compat.h

 
 #endif
 
+/* 
+ * XXX: Override protocol_getMethodDescription. This is a crude hack that's added because
+ * protocol_getMethodDescription sometimes gives the wrong answer (test_protocols.py).
+ * I haven't found the root cause for this yet, it may or may not be a problem with PyObjC.
+ */
+extern struct objc_method_description PyObjC_protocol_getMethodDescription(Protocol *p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod);
+#define protocol_getMethodDescription PyObjC_protocol_getMethodDescription
+
+
 extern void PyObjC_SetupRuntimeCompat(void);
 
 #endif /* PyObjC_RUNTIME_COMPAT */

pyobjc-core/Modules/objc/objc-runtime-compat.m

 #endif
 #endif
 
+#undef protocol_getMethodDescription
+struct objc_method_description 
+PyObjC_protocol_getMethodDescription(Protocol *p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod)
+{
+	struct objc_method_description  result = protocol_getMethodDescription(p, aSel, isRequiredMethod, isInstanceMethod);
+	if (result.name != NULL) {
+		return result;
+	}
+
+	{
+		/* This code should not be necessary.... 
+		 * 
+		 * for some reason the protocols created by PyObjC don't always work, without this
+		 * function test_protocol.py sometimes (but not always!) fails.
+		 */
+
+		struct objc_method_description* methods;
+		unsigned int count, i;
+		methods = protocol_copyMethodDescriptionList(p, isRequiredMethod, isInstanceMethod, &count);
+		if (methods == NULL) {
+			return result;
+		}
+
+		for (i = 0; i < count; i++) {
+			if (sel_isEqual(methods[i].name, aSel)) {
+				result = methods[i];
+				free(methods);
+				return result;
+			}
+		}
+		free(methods);
+		return result;
+
+	}
+}
+
+
 
 void PyObjC_SetupRuntimeCompat(void)
 {

pyobjc-core/Modules/objc/test/instanceVariables.m

 
 -(void)dealloc
 {
-	Py_XDECREF(pyValue);
+	PyObjC_BEGIN_WITH_GIL
+		Py_XDECREF(pyValue);
+	PyObjC_END_WITH_GIL
 	[objValue release];
 	[nilValue release];
 	[super dealloc];

pyobjc-core/NEWS.txt

 Version 2.4  (or 3.0)
 ---------------------
 
+- Fix crash when unarchiving a Python object. 
+
 - Add missing calls to ``[super init]`` in the implementation of
   OC_PythonUnicode and OC_PythonString (the ObjC proxies for python's
   unicode and str types)

pyobjc-core/PyObjCTest/test3_protocol.py

                 ])
 
         def testMethodInfo(self):
+            self.assertEqual(MyProtocol3.instanceMethods(), [
+                {'typestr': b'I@:', 'required': True, 'selector': b'protoMethod'},
+                {'typestr': b'v@:ii', 'required': True, 'selector': b'anotherProto:with:'},
+            ])
+            self.assertEqual(MyProtocol3.classMethods(), [
+            ])
             self.assertEqual(
-                    MyProtocol3.descriptionForInstanceMethod_("protoMethod"),
-                        ("protoMethod", "I@:"))
+                    MyProtocol3.descriptionForInstanceMethod_(b"protoMethod"),
+                        (b"protoMethod", b"I@:"))
 
             self.assertEqual(
-                    MyProtocol3.descriptionForInstanceMethod_("nosuchmethod"),
+                    MyProtocol3.descriptionForInstanceMethod_(b"nosuchmethod"),
                         None)
 
+            self.assertEqual(MyClassProtocol3.classMethods(), [
+                {'required': True, 'selector': b'aClassOne:', 'typestr': b'@@:i'}
+            ])
+            self.assertEqual(MyProtocol3.classMethods(), [
+            ])
             self.assertEqual(
-                    MyClassProtocol3.descriptionForClassMethod_("aClassOne:"),
-                        ("aClassOne:", "@@:i"))
+                    MyClassProtocol3.descriptionForClassMethod_(b"aClassOne:"),
+                        (b"aClassOne:", b"@@:i"))
 
             self.assertEqual(
-                    MyClassProtocol3.descriptionForClassMethod_("nosuchmethod"),
+                    MyClassProtocol3.descriptionForClassMethod_(b"nosuchmethod"),
                         None)
 
 

pyobjc-core/PyObjCTest/test_protocol.py

     if OC_TestProtocol is not None:
 
         class TestFormalOCProtocols(TestCase):
+            def testMethodInfo(self):
+                actual = OC_TestProtocol.instanceMethods()
+                actual.sort(key=lambda item: item['selector'])
+                expected = [
+                    {'required': True, 'selector': b'method1', 'typestr': b'i@:'},
+                    {'required': True, 'selector': b'method2:', 'typestr': b'v@:i'}
+                ]
+                self.assertEqual(actual, expected)
+                self.assertEqual(OC_TestProtocol.classMethods(), [])
+
+                self.assertEqual(OC_TestProtocol.descriptionForInstanceMethod_(b"method1"), (b"method1", b"i@:"))
+                self.assertEqual(OC_TestProtocol.descriptionForInstanceMethod_(b"method2:"), (b"method2:", b"v@:i"))
             
             def testImplementFormalProtocol(self):
 
                 ])
 
         def testMethodInfo(self):
+            self.assertEqual(MyProtocol.instanceMethods(), [
+                {'typestr': b'I@:', 'required': True, 'selector': b'protoMethod'}, 
+                {'typestr': b'v@:ii', 'required': True, 'selector': b'anotherProto:with:'},
+            ])
+            self.assertEqual(MyProtocol.classMethods(), [
+            ])
             self.assertEqual(
-                    MyProtocol.descriptionForInstanceMethod_("protoMethod"),
+                    MyProtocol.descriptionForInstanceMethod_(b"protoMethod"),
                         ("protoMethod", "I@:"))
 
             self.assertEqual(
-                    MyProtocol.descriptionForInstanceMethod_("nosuchmethod"),
+                    MyProtocol.descriptionForInstanceMethod_(b"nosuchmethod"),
                         None)
 
+            self.assertEqual(MyClassProtocol.classMethods(), [
+                {'required': True, 'selector': 'aClassOne:', 'typestr': '@@:i'}
+            ])
+            self.assertEqual(MyProtocol.classMethods(), [
+            ])
             self.assertEqual(
-                    MyClassProtocol.descriptionForClassMethod_("aClassOne:"),
+                    MyClassProtocol.descriptionForClassMethod_(b"aClassOne:"),
                         ("aClassOne:", "@@:i"))
 
             self.assertEqual(
-                    MyClassProtocol.descriptionForClassMethod_("nosuchmethod"),
+                    MyClassProtocol.descriptionForClassMethod_(b"nosuchmethod"),
                         None)
 
 

pyobjc-framework-Cocoa/Lib/PyObjCTools/AppHelper.py

 
 __all__ = ( 'runEventLoop', 'runConsoleEventLoop', 'stopEventLoop', 'endSheetMethod', 'callAfter', 'callLater' )
 
-from AppKit import *
-from Foundation import *
+from AppKit import (NSApp, NSRunAlertPanel, NSApplicationMain,
+                    NSApplicationDidFinishLaunchingNotification)
+from Foundation import (NSObject, NSRunLoop, NSTimer, NSDefaultRunLoopMode,
+                        NSNotificationCenter, NSLog, NSAutoreleasePool)
+
 import os
 import sys
 import traceback

pyobjc-framework-Cocoa/Modules/_CoreFoundation.m

 		PyObjC_INITERROR();
 	}
 
+	/* Some C functions aren't available at runtime (e.g. when compiling on
+	 * OS X 10.5 but running on 10.4), so we use "#pragma weak" to weakly
+	 * link the functions, then we remove the corresponding Python wrappers
+	 * at runtime when we detect that the underlying C functions aren't
+	 * available.  It's a bit gross, but it's probably worse to try to
+	 * mimic Py_InitModule*, which is "a bit of a hack" according to its
+	 * source code.
+	 */
+	COREFOUNDATION_FILEDESCRIPTOR_AFTER_CREATE
+
 	if (PyObjC_ImportAPI(m) == -1) PyObjC_INITERROR();
 
 	PyObjC_INITDONE();

pyobjc-framework-Cocoa/Modules/_CoreFoundation_CFFileDescriptor.m

 #if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
 
+/* Needed when building against the OS X 10.5+ SDK but running on 10.4. */
+#pragma weak CFFileDescriptorCreate
+#pragma weak CFFileDescriptorGetContext
+
 static void* 
 mod_filedescr_retain(void* info) 
 {
 		METH_VARARGS,		\
 		NULL		\
 	},
+
+#define COREFOUNDATION_FILEDESCRIPTOR_AFTER_CREATE		\
+	if (&CFFileDescriptorCreate == NULL) {  /* weakly linked */		\
+		if (PyObject_DelAttrString(m, "CFFileDescriptorCreate") == -1) {		\
+			PyObjC_INITERROR();		\
+		}		\
+	}		\
+	if (&CFFileDescriptorGetContext == NULL) {  /* weakly linked */		\
+		if (PyObject_DelAttrString(m, "CFFileDescriptorGetContext") == -1) {		\
+			PyObjC_INITERROR();		\
+		}		\
+	}

pyobjc-framework-Quartz/PyObjCTest/test_cgremoteoperation.py

         v = CGAssociateMouseAndMouseCursorPosition(0)
         self.assertEqual(v, 0)
 
+        # For some reason there are 2 NSMachPort classes on OSX 10.8
+        classes = tuple([cls for cls in objc.getClassList() if cls.__name__ == 'NSMachPort'])
+
         v = CGWindowServerCFMachPort()
-        self.assertIsInstance(v, CFMachPortRef)
+        self.assertIsInstance(v, classes)
 
         self.assertTrue(CGSetLocalEventsFilterDuringSupressionState is CGSetLocalEventsFilterDuringSuppressionState)
 

pyobjc-framework-Social/PyObjCTest/test_slrequest.py

 from PyObjCTools.TestSupport import *
-import Social
+import sys
 
 SLRequestHandler = b'v@@@'
 
-class TestSLRequest (TestCase):
-    @min_os_level("10.8")
-    def testConstants(self):
-        self.assertEqual(Social.SLRequestMethodGET, 0)
-        self.assertEqual(Social.SLRequestMethodPOST, 1)
-        self.assertEqual(Social.SLRequestMethodDELETE, 2)
+if sys.maxsize > 2**32:
+    import Social
 
-    @min_os_level("10.8")
-    def testMethods(self):
-        self.assertArgIsBlock(Social.SLRequest.performRequestWithHandler_, 0, SLRequestHandler)
+    class TestSLRequest (TestCase):
+        @min_os_level("10.8")
+        def testConstants(self):
+            self.assertEqual(Social.SLRequestMethodGET, 0)
+            self.assertEqual(Social.SLRequestMethodPOST, 1)
+            self.assertEqual(Social.SLRequestMethodDELETE, 2)
+
+        @min_os_level("10.8")
+        def testMethods(self):
+            self.assertArgIsBlock(Social.SLRequest.performRequestWithHandler_, 0, SLRequestHandler)
 
 if __name__ == "__main__":
     main()

pyobjc-framework-Social/PyObjCTest/test_slservicetypes.py

 from PyObjCTools.TestSupport import *
-import Social
+import sys
 
-class TestSLTypes (TestCase):
-    @min_os_level("10.8")
-    def testConstants(self):
-        self.assertIsInstance(Social.SLServiceTypeTwitter, unicode)
-        self.assertIsInstance(Social.SLServiceTypeSinaWeibo, unicode)
+try:
+    unicode
+except NameError:
+    unicode = str
+
+
+if sys.maxsize >= 2**32:
+
+    import Social
+
+    class TestSLTypes (TestCase):
+        @min_os_level("10.8")
+        def testConstants(self):
+            self.assertIsInstance(Social.SLServiceTypeTwitter, unicode)
+            self.assertIsInstance(Social.SLServiceTypeSinaWeibo, unicode)
 
 if __name__ == "__main__":
     main()