[PyObjC-svn] r2481 - in trunk/pyobjc/pyobjc-core: . Modules/objc Modules/objc/test PyObjCTest

[email protected] Sun, 16 May 2010 16:19:14 -0500
Newsgroups gmane.comp.python.pyobjc.cvs
Message-ID <[email protected]>
Author: ronaldoussoren
Date: Sun May 16 16:19:13 2010
New Revision: 2481

Log:
* Add test for the -action issue from the mailinglist
* Add first stab add avoiding to avoid replacing  
  the signature from the runtime by one that is
  incompatible. This doesn't work properly yet and
  is therefore disabled for now.
* Various tweaks to enable building with python 2.7
  again.



Added:
   trunk/pyobjc/pyobjc-core/PyObjCTest/test_metadata_inheritance.py   (contents, props changed)
Modified:
   trunk/pyobjc/pyobjc-core/Modules/objc/block_support.m
   trunk/pyobjc/pyobjc-core/Modules/objc/libffi_support.m
   trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.m
   trunk/pyobjc/pyobjc-core/Modules/objc/module.m
   trunk/pyobjc/pyobjc-core/Modules/objc/objc_support.h
   trunk/pyobjc/pyobjc-core/Modules/objc/objc_support.m
   trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc-api.h
   trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc-compat.h
   trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc.h
   trunk/pyobjc/pyobjc-core/Modules/objc/selector.m
   trunk/pyobjc/pyobjc-core/Modules/objc/super-call.m
   trunk/pyobjc/pyobjc-core/Modules/objc/test/metadatafunction.m
   trunk/pyobjc/pyobjc-core/PyObjCTest/test_opaque.py
   trunk/pyobjc/pyobjc-core/setup.py

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/block_support.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/block_support.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/block_support.m	Sun May 16 16:19:13 2010
@@ -297,7 +297,7 @@
 	return NULL;
 }
 
-#if PY_MAJOR_VERSION == 2
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
 static void PyObjCBlock_CleanupCapsule(void* ptr)
 {
 	PyObjCFFI_FreeBlockFunction(ptr);

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/libffi_support.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/libffi_support.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/libffi_support.m	Sun May 16 16:19:13 2010
@@ -155,8 +155,7 @@
 static ffi_type* signature_to_ffi_type(const char* argtype);
 
 #if PY_MAJOR_VERSION == 2
-static void cleanup_ffitype_capsule(void* ptr, void* context __attribute__((__unused__)))
-
+static void cleanup_ffitype_capsule(void* ptr)
 {
 	free_type(ptr);
 }
@@ -2269,7 +2268,7 @@
 }
 
 
-#if PY_MAJOR_VERSION == 2
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
 static void imp_capsule_cleanup(void* ptr, void* context __attribute__((__unused__)))
 {
 	PyObjCFFI_FreeIMP(ptr);

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.m	Sun May 16 16:19:13 2010
@@ -508,6 +508,14 @@
 		}
 
 		char* type = PyBytes_AsString(bytes);
+
+		if (!PyObjC_signatures_compatible(descr->type, type)) {
+			/* The new signature is not compatible enough, ignore the 
+			 * override.
+			 */
+			type = descr->type;
+		}
+
 		char* tp = PyMem_Malloc(strlen(type)+2);
 		if (tp == NULL) {
 			Py_XDECREF(bytes);

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/module.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/module.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/module.m	Sun May 16 16:19:13 2010
@@ -1367,7 +1367,7 @@
   "Returns a closure object that can be used to call the function from\n"
   "C. This object has no useable interface from Python.\n"
  );
-#if PY_MAJOR_VERSION == 2
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
 static void _callback_cleanup(void* closure)
 {
 	PyObjCFFI_FreeIMP((IMP)closure);

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/objc_support.h
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/objc_support.h	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/objc_support.h	Sun May 16 16:19:13 2010
@@ -22,6 +22,13 @@
 #ifndef _objc_support_H
 #define _objc_support_H
 
+extern BOOL PyObjC_signatures_compatible(const char* type1, const char* type2);
+/* Returns True iff two typestrings are compatible:
+ * - elements have same size
+ * - 'id' is compatible with 'void*' and not with other types
+ * - 'float'/'double' are not compatible with integer types.
+ */
+
 /*#F Takes a C value pointed by @var{datum} with its type encoded in
   @var{type}, that should be coming from an ObjC @encode directive,
   and returns an equivalent Python object where C structures and

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/objc_support.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/objc_support.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/objc_support.m	Sun May 16 16:19:13 2010
@@ -871,6 +871,10 @@
 	{
 		Py_ssize_t max_size = 0;
 		type++;
+		/* Skip name part: */
+		while (*type != _C_UNION_E && *type++ != '='); 
+
+		/* Calculate size: */
 		while (*type != _C_UNION_E) {
 			itemSize = PyObjCRT_SizeOfType (type);
 			if (itemSize == -1) return -1;
@@ -2808,3 +2812,70 @@
 	}
 	Py_DECREF(proxy);
 }
+
+BOOL _PyObjC_signatures_compatible(const char* type1, const char* type2)
+{
+	return YES;
+	/* Ignore type modifiers */
+	type1 = PyObjCRT_SkipTypeQualifiers(type1);
+	type2 = PyObjCRT_SkipTypeQualifiers(type2);
+
+	if (PyObjCRT_SizeOfType(type1) != PyObjCRT_SizeOfType(type2)) {
+		return NO;
+	}
+	switch (*type1) {
+	case _C_FLT: case _C_DBL: 
+		switch (*type2) {
+		case _C_FLT: case _C_DBL: 
+			return YES;
+	 	default:     
+			return NO;
+		}
+
+	case _C_ID:
+		if (*type2 == _C_ID) {
+			return YES;
+		}
+		if (type2[0] == _C_PTR && type2[1] == _C_VOID) {
+			return YES;
+		}
+		return NO;
+
+	case _C_CHARPTR:
+		if (*type2 == _C_CHARPTR) {
+			return YES;
+		} else if (*type2 == _C_PTR) {
+			return PyObjC_signatures_compatible("c", type2+1);
+		} else {
+			return NO;
+		}
+	
+	case _C_PTR:
+		if (type2[1] == _C_VOID && type2[0] == _C_ID) {
+			return YES;
+		}
+		if (*type2 == _C_CHARPTR) {
+			return PyObjC_signatures_compatible(type1+1, "c");
+		}
+		if (*type2 != _C_PTR) {
+			return NO;
+		}
+		return PyObjC_signatures_compatible(type1+1, type2+1);
+	
+	default:
+		switch (*type2) {
+		case _C_ID: case _C_PTR: return NO;
+		case _C_FLT: case _C_DBL: return NO;
+		default: return YES;
+		}
+	}
+}
+BOOL PyObjC_signatures_compatible(const char* type1, const char* type2)
+{
+	BOOL r =  _PyObjC_signatures_compatible(type1, type2);
+
+	if (!r) {
+		NSLog(@"Compatible: '%s' '%s' -> %d", type1, type2, r);
+	}
+	return r;
+}

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc-api.h
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc-api.h	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc-api.h	Sun May 16 16:19:13 2010
@@ -412,7 +412,7 @@
 static inline PyObject*
 PyObjC_CreateInlineTab(PyObjC_function_map* map)
 {
-#if PY_MAJOR_VERSION == 2
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
 	return PyCObject_FromVoidPtr(map, NULL);
 #else
 	return PyCapsule_New(map, "objc.__inline__", NULL);
@@ -450,7 +450,7 @@
 			"No C_API in objc module");
 		return -1;
 	}
-#if PY_MAJOR_VERSION == 2
+#if PY_MAJOR_VERSION == 2 && PY_VERSION_MAJOR < 7
 	PyObjC_API = PyCObject_AsVoidPtr(api_obj);
 #else
 	PyObjC_API = PyCapsule_GetPointer(api_obj, "objc." PYOBJC_API_NAME);

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc-compat.h
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc-compat.h	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc-compat.h	Sun May 16 16:19:13 2010
@@ -135,14 +135,18 @@
 #define Py_TYPE(ob)             (((PyObject*)(ob))->ob_type)
 #define Py_SIZE(ob)             (((PyVarObject*)(ob))->ob_size)
 
+
 /* Source-level backward compatibility: use PyCapsule API in sources, fall back to
  * PyCObject when needed.
  */
+#if PY_MINOR_VERSION < 7
 #define PyCapsule_New(pointer, name, destructor) PyCObject_FromVoidPtr(pointer, destructor)
 #define PyCapsule_GetPointer(object, name) PyCObject_AsVoidPtr(object)
 #define PyCapsule_CheckExact(object)	PyCObject_Check(object)
 #endif
 
+#endif
+
 #if PY_MAJOR_VERSION == 2
 
 #define PyErr_Format PyObjCErr_Format

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc.h
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc.h	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/pyobjc.h	Sun May 16 16:19:13 2010
@@ -167,14 +167,15 @@
     do { \
 	PyErr_Format(PyObjCExc_InternalError, \
 	  "PyObjC: internal error in %s at %s:%d: %s", \
-	   __FUNCTION__, __FILE__, __LINE__, msg) \
+	   __FUNCTION__, __FILE__, __LINE__, msg); \
 	   _PyObjC_InternalError_Bailout(); \
     } while (0)
 
 #define PyObjC_Assert(expr, retval) \
+	do { \
 	if (!(expr)) { PyObjCErr_InternalErrorMesg(\
-			"assertion failed: " #expr); return (retval); }
-
+			"assertion failed: " #expr); return (retval); } \
+	} while (0)
 #else
 
 #define PyObjCErr_InternalError()	((void)0)

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/selector.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/selector.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/selector.m	Sun May 16 16:19:13 2010
@@ -2057,7 +2057,7 @@
 		 * the user may have specified a more exact
 		 * signature!
 		 */
-		char* typestr = NULL;
+		const char* typestr = NULL;
 
 		if (super_sel == NULL) {
 			/* FIXME: This isn't optimal when hiding methods with non-standard types */

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/super-call.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/super-call.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/super-call.m	Sun May 16 16:19:13 2010
@@ -46,7 +46,7 @@
 	return 0;
 }
 
-#if PY_MAJOR_VERSION == 2
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
 
 static void memblock_capsule_cleanup(void* ptr, void* closure __attribute__((__unused__)))
 {

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/test/metadatafunction.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/test/metadatafunction.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/test/metadatafunction.m	Sun May 16 16:19:13 2010
@@ -502,10 +502,10 @@
 		INITERROR();
 	}
 	
-#if PY_VERSION_HEX >= 0x03000000
-	v = PyCapsule_New(gFunctionMap, "objc.__functionlist__", NULL);
-#else
+#if PY_VERSION_MAJOR == 2 && PY_VERSION_MINOR < 7
 	v = PyCObject_FromVoidPtr(gFunctionMap, NULL);
+#else
+	v = PyCapsule_New(gFunctionMap, "objc.__functionlist__", NULL);
 #endif
 	if (v == NULL) {
 		INITERROR();

Modified: trunk/pyobjc/pyobjc-core/PyObjCTest/test_opaque.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/PyObjCTest/test_opaque.py	(original)
+++ trunk/pyobjc/pyobjc-core/PyObjCTest/test_opaque.py	Sun May 16 16:19:13 2010
@@ -60,7 +60,7 @@
 
         # There is no exposed type object that for PyCObject, test the
         # type name instead
-        if sys.version_info[0] == 2:
+        if sys.version_info[0] == 2 and sys.version_info[1] < 7:
             self.assertEquals( type(f.__cobject__()).__name__, 'PyCObject' )
         else:
             self.assertEquals( type(f.__cobject__()).__name__, 'PyCapsule' )

Modified: trunk/pyobjc/pyobjc-core/setup.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/setup.py	(original)
+++ trunk/pyobjc/pyobjc-core/setup.py	Sun May 16 16:19:13 2010
@@ -257,52 +257,28 @@
     "-DPyObjC_BUILD_RELEASE=%02d%02d"%(tuple(map(int, platform.mac_ver()[0].split('.')[:2]))),
     "-no-cpp-precomp",
     "-DMACOSX",
-    #"-Wno-long-double",
-    #"-Wselector",
-    #"-Wstrict-overflow",
     "-g",
-    #"-fobjc-gc",
     "-fexceptions",
 
-    ## Arghh, a stupid compiler flag can cause problems. Don't 
-    ## enable -O0 if you value your sanity. With -O0 PyObjC will crash
-    ## on i386 systems when a method returns a struct that isn't returned
-    ## in registers. 
-    #"-O0",
-    "-O1",
-    #"-O2",
-    #"-O3",
-    #'-arch', 'x86_64', '-arch', 'ppc64',
 
     # Loads of warning flags
     "-Wall", "-Wstrict-prototypes", "-Wmissing-prototypes",
-    "-Wformat=2", "-W", "-Wshadow",
+    "-Wformat=2", "-W", 
+    #"-Wshadow", # disabled due to warnings from Python headers
     "-Wpointer-arith", #"-Wwrite-strings",
     "-Wmissing-declarations",
     "-Wnested-externs",
     "-Wno-long-long",
-    #"-Wfloat-equal",
-
-    # These two are fairly useless:
-    #"-Wunreachable-code",
-    #"-pedantic",
 
     "-Wno-import",
-    #"-Werror",
-
-    # use the same optimization as Python, probably -O3,
-    # but can be overrided by one of the following:
-
-    # no optimization, for debugging
-    #"-O0",
-
-    # g4 optimized
-    #"-fast", "-fPIC", "-mcpu=7450",
-
-    # g5 optimized
-    #"-fast", "-fPIC",
     ])
 
+## Arghh, a stupid compiler flag can cause problems. Don't 
+## enable -O0 if you value your sanity. With -O0 PyObjC will crash
+## on i386 systems when a method returns a struct that isn't returned
+## in registers. 
+if '-O0' in get_config_var('CFLAGS'):
+    CFLAGS.append('-O1')
 
 OBJC_LDFLAGS = frameworks('CoreFoundation', 'Foundation', 'Carbon')
 

------------------------------------------------------------------------------