Commits

Ronald Oussoren  committed 39f1475

- Fix typo in AppKit.__init__
- NSSelectorFromString, NSStringFromSelector, NSStringFromClass:
these are automaticly wrapped, don't bother with pure python version
(silences warning of epydoc, and saves us a discussion on the merits of
that warning)
- Fix typo in objc.__init__
- Workaround for crash in 'pydoc Foundation' (in objc._convenience). This
isn't a real bugfix, but I can't find the actual bug at the moment.
- Don't add posed-as classes to the module dict in objc.loadBundle
- Found 'B' in a signature string on Panther, skip this character when
splitting signatures. Real fix will follow when I know what this does.
- When researching this issue I found that the GNU runtime defines
_C_ATOM, handle this in objc_support.m. It also doesn't define _C_LNGLNG
but has _C_LNG_LNG. (And no, I'm not working on a GNUstep port)
- call [obj retain] before converting the object to a CFType in
toll-free-bridging.m. Not doing this causes a hard crash, needs further
investigation.
- Make sure Scripts/runalltests reports tests that fail due to a signal,
even if this happens after the final message by unittest.main.

  • Participants
  • Parent commits c37841a

Comments (0)

Files changed (12)

File pyobjc/Doc/TODO

 * Use libffi to do away with class-builder.m:find_real_superclass. And check
   if we can use libffi to simplify code.
 
+* See XXX in Lib/objc/_convenience.py. That code masks a real, but elusive,
+  bug.
+
 
 Support for GNUstep
 ...................

File pyobjc/Lib/AppKit/__init__.py

 # Load the Cocoa bundle, and gather all classes defined there
 _objc.loadBundle("AppKit", globals(), bundle_path="/System/Library/Frameworks/AppKit.framework")
 _objc.recyleAutoreleasePool()
-del Foundation
 
 
 # Define usefull utility methods here
 
 # The used to be defined here as pure python functions, these aliasses
 # are left here for backward compatibility.
-NSMakePoint = Foundaiton.NSMakePoint
+NSMakePoint = Foundation.NSMakePoint
 NSMakeSize = Foundation.NSMakeSize
 NSMakeRect = Foundation.NSMakeRect
 
+del Foundation
+
 import protocols  # no need to export these, just register with PyObjC
 
 #

File pyobjc/Lib/Foundation/__init__.py

 
 NSBundle = _objc.lookUpClass('NSBundle')
 
-# We use strings to represent selectors, therefore 
-# NSSelectorFromString and NSStringFromSelector are no-ops (for now)
-
-def NSSelectorFromString(aSelectorName):
-    if not isinstance(aSelectorName, str):
-        raise TypeError, "aSelector must be string"
-
-    return aSelectorName
-
-NSStringFromSelector = NSSelectorFromString
-
-def NSStringFromClass(aClass):
-    return aClass.__name__
-
 _objc.loadBundle("Foundation", globals(), bundle_path="/System/Library/Frameworks/Foundation.framework")
 
 import os

File pyobjc/Lib/objc/__init__.py

     warings.warn(
         "Use recycleAutoreleasePool instead of recycle_autorelease_pool",
         DeprecationWarning)
-    recycleAutoreleasePool()
+    recyleAutoreleasePool()
+
+###
+# This can be usefull to hunt down memory problems in the testsuite.
+#import atexit
+#atexit.register(recyleAutoreleasePool)

File pyobjc/Lib/objc/_convenience.py

 
     Matching entries from both mappings are added to the 'type_dict'.
     """
-    for sel in type_dict.values():
+    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
 
-        
         if sel.selector.startswith('init') and not sel.isClassMethod:
             # Instance methods that start with 'init*' are constructors. These
             # return 'self'. If they don't they reallocated the previous 

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

                 if not isinstance(sel, objc.selector): continue
 
                 elems = objc.splitSignature(sel.signature)
+            
 
     def testSimple(self):
         self.assertEquals(objc.splitSignature("@:@"), ('@',':','@'))

File pyobjc/Modules/objc/module.m

 			if (r == -1) {
 				PyErr_Clear();
 			} else if (c == 0) {
-				if (PyDict_SetItemString(module_globals, 
+				if (((PyTypeObject*)item)->tp_name[0] == '%') {
+					/* skip, posed-as type */
+				} else if (PyDict_SetItemString(module_globals, 
 						((PyTypeObject*)item)->tp_name, item) == -1) {
 					Py_DECREF(module_key);
 					Py_DECREF(class_list);
 			return NULL;
 		}
 
-		if (PyDict_SetItemString(module_globals, 
+		if (((PyTypeObject*)item)->tp_name[0] == '%') {
+			/* skip, posed-as type */
+		} else if (PyDict_SetItemString(module_globals, 
 				((PyTypeObject*)item)->tp_name, item) == -1) {
 			Py_DECREF(module_key);
 			Py_DECREF(class_list);

File pyobjc/Modules/objc/objc_support.h

 #define nil NULL
 #endif
 
-#ifndef _C_LNGLNG
-#define _C_LNGLNG 'q'
+#ifndef _C_LNG_LNG
+#define _C_LNG_LNG 'q'
 #endif
 
-#ifndef _C_ULNGLNG
-#define _C_ULNGLNG 'Q'
+#ifndef _C_ULNG_LNG
+#define _C_ULNG_LNG 'Q'
 #endif
 
+/* What we call _C_LNGLNG is actually _C_LNG_LNG in the GNU runtime */
+#define _C_LNGLNG _C_LNG_LNG
+#define _C_ULNGLNG _C_ULNG_LNG
+
 extern Ivar_t class_getInstanceVariable(Class aClass, const char *name);
 extern Ivar_t object_getInstanceVariable(id obj, const char *name, void **out);
 extern struct objc_method_list *class_nextMethodList(Class aClass, void **ptr);

File pyobjc/Modules/objc/objc_support.m

 	type = PyObjCRT_SkipTypeQualifiers (type);
 
 	switch (*type) {
+	case 'B':	
+		/* This turned up on Panther, without documentation */
+		NSLog(@"Parsing typespec containing unsupported code 'B'");
+		type++;
+		break;
+
 	/* The following are one character type codes */
 	case _C_UNDEF:
 	case _C_ID:
 	case _C_CHR:
 	case _C_UCHR:
 	case _C_CHARPTR:
+#ifdef _C_ATOM
+	case _C_ATOM:
+#endif
 	case _C_SHT:
 	case _C_USHT:
 	case _C_INT:
 	case _C_FLT:   return __alignof__ (float);
 	case _C_DBL:   return __alignof__ (double);
 	case _C_CHARPTR: return __alignof__ (char *);
+#ifdef _C_ATOM
+	case _C_ATOM: return __alignof__ (char *);
+#endif
 	case _C_PTR:   return __alignof__ (void *);
 	case _C_LNGLNG: return __alignof__(long long);
 	case _C_ULNGLNG: return __alignof__(unsigned long long);
 
 	case _C_PTR:
 	case _C_CHARPTR:
+#ifdef _C_ATOM
+	case _C_ATOM
+#endif
 		return sizeof(char*);
       
 	case _C_ARY_B:
 			(long)(*(unsigned char*)datum));
 		break;
 
-	case _C_CHARPTR:
+	case _C_CHARPTR: 
+#ifdef _C_ATOM
+	case _C_ATOM:
+#endif
 	{
 		char *cp = *(char **) datum;
 
 	type = PyObjCRT_SkipTypeQualifiers (type);
   
 	switch (*type) {
+#ifdef _C_ATOM
+	case _C_ATOM:
+#endif
 	case _C_CHARPTR:
 		if (!PyString_Check (argument) && argument != Py_None) {
 			ObjCErr_Set(PyExc_ValueError,

File pyobjc/Modules/objc/objc_util.m

 	PyObject* dict;
 	PyObject* keys;
 	int       i, len;
+
+	if (!PyObjCClass_Check(cls)) {
+		PyErr_SetString(PyExc_TypeError, "not a class");
+		return -1;
+	}
 	
 
 	if (ObjC_class_extender == NULL || cls == NULL) return 0;
 		return -1;
 	}
 	Py_DECREF(res);
-
 	keys = PyDict_Keys(dict);
 	if (keys == NULL) {
 		Py_DECREF(args);
 			continue;
 		}
 		if (	   strcmp(n, "__dict__") == 0 
-			|| strcmp(n, "__bases__") == 0) {
+			|| strcmp(n, "__bases__") == 0
+			|| strcmp(n, "__slots__") == 0
+		   ) {
 
 			Py_DECREF(k);
 			continue;

File pyobjc/Modules/objc/toll-free-bridging.m

 
 PyObject* PyObjC_IDToCFType(id argument)
 {
-
+	[argument retain];
 	if ([argument isKindOfClass:[NSMutableString class]]) {
 		return CFMutableStringRefObj_New((CFMutableStringRef)argument);
 	}

File pyobjc/Scripts/runalltests

                 ln = ''
                 for ln in fd.xreadlines():
                     sys.stdout.write(ln)
+
+                xit = fd.close()
                 if ln.startswith('OK'):
-                    tests[path] = ln.strip()
-                    test_sum['OK'] += 1
+                    if xit is not None:
+                        tests[path] = 'Exit with %s: %s'%(xit, ln.strip())
+                        test_sum['CRASH'] += 1
+                    else:
+                        tests[path] = ln.strip()
+                        test_sum['OK'] += 1
 
                 elif ln.startswith('FAIL'):
                     tests[path] = ln.strip()