Commits

Ronald Oussoren committed 9818806

The blocks runtime has an encoded signature for blocks, use that.

With a recent enough compiler (where 'recent enough' is still fairly
old) the compiler stores a type encoding for the block in the block
structure. I already had code to extract the signature from the block,
the signature is now actually used when there is no information about
the block result in the metadata system.

  • Participants
  • Parent commits 2c55d6e

Comments (0)

Files changed (3)

pyobjc-core/Modules/objc/libffi_support.m

 					return NULL;
 				}
 
-				if (methinfo->rettype.callable != NULL) {
-					if (PyObjCObject_IsBlock(objc_result) && PyObjCObject_GetBlock(objc_result) == NULL) {
+				if (PyObjCObject_IsBlock(objc_result) && PyObjCObject_GetBlock(objc_result) == NULL) {
+					/* Result is an (Objective-)C block for which we don't have a Python signature
+					 *
+					 * 1) Try to extract from the metadata system
+					 * 2) Try to extract from the ObjC runtime
+					 *
+					 * Both systems may not have the required information.
+					 */
+
+					if (methinfo->rettype.callable != NULL) {
 						PyObjCObject_SET_BLOCK(objc_result, methinfo->rettype.callable);
 						Py_INCREF(methinfo->rettype.callable);
+					} else {
+						char* signature = PyObjCBlock_GetSignature(objc_result);
+						if (signature != NULL) {
+							PyObject* sig = PyObjCMethodSignature_WithMetaData(signature, NULL, YES);
+							if (sig == NULL) {
+								Py_DECREF(objc_result);
+								return NULL;
+							}
+							PyObjCObject_SET_BLOCK(objc_result, sig);
+							sig = NULL;
+						}
 					}
 				}
-
 			} else {
 
 				objc_result = pythonify_c_return_value (tp, pRetval);

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

 
 	if (PyObjCObject_IsBlock(obj)) {
 		PyObjCMethodSignature* v = PyObjCObject_GetBlock(obj);
+		PyObjCObject_SET_BLOCK(obj, NULL);	
 		Py_XDECREF(v);
-		PyObjCObject_SET_BLOCK(obj, NULL);	
 	}
 			
 

pyobjc-core/NEWS.txt

 
 - Improved documentation
 
+- For Objective-C blocks: try to extract the block signature from the (Objective-)C runtime
+  when there is no metadata for the block. The block signature is available only when the
+  code that creates the block is compiled using a recent enough compiler (although "recent
+  enough" is fairly old by now)
 
 Version 2.4.1
 -------------