[PyObjC-svn] r2571 - in trunk/pyobjc/pyobjc-framework-Cocoa: . Doc Lib/CoreFoundation Modules PyObjCTest

[email protected] Fri, 13 Aug 2010 01:10:41 -0500
Newsgroups gmane.comp.python.pyobjc.cvs
Message-ID <[email protected]>
Author: ronaldoussoren
Date: Fri Aug 13 01:10:41 2010
New Revision: 2571

Log:
This fixes a number of small issues:

* The wrappers for the NSBitmapImagerep initializers were incomplete, now both methods
  that take bitmap plane arguments are implemented and work.

* Fix issue with cfmessage port wrappers

* Remove debug print statuements

All of this is tested on python 2.7 and will be backported to 2.3.1 once I've finished
testing.

With this patch all tests pass, although the cfrunloop and cfusernotification tests still
fail most of the time when running the entire suite. This is probably related to how I set up
the loop and clean up resources, the tests run fine when running those test modules seperately.


Modified:
   trunk/pyobjc/pyobjc-framework-Cocoa/Doc/api-notes-CoreFoundation.txt
   trunk/pyobjc/pyobjc-framework-Cocoa/Lib/CoreFoundation/PyObjC.bridgesupport
   trunk/pyobjc/pyobjc-framework-Cocoa/Modules/_AppKit_nsbitmap.m
   trunk/pyobjc/pyobjc-framework-Cocoa/Modules/_Foundation_data.m
   trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfmessageport.py
   trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfnumber.py
   trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfrunloop.py
   trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfsocket.py
   trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfstream.py
   trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfusernotification.py
   trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_nsbitmapimagerep.py
   trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_nsnull.py
   trunk/pyobjc/pyobjc-framework-Cocoa/setup.py

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/Doc/api-notes-CoreFoundation.txt
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/Doc/api-notes-CoreFoundation.txt	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/Doc/api-notes-CoreFoundation.txt	Fri Aug 13 01:10:41 2010
@@ -153,6 +153,11 @@
 * ``CFMessagePortSetDispatchQueue``: not supported yet because there
   are no wrappers for dispatch_queue_t yet.
 
+* ``CFMessagePortInvalidationCallback``: The second argument of the 
+  callback is an integer that should be ignored. The context value
+  can be retrieved using ``CFMessagePortGetContext`` (for local
+  ports, remote ports don't have a context).
+
 CFNumber
 --------
 

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/Lib/CoreFoundation/PyObjC.bridgesupport
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/Lib/CoreFoundation/PyObjC.bridgesupport	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/Lib/CoreFoundation/PyObjC.bridgesupport	Fri Aug 13 01:10:41 2010
@@ -2266,7 +2266,7 @@
   <function name='CFMessagePortGetInvalidationCallBack'>
     <retval function_pointer='true' type='^?' type64='^?'>
       <arg type='@' />
-      <arg type='@' />
+      <arg type='^v' />
     </retval>
     <arg type='^{__CFMessagePort=}' />
   </function>
@@ -2302,7 +2302,7 @@
     <arg type='^{__CFMessagePort=}' />
     <arg function_pointer='true' type='^?' type64='^?'>
       <arg type='@' />
-      <arg type='@' />
+      <arg type='^v' />
     </arg>
   </function>
   <function name='CFMessagePortSetName'>

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/Modules/_AppKit_nsbitmap.m
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/Modules/_AppKit_nsbitmap.m	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/Modules/_AppKit_nsbitmap.m	Fri Aug 13 01:10:41 2010
@@ -67,107 +67,183 @@
 	return result;
 }
 
-#if 0
 static PyObject*
-call_NSBitmapImageRep_initWithBitmapDataPlanes_bitmapFormat(
-		PyObject* method, PyObject* self, PyObject* arguments)
+call_NSBitmapImageRep_initWithBitmap(PyObject* method, 
+		PyObject* self, PyObject* arguments)
 {
-	PyObject* py_planes;
-	unsigned char** planes;
-	Py_ssize_t  nr_planes;
-	PyObject* py_width;
-	NSInteger width;
-	PyObject* py_height;
-	NSInteger height;
-	long	  bitsPerSample;
-	long	  samplesPerPixel;
-	PyObject* py_hasAlpha;
-	BOOL	  hasAlpha;
-	PyObject* py_isPlanar;
-	BOOL	  isPlanar;
-	PyObject* py_colorSpaceName;
-	NSString* colorSpaceName;
-	long	  bitmapFormat;
-	PyObject* py_bytesPerRow;
-	NSInteger bytesPerRow;
-	PyObject* py_bitsPerPixel;
-	NSInteger bitsPerPixel;
-
-	if (!PyArg_Parse(args, "OOOiiOOOiOO", 
-		&py_planes, &py_width, &py_height, &bitsPerSample,
-		&samplesPerPixel, &py_hasAlpha, &py_isPlanar,
-		&bitmapFormat, &py_bytesPerRow, &py_bitsPerPixel)) {
+	PyObject* result;
+	PyObject* maybeNone;
+	const void *dataPlanes[5];
+	int garbage;
+	int width, height;
+	int bps, spp;
+	BOOL hasAlpha, isPlanar;
+	char *colorSpaceName;
+	NSString *colorSpaceNameString;
+	int bpr, bpp, i;
+	NSBitmapImageRep *newImageRep;
+	struct objc_super super;
+	PyObject*  py_Planes[5];
+	Py_buffer  planeBuffers[5];
 
-		return NULL;
+	for (i = 0; i < 5; i++) {
+		py_Planes[i] = NULL;
+		planeBuffers[i].buf = NULL;
 	}
 
-	if (PyObjC_PythonToObjC(@encode(NSInteger), py_width, &width) == -1) {
-		return NULL;
-	}
-	if (PyObjC_PythonToObjC(@encode(NSInteger), py_height, &height) == -1) {
-		return NULL;
-	}
-	hasAlpha = PyObject_IsTrue(py_hasAlpha);
-	isPlanar = PyObject_IsTrue(py_isPlanar);
-	if (PyObjC_PythonToObjC(@encode(NSInteger), py_bytesPerRow, &bytesPerRow) == -1) {
-		return NULL;
-	}
-	if (PyObjC_PythonToObjC(@encode(NSInteger), py_bitsPerPixel, &bitsPerPixel) == -1) {
-		return NULL;
-	}
+	// check for five well defined read buffers in data planes argument
+	if (!PyArg_ParseTuple(arguments, "(OOOOO)iiiibbsii",
+		py_Planes + 0,
+		py_Planes + 1,
+		py_Planes + 2,
+		py_Planes + 3,
+		py_Planes + 4,
+		&width,
+		&height,
+		&bps,
+		&spp,
+		&hasAlpha,
+		&isPlanar,
+		&colorSpaceName,
+		&bpr,
+		&bpp)) {
 
-	if (py_planes == Py_None) {
-		planes = NULL;
-		nr_planes = -1;
-	} else {
-		PyObject* seq = PySequence_Fast(py_planes,
-				"Planes must be sequence");
-		if (seq == NULL) {
+		if ( !PyErr_ExceptionMatches(PyExc_TypeError) ) {
 			return NULL;
 		}
-		nr_planes = PySequence_Fast_GET_SIZE(seq);
 
-		planes = malloc(sizeof(unsigned char*) * nr_planes);
-		if (planes == NULL) {
-			PyErr_NoMemory();
-			Py_DECREF(seq);
-			return NULL;
+		PyErr_Clear();
+		bzero(dataPlanes, sizeof(dataPlanes));
+		bzero(py_Planes, sizeof(py_Planes));
+
+		if (!PyArg_ParseTuple(arguments, "Oiiiibbsii",
+				 &maybeNone,
+				 &width,
+				 &height,
+				 &bps,
+				 &spp,
+				 &hasAlpha,
+				 &isPlanar,
+				 &colorSpaceName,
+				 &bpr,
+				 &bpp)){
+
+			return NULL; //! any other situations that we need to parse specific args go here
+		} else {
+			// first arg must be none as nothing else makes sense
+			if (maybeNone != Py_None) {
+				PyErr_SetString(PyExc_TypeError, "First argument must be a 5 element Tuple or None.");
+				return NULL;
+			}
+		}
+	} else {
+		for (i = 0; i < 5; i++) {
+			if (py_Planes[i] == Py_None) {
+				dataPlanes[i] = NULL;
+			} else {
+				int r = PyObject_GetBuffer(py_Planes[i], planeBuffers + i,
+						PyBUF_SIMPLE);
+				if (r == 0) {
+					dataPlanes[i] = planeBuffers[i].buf;
+				} else {
+#if PY_MAJOR_VERSION == 2
+					/* Fall back to old-style buffers, not all python 2 types 
+					 * implement the newer APIs and that includes the stdlib.
+					 */
+					PyErr_Clear();
+					void * buf;
+					Py_ssize_t len;
+					int r = PyObject_AsReadBuffer(py_Planes[i], 
+						&buf, &len);
+					if (r == -1) {
+						goto error_cleanup;
+					}
+					dataPlanes[i] = buf;
+#else
+					goto error_cleanup;
+#endif
+				}
+			}
 		}
+	}
+
+	colorSpaceNameString = [NSString stringWithUTF8String: colorSpaceName];
+
+	PyObjC_DURING
+		PyObjC_InitSuper(&super,
+			PyObjCSelector_GetClass(method),
+			PyObjCObject_GetObject(self));
+    
+		newImageRep = ((id(*)(struct objc_super*, SEL, const void**, NSInteger, NSInteger, NSInteger, NSInteger, BOOL, BOOL, id, NSInteger, NSInteger))objc_msgSendSuper)(&super,
+				PyObjCSelector_GetSelector(method),
+				dataPlanes, width, height, bps, spp, 
+				hasAlpha, isPlanar, colorSpaceNameString, 
+				bpr, bpp);
 
-		Py_ssize_t i;
-		for (i = 0; i < nr_planes; i++) {
+	PyObjC_HANDLER
+		PyObjCErr_FromObjC(localException);
+		result = NULL;
+		newImageRep = nil;
+	PyObjC_ENDHANDLER
 
+	for (i = 0; i < 5; i++) {
+		if (py_Planes[i] != NULL && planeBuffers[i].buf != NULL) {
+			PyBuffer_Release(&planeBuffers[i]);
 		}
 	}
-}
-#endif
 
+	if (newImageRep == nil && PyErr_Occurred()) {
+		return NULL;
+	}
+
+	result = PyObjC_IdToPython(newImageRep);
+
+	return result;
+
+error_cleanup:
+	{
+		int j = i;
+		for (i = 0; i < j; i++) {
+			if (py_Planes[i] != NULL && planeBuffers[i].buf != NULL) {
+				PyBuffer_Release(&planeBuffers[i]);
+			}
+		}
+	}
+	return NULL;
+}
 
-/* XXX: Needs looking into, argument parsing seems awfully complex */
 static PyObject*
-call_NSBitmapImageRep_initWithBitmap(PyObject* method, 
+call_NSBitmapImageRep_initWithBitmapFormat(PyObject* method, 
 		PyObject* self, PyObject* arguments)
 {
 	PyObject* result;
 	PyObject* maybeNone;
-	unsigned char *dataPlanes[5];
+	const void *dataPlanes[5];
 	int garbage;
 	int width, height;
 	int bps, spp;
 	BOOL hasAlpha, isPlanar;
 	char *colorSpaceName;
 	NSString *colorSpaceNameString;
-	int bpr, bpp;
+	int bpr, bpp, i;
 	NSBitmapImageRep *newImageRep;
+	int format;
 	struct objc_super super;
+	PyObject*  py_Planes[5];
+	Py_buffer  planeBuffers[5];
+
+	for (i = 0; i < 5; i++) {
+		py_Planes[i] = NULL;
+		planeBuffers[i].buf = NULL;
+	}
 
 	// check for five well defined read buffers in data planes argument
-	if (!PyArg_ParseTuple(arguments, "("Py_ARG_BYTES"#"Py_ARG_BYTES"#"Py_ARG_BYTES"#"Py_ARG_BYTES"#"Py_ARG_BYTES"#)iiiibbsii",
-		&dataPlanes[0], &garbage,
-		&dataPlanes[1], &garbage,
-		&dataPlanes[2], &garbage,
-		&dataPlanes[3], &garbage,
-		&dataPlanes[4], &garbage,
+	if (!PyArg_ParseTuple(arguments, "(OOOOO)iiiibbsiii",
+		py_Planes + 0,
+		py_Planes + 1,
+		py_Planes + 2,
+		py_Planes + 3,
+		py_Planes + 4,
 		&width,
 		&height,
 		&bps,
@@ -175,6 +251,7 @@
 		&hasAlpha,
 		&isPlanar,
 		&colorSpaceName,
+		&format,
 		&bpr,
 		&bpp)) {
 
@@ -184,8 +261,9 @@
 
 		PyErr_Clear();
 		bzero(dataPlanes, sizeof(dataPlanes));
+		bzero(py_Planes, sizeof(py_Planes));
 
-		if (!PyArg_ParseTuple(arguments, "Oiiiibbsii",
+		if (!PyArg_ParseTuple(arguments, "Oiiiibbsiii",
 				 &maybeNone,
 				 &width,
 				 &height,
@@ -194,6 +272,7 @@
 				 &hasAlpha,
 				 &isPlanar,
 				 &colorSpaceName,
+				 &format,
 				 &bpr,
 				 &bpp)){
 
@@ -205,6 +284,35 @@
 				return NULL;
 			}
 		}
+	} else {
+		for (i = 0; i < 5; i++) {
+			if (py_Planes[i] == Py_None) {
+				dataPlanes[i] = NULL;
+			} else {
+				int r = PyObject_GetBuffer(py_Planes[i], planeBuffers + i,
+						PyBUF_SIMPLE);
+				if (r == 0) {
+					dataPlanes[i] = planeBuffers[i].buf;
+				} else {
+#if PY_MAJOR_VERSION == 2
+					/* Fall back to old-style buffers, not all python 2 types 
+					 * implement the newer APIs and that includes the stdlib.
+					 */
+					PyErr_Clear();
+					void * buf;
+					Py_ssize_t len;
+					int r = PyObject_AsReadBuffer(py_Planes[i], 
+						&buf, &len);
+					if (r == -1) {
+						goto error_cleanup;
+					}
+					dataPlanes[i] = buf;
+#else
+					goto error_cleanup;
+#endif
+				}
+			}
+		}
 	}
 
 	colorSpaceNameString = [NSString stringWithUTF8String: colorSpaceName];
@@ -214,11 +322,11 @@
 			PyObjCSelector_GetClass(method),
 			PyObjCObject_GetObject(self));
     
-		newImageRep = ((id(*)(struct objc_super*, SEL, unsigned char**, NSInteger, NSInteger, NSInteger, NSInteger, BOOL, BOOL, id, NSInteger, NSInteger))objc_msgSendSuper)(&super,
+		newImageRep = ((id(*)(struct objc_super*, SEL, const void**, NSInteger, NSInteger, NSInteger, NSInteger, BOOL, BOOL, id, NSBitmapFormat, NSInteger, NSInteger))objc_msgSendSuper)(&super,
 				PyObjCSelector_GetSelector(method),
 				dataPlanes, width, height, bps, spp, 
 				hasAlpha, isPlanar, colorSpaceNameString, 
-				bpr, bpp);
+				(NSBitmapFormat)format, bpr, bpp);
 
 	PyObjC_HANDLER
 		PyObjCErr_FromObjC(localException);
@@ -226,6 +334,12 @@
 		newImageRep = nil;
 	PyObjC_ENDHANDLER
 
+	for (i = 0; i < 5; i++) {
+		if (py_Planes[i] != NULL && planeBuffers[i].buf != NULL) {
+			PyBuffer_Release(&planeBuffers[i]);
+		}
+	}
+
 	if (newImageRep == nil && PyErr_Occurred()) {
 		return NULL;
 	}
@@ -233,6 +347,17 @@
 	result = PyObjC_IdToPython(newImageRep);
 
 	return result;
+
+error_cleanup:
+	{
+		int j = i;
+		for (i = 0; i < j; i++) {
+			if (py_Planes[i] != NULL && planeBuffers[i].buf != NULL) {
+				PyBuffer_Release(&planeBuffers[i]);
+			}
+		}
+	}
+	return NULL;
 }
 
 
@@ -282,7 +407,7 @@
 				PyObject* buffer = PyBuffer_FromReadWriteMemory(dataPlanes[i], bytesPerPlane);
 #else
 				Py_buffer info;
-				if (PyBuffer_FillInfo(&info, NULL, dataPlanes[i], bytesPerPlane, 1, PyBUF_FULL) < 0) {
+				if (PyBuffer_FillInfo(&info, NULL, dataPlanes[i], bytesPerPlane, 0, PyBUF_FULL) < 0) {
 					return NULL;
 				}
 				PyObject* buffer = PyMemoryView_FromBuffer(&info);
@@ -322,7 +447,7 @@
 			PyObjCSelector_GetClass(method),
 			PyObjCObject_GetObject(self));
     
-		bitmapData = (unsigned char *) objc_msgSendSuper(&super, 
+		bitmapData = (unsigned char *(*)(id, SEL)) objc_msgSendSuper(&super, 
 				PyObjCSelector_GetSelector(method));
 			
 		bytesPerPlane = [
@@ -340,13 +465,15 @@
 		return NULL;
 	}
 
-#if  PY_VERSION_HEX <= 0x02069900 
+#if  PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 6
 	result = PyBuffer_FromReadWriteMemory(bitmapData, bytesPerPlane);
 #else
+
 	/* A memory view requires that the backing store implements the buffer
 	 * interface, therefore create a mutable bytes object to do that for us.
 	 */
 	Py_buffer info;
+#if 0
 	NSMutableData* data = [[NSMutableData alloc] initWithBytesNoCopy:bitmapData length: bytesPerPlane freeWhenDone:NO];
 	PyObject* bytesBuf = PyObjC_ObjCToPython("@", &data);
 	[data release];
@@ -355,6 +482,8 @@
 	}
 
 	if (PyBuffer_FillInfo(&info, bytesBuf, bitmapData, bytesPerPlane, 0, PyBUF_FULL) < 0) {
+#endif
+	if (PyBuffer_FillInfo(&info, NULL, bitmapData, bytesPerPlane, 0, PyBUF_FULL) < 0) {
 		return NULL;
 	}
 	result = PyMemoryView_FromBuffer(&info);
@@ -395,6 +524,15 @@
 			PyObjCUnsupportedMethod_IMP) < 0) {
 
 		return -1;
+	}
+
+	if (PyObjC_RegisterMethodMapping(
+			class_NSBitmapImageRep,
+			@selector(initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:),
+			call_NSBitmapImageRep_initWithBitmapFormat,
+			PyObjCUnsupportedMethod_IMP) < 0) {
+
+		return -1;
 	}
 
 	if (PyObjC_RegisterMethodMapping(

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/Modules/_Foundation_data.m
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/Modules/_Foundation_data.m	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/Modules/_Foundation_data.m	Fri Aug 13 01:10:41 2010
@@ -33,13 +33,11 @@
 	result = PyBuffer_FromMemory((char*)bytes, bytes_len);
 #else
 	/* 2.7 or later: use a memory view */
-	printf("\n-data %p\n", bytes);
 	Py_buffer info;
 	if (PyBuffer_FillInfo(&info, self, (void*)bytes, bytes_len, 1, PyBUF_FULL_RO) < 0) {
 		return NULL;
 	}
 	result = PyMemoryView_FromBuffer(&info);
-	printf("-> %s\n", PyObject_REPR(result));
 #endif
 
 	return result;

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfmessageport.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfmessageport.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfmessageport.py	Fri Aug 13 01:10:41 2010
@@ -24,28 +24,29 @@
 
     def testTypeID(self):
         self.assertIsInstance(CFMessagePortGetTypeID(), (int, long))
+
     def testInteraction(self):
-        self.fail("research")
         class Context: pass
         context = Context()
 
         def callout(port, messageid, data, info):
             pass
-
         port, shouldFree = CFMessagePortCreateLocal(None, u"name", callout, context, None)
         self.assertIsInstance(port, CFMessagePortRef)
         self.assertIs(shouldFree is True or shouldFree, False)
         self.assertFalse(CFMessagePortIsRemote(port))
         ctx = CFMessagePortGetContext(port, None)
         self.assertIs(ctx, context)
-        port = CFMessagePortCreateRemote(None, u"name")
-        self.assertIsInstance(port, CFMessagePortRef)
+
+        port2 = CFMessagePortCreateRemote(None, u"name")
+        self.assertIsInstance(port2, CFMessagePortRef)
         self.assertResultIsBOOL(CFMessagePortIsRemote)
-        self.assertTrue(CFMessagePortIsRemote(port))
-        self.assertTrue(CFMessagePortGetName(port), u"name")
+        self.assertTrue(CFMessagePortIsRemote(port2))
+        self.assertTrue(CFMessagePortGetName(port2), u"name")
+
 
-        CFMessagePortSetName(port, "newname")
-        self.assertTrue(CFMessagePortGetName(port), u"newname")
+        CFMessagePortSetName(port2, "newname")
+        self.assertTrue(CFMessagePortGetName(port2), u"newname")
 
         cb = CFMessagePortGetInvalidationCallBack(port)
         self.assertIs(cb, None)

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfnumber.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfnumber.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfnumber.py	Fri Aug 13 01:10:41 2010
@@ -168,7 +168,10 @@
         self.assertEqual(v , kCFNumberDoubleType)
         v = CFNumberGetByteSize(44)
 
-        self.assertEqual(v , 8)
+        if sys.maxint >= 2**32:
+            self.assertEqual(v , 8)
+        else:
+            self.assertEqual(v , 4)
         v = CFNumberGetByteSize(44.0)
         self.assertEqual(v , 8)
         self.assertFalse(CFNumberIsFloatType(44))

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfrunloop.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfrunloop.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfrunloop.py	Fri Aug 13 01:10:41 2010
@@ -136,8 +136,9 @@
         self.assertIs(CFRunLoopContainsTimer(rl, timer, kCFRunLoopDefaultMode), False)
         CFRunLoopAddTimer(rl, timer, kCFRunLoopDefaultMode)
         self.assertIs(CFRunLoopContainsTimer(rl, timer, kCFRunLoopDefaultMode), True)
-        res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 2.0, True)
+        res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.3, True)
 
+        CFRunLoopTimerInvalidate(timer)
         CFRunLoopRemoveTimer(rl, timer, kCFRunLoopDefaultMode)
         self.assertIs(CFRunLoopContainsTimer(rl, timer, kCFRunLoopDefaultMode), False)
         self.assertFalse(len(state) < 3)

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfsocket.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfsocket.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfsocket.py	Fri Aug 13 01:10:41 2010
@@ -4,6 +4,15 @@
 import CoreFoundation
 import sys
 
+def onTheNetwork():
+    try:
+        socket.gethostbyname('www.apple.com')
+
+    except socket.gaierror:
+        return False
+
+    return True
+
 
 class TestSocket (TestCase):
     def testTypes(self):
@@ -53,6 +62,7 @@
         CFSocketSetDefaultNameRegistryPortNumber(p1)
 
 
+    @onlyIf(onTheNetwork(), "cannot test without internet connection")
     def testSocketFunctions(self):
         data = {}
         state = []
@@ -161,5 +171,6 @@
         self.assertNotHasAttr(CoreFoundation, 'CFSocketRegisterSocketSignature')
         self.assertNotHasAttr(CoreFoundation, 'CFSocketRegisterValue')
         self.assertNotHasAttr(CoreFoundation, 'CFSocketUnregister')
+
 if __name__ == "__main__":
     main()

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfstream.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfstream.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfstream.py	Fri Aug 13 01:10:41 2010
@@ -2,6 +2,8 @@
 from CoreFoundation import *
 import errno, time, os, socket, sys
 
+from test_cfsocket import onTheNetwork
+
 
 class TestStream (TestCase):
     def testTypes(self):
@@ -251,6 +253,7 @@
 
         del readStream, writeStream
 
+    @onlyIf(onTheNetwork)
     def testSockets(self):
         sd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
         sd.connect(('www.apple.com', 80))

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfusernotification.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfusernotification.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_cfusernotification.py	Fri Aug 13 01:10:41 2010
@@ -34,7 +34,8 @@
         CFRunLoopRunInMode(kCFRunLoopDefaultMode, 2.0, True)
 
         CFUserNotificationCancel(ref)
-        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, True)
+        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 5.0, True)
+        CFRunLoopRemoveSource(rl, rls, kCFRunLoopDefaultMode)
 
         self.assertEqual(len(values), 1)
         self.assertIs(values[0][0], ref)

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_nsbitmapimagerep.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_nsbitmapimagerep.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_nsbitmapimagerep.py	Fri Aug 13 01:10:41 2010
@@ -19,6 +19,29 @@
         i2 = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel_(None, width, height, 8, 3, NO, NO, NSDeviceRGBColorSpace, 0, 0)
         self.assert_(i2)
 
+    def testPixelFormat(self):
+        width = 16
+        height = 16
+
+        i1 = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_(None, width, height, 8, 3, NO, NO, NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat, 0, 0)
+        self.assertIsInstance(i1, NSBitmapImageRep)
+
+        singlePlane = objc.allocateBuffer(width*height*4)
+        for i in range(0, width*height):
+            si = i * 4
+            singlePlane[si] = 1
+            singlePlane[si+1] = 2
+            singlePlane[si+2] = 3
+            singlePlane[si+3] = 4
+        dataPlanes = (singlePlane, None, None, None, None)
+        # test non-planar, premade buffer
+        i2 = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_(dataPlanes, width, height, 8, 3, NO, NO, NSDeviceRGBColorSpace, NSAlphaFirstBitmapFormat, 0, 0)
+        self.assertIsInstance(i2, NSBitmapImageRep)
+
+        bitmapData = i2.bitmapData()
+
+        self.assertEqual(len(bitmapData), width * height * 4)
+
     def testImageData(self):
         width = 256
         height = 256
@@ -46,12 +69,11 @@
         self.assert_(i1)
 
         singlePlane = objc.allocateBuffer(width*height*3)
-        for i in range(0, 256*256):
+        for i in range(0, width*height):
             si = i * 3
             singlePlane[si] = rPlane[i]
             singlePlane[si+1] = gPlane[i]
             singlePlane[si+2] = bPlane[i]
-
         dataPlanes = (singlePlane, None, None, None, None)
         # test non-planar, premade buffer
         i2 = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel_(dataPlanes, width, height, 8, 3, NO, NO, NSDeviceRGBColorSpace, 0, 0)
@@ -81,13 +103,21 @@
         b[0:len(b)] = bPlane[0:len(bPlane)]
 
         bitmapData = i2.bitmapData()
+
         self.assertEqual(len(bitmapData), len(singlePlane))
-        self.assertEqual(bitmapData, singlePlane)
+        try:
+            memoryview
+        except NameError:
+            self.assertEqual(bitmapData, singlePlane)
+        else:
+            self.assertEquals(bitmapData.tobytes(),
+                singlePlane)
         
         a = array.array('L', [255]*4)
         self.assertArgIsOut(NSBitmapImageRep.getPixel_atX_y_, 0)
         d = i2.getPixel_atX_y_(a, 1, 1)
         self.assertIs(a, d)
+
 class TestBadCreation(TestCase):
 
     # Redirect stderr to /dev/null for the duration of this test, 
@@ -172,8 +202,6 @@
         self.assertArgIsOut(NSBitmapImageRep.getCompression_factor_, 0)
         self.assertArgIsOut(NSBitmapImageRep.getCompression_factor_, 1)
 
-        self.fail("- (id)initWithBitmapDataPlanes:(unsigned char **)planes pixelsWide:(NSInteger)width pixelsHigh:(NSInteger)height bitsPerSample:(NSInteger)bps samplesPerPixel:(NSInteger)spp hasAlpha:(BOOL)alpha isPlanar:(BOOL)isPlanar colorSpaceName:(NSString *)colorSpaceName  bitmapFormat:(NSBitmapFormat)bitmapFormat bytesPerRow:(NSInteger)rBytes bitsPerPixel:(NSInteger)pBits;")
-
 
 
 if __name__ == '__main__':

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_nsnull.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_nsnull.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/PyObjCTest/test_nsnull.py	Fri Aug 13 01:10:41 2010
@@ -4,7 +4,6 @@
 class TestNSNull (TestCase):
     def testBool(self):
         v = NSNull.null()
-        print bool(v)
         self.assert_(not v)
         self.assert_(v is not None)
 

Modified: trunk/pyobjc/pyobjc-framework-Cocoa/setup.py
==============================================================================
--- trunk/pyobjc/pyobjc-framework-Cocoa/setup.py	(original)
+++ trunk/pyobjc/pyobjc-framework-Cocoa/setup.py	Fri Aug 13 01:10:41 2010
@@ -6,6 +6,17 @@
 for information on how to use these frameworks and PyObjC's documentation
 for general tips and tricks regarding the translation between Python
 and (Objective-)C frameworks
+
+NEWS
+====
+
+2.4
+-----
+
+- Fix wrappers for a number of NSBitmap methods, those got broken while
+  introducing Python 3 support.
+
+- Add wrapper for [NSBitmapImageRep -initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:]
 '''
 from pyobjc_setup import setup, Extension
 import os

------------------------------------------------------------------------------
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev