Commits

Ronald Oussoren committed d1d9682

- Work better with type 'bool' (Objective-C)
- Other workaround for bug #77308
PyTuple_Type is not 'Ready' when entering init_objc, that's normal. It is
also not ready during calls to _convenience.py while __dict__ is set. That
is not normal and causes a crash. Calling PyType_Ready on the tuple type
makes sure the type is ready, which means we no longer get a crash.

  • Participants
  • Parent commits e6b8996

Comments (0)

Files changed (6)

File pyobjc/Lib/objc/_convenience.py

     Matching entries from both mappings are added to the 'type_dict'.
     """
     for k, sel in type_dict.items():
-        if k in ('__doc__', '__slots__', '__bases__', '__module__'):
-            # XXX: Without this test we get crashes on 'pydoc Foundation'.
-            # The crash happens in this function when testing
-            # type_dict['__slots__'] in the if-stmt below. That value
-            # ends up as a tuple with a corrupt type (__mro__ is NULL)
-            continue
-
         if not isinstance(sel, selector):
             continue
 

File pyobjc/Modules/objc/libffi_support.m

 	type->size = objc_sizeof_type(argtype);
 	type->alignment = objc_alignof_type(argtype);
 	type->type = FFI_TYPE_STRUCT;
-	type->elements = malloc((1+field_count) * sizeof(ffi_type));
+	type->elements = malloc((1+field_count) * sizeof(ffi_type*));
 	if (type->elements == NULL) {
 		free(type);
 		PyErr_NoMemory();
 		return &ffi_type_sint;
 	case _C_UCHR: case _C_USHT:
 		return &ffi_type_uint;
+#ifdef _C_BOOL
+	case _C_BOOL: return &ffi_type_sint;
+#endif	
 	default:
 		return signature_to_ffi_type(argtype);
 	}
 	case _C_CLASS: return &ffi_type_pointer;
 	case _C_SEL: return &ffi_type_pointer;
 	case _C_CHR: return &ffi_type_schar;
+#ifdef _C_BOOL
+	case _C_BOOL: return &ffi_type_schar;
+#endif	
 	case _C_UCHR: return &ffi_type_uchar;
 	case _C_SHT: return &ffi_type_sshort;
 	case _C_USHT: return &ffi_type_ushort;

File pyobjc/Modules/objc/module.m

 {
 	PyObject *m, *d;
 
-	//NSLog(@"initobjc");
+	/* HACK ALERT (Python 2.3)
+	 * If you do 'import objc' as the first thing in a fresh python
+	 * interpreter, PyTuple_Type.tp_mro happens to be NULL at this 
+	 * point. For some reason this messes up the bridge later on causing
+	 * 'pydoc Foundation' to crash. There seems to be a path were 
+	 * PyType_Ready isn't called when it should be. Specifically, we
+	 * end up with PyTuple_Type.tp_dict != NULL and 
+	 * PyTuple_Type.tp_mro == NULL in 
+	 * objc_util.m:ObjC_UpdateConvenienceMethods. It is unclear to me
+	 * what causes this.
+	 */
+	if (PyTuple_Type.tp_mro == NULL) {
+		if (PyType_Ready(&PyTuple_Type) < 0) {
+			return;
+		}
+	}
 
 	/* Allocate an auto-release pool for our own use, this avoids numerous
 	 * warnings during startup of a python script.
 	PyType_Ready(&PyObjCInstanceVariable_Type);
 	PyType_Ready(&PyObjCInformalProtocol_Type);
 	PyType_Ready(&PyObjCUnicode_Type);
+	PyType_Ready(&PyObjCInformalProtocol_Type);
 
 	m = Py_InitModule4("_objc", meta_methods, NULL,
 			NULL, PYTHON_API_VERSION);

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

 	Py_DECREF(real_bases); 
 	args = NULL;
 	real_bases = NULL;
-
 	
 	Py_DECREF(protocols);
 	protocols = NULL;

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

 	n = PyTuple_GET_SIZE(mro);
 	for (i = 0; i < n; i++) {
 		base = PyTuple_GET_ITEM(mro, i);
-		assert(PyType_Check(base));
 
 		if (PyClass_Check(base)) {
 			dict = ((PyClassObject*)base)->cl_dict;
 		} else {
+			assert(PyType_Check(base));
 			if (PyObjCClass_Check(base)) {
 				PyObjCClass_CheckMethodList(base, 0);
 			}

File pyobjc/Modules/objc/objc_util.m

 		if (	   strcmp(n, "__dict__") == 0 
 			|| strcmp(n, "__bases__") == 0
 			|| strcmp(n, "__slots__") == 0
+			|| strcmp(n, "__mro__") == 0
 		   ) {
 
 			Py_DECREF(k);