Commits

Ronald Oussoren committed 7070bfb

- Fix some loose ends from migration of Modules/Cocoa (how's that for
team work? ;-) ;-) )
- Add specific conversion for PyBool_Type (if that is present). Not sure if
that is the right thing to do.
- Fix for NSLocalizedString + regression test
- Add pickling to Doc/TODO

  • Participants
  • Parent commits 68f2339
  • Branches pyobjc-ancient

Comments (0)

Files changed (15)

 is generated.
 
 NOTE: At least one person has problems compiling Modules/objc on 10.1.
+
+Pickle support
+..............
+
+Objective-C objects don't support pickling. They do pickle without errors using
+protocol version 2 (Python >= 2.3a2), but that doesn't include the state of
+the Objective-C object only that of the proxy.
+
+NSCoder support
+...............
+
+It might be usefull to add default implementations of ``encodeWithCoder:`` and
+``initWithCoder:`` methods to Python subclasses of Objective-C classes that 
+implement these.

Examples/CurrencyConverter/CurrencyConverter.py

 from Foundation import NSObject
 after('import Foundation')
 from AppKit import NSApplicationMain, NibClassBuilder
+from AppKit import NSRunAlertPanel
 after('import AppKit')
 from objc import *
 after('import objc')
         self.totalField.setFloatValue_(total)
         self.rateField.selectText_(self)
 
+        x = NSRunAlertPanel("Calculation Result", 
+            "The result is %s"%(total), "OK", None, None)
+        print x
+
 after('class ConverterController')
 
 sys.exit(NSApplicationMain(sys.argv))

Lib/Foundation/test/test_nslocalizedstring.py

+# Place holder for real tests.
+import unittest
+import objc
+
+from Foundation import NSLocalizedString
+
+class TestNSLocalizedString(unittest.TestCase):
+    def testBasic(self):
+        # This is mostly a regression tests, the function used to crash on 
+        # this...
+
+        s = NSLocalizedString("hello world", "")
+        objc.recycle_autorelease_pool()
+        self.assertEquals (s, "hello world")
+        self.assertEquals (s.pyobjc_NSString().description(), "hello world")
+
+        
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestNSLocalizedString))
+    return suite
+
+if __name__ == '__main__':
+    unittest.main( )
+

Modules/AddressBook/_AddressBook.m

 #include "pyobjc-api.h"
 #include "objc_support.h"
 #include "OC_PythonObject.h"
-#include "const-table.h"
+#include "wrapper-const-table.h"
 
 static PyMethodDef addressbook_methods[] = {
 	{ 0, 0, 0, 0 }

Modules/AppKit/_AppKit.m

 #include "pyobjc-api.h"
 #include "objc_support.h"
 #include "OC_PythonObject.h"
-#include "const-table.h"
+#include "wrapper-const-table.h"
 #ifndef GNU_RUNTIME
 #include <objc/objc-runtime.h>
 #endif
   return Py_None; 
 }
 
+static PyObject*
+objc_NSGetWindowServerMemory(PyObject* self, PyObject* args, PyObject* kwds)
+{
+static char* keywords[] = { "context", "windowDumpStream", NULL };
+	int context;
+	int virtualMemory = 0;
+	int doDumpStream;
+	int res;
+	int windowBackingMemory = 0;
+	NSString* windowDumpStream = NULL;
+	PyObject* result;
+	PyObject* v;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii:NSGetWindowServerMemory", keywords, &context, &doDumpStream)) {
+		return NULL;
+	}
+
+	NS_DURING
+		if (doDumpStream) {
+			res = NSGetWindowServerMemory(
+				context, &virtualMemory, &windowBackingMemory,
+				&windowDumpStream);
+		} else {
+			res = NSGetWindowServerMemory(
+				context, &virtualMemory, &windowBackingMemory,
+				NULL);
+		}
+	NS_HANDLER
+		ObjCErr_FromObjC(localException);
+	NS_ENDHANDLER
+
+	if (PyErr_Occurred()) {
+		return NULL;
+	}
+
+	result = PyTuple_New(4);
+	if (result == NULL) return NULL;
+
+	v = PyInt_FromLong(res);
+	if (v == NULL) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	PyTuple_SET_ITEM(result, 0, v);
+
+	v = PyInt_FromLong(virtualMemory);
+	if (v == NULL) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	PyTuple_SET_ITEM(result, 1, v);
+
+	v = PyInt_FromLong(windowBackingMemory);
+	if (v == NULL) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	PyTuple_SET_ITEM(result, 2, v);
+
+	v = ObjC_IdToPython(windowDumpStream);
+	if (v == NULL) {
+		Py_DECREF(result);
+		return NULL;
+	}
+
+	PyTuple_SET_ITEM(result, 3, v);
+
+	return result;
+}
+
+	
+
+
 #ifdef GNUSTEP
 #include "_App_Functions.GNUstep.inc"
 
 		METH_VARARGS,
 		NULL
 	},
+	{
+		"NSGetWindowServerMemory",
+		(PyCFunction)objc_NSGetWindowServerMemory,
+		METH_VARARGS,
+		NULL
+	},
 
 	METHOD_TABLE_ENTRIES
 

Modules/Foundation/_Foundation.m

 #import <Foundation/NSDebug.h>
 #include "pyobjc-api.h"
 #include "objc_support.h"
-#include "const-table.h"
+#include "wrapper-const-table.h"
 
 /** Functions */
 
 	oc_result = NSLocalizedString(oc_key, oc_comment);
 
 	result = ObjC_IdToPython(oc_result);
-	[oc_result release];
 	return result;
 }
 
 
 	oc_result = NSLocalizedStringFromTable(oc_key, oc_tableName, oc_comment);
 	result = ObjC_IdToPython(oc_result);
-	[oc_result release];
 	return result;
 }
 
 			oc_key, oc_tableName, oc_bundle, oc_comment);
 
 	result = ObjC_IdToPython(oc_result);
-	[oc_result release];
 	return result;
 }
 

Modules/InterfaceBuilder/_InterfaceBuilder.m

 #include "pyobjc-api.h"
 #include "objc_support.h"
 #include "OC_PythonObject.h"
-#include "const-table.h"
+#include "wrapper-const-table.h"
 
 static PyMethodDef ib_methods[] = {
 	{ 0, 0, 0, 0 }

Modules/PreferencePanes/_PreferencePanes.m

 #include "pyobjc-api.h"
 #include "objc_support.h"
 #include "OC_PythonObject.h"
-#include "const-table.h"
+#include "wrapper-const-table.h"
 
 static PyMethodDef prefpanes_methods[] = {
 	{ 0, 0, 0, 0 }

Modules/objc/objc_support.m

 
 @end /* PyObjCSupport */
 
+#if 1
+
+/*
+ * Automaticly mapping from NSNumber to python numbers doesn't work when
+ * you want to add the result of NSNumber.numberWithBool_ to a property list.
+ */
+
 @interface NSNumber (PyObjCSupport)
 -(PyObject*)__pyobjc_PythonObject__;
 @end /* NSNumber (PyObjCSupport) */
 
 @end /* NSNumber (PyObjCSupport) */
 
+#endif
+
 @interface NSString (PyObjCSupport)
 -(PyObject*)__pyobjc_PythonObject__;
 @end /* NSString (PyObjCSupport) */
 					"to encode unicode string to UTF8");
 				return -1;
 			}
+
+#ifdef PyObjC_HAVE_PYTHON_BOOL
+		} else if (PyBool_Check(argument)) {
+			*(id *) datum = [NSNumber 
+				numberWithBool:PyInt_AS_LONG (argument)];
+#endif			
 		} else if (PyInt_Check (argument)) {
 			*(id *) datum = [NSNumber 
 				numberWithLong:PyInt_AS_LONG (argument)];

Modules/objc/pyobjc-api.h

  * - This interface is in development, the the API will probably change in
  *   incompatible ways.
  *
- * $Id: pyobjc-api.h,v 1.7 2003/02/23 08:58:43 ronaldoussoren Exp $
+ * $Id: pyobjc-api.h,v 1.8 2003/02/26 14:26:36 ronaldoussoren Exp $
  */
 
 #include <Python.h>
 #if PY_VERSION_HEX < 0x0203000A /* Python < 2.3.0a */
 
 /* PyBool_Type was introduced in Python 2.3 */
+
+#define PyObjC_HAVE_PYTHON_BOOL
 #define PyBool_Check(_x_) (0)
 #define PyBool_FromLong(_x_) PyInt_FromLong(_x_)
 

Modules/objc/pyobjc.h

 /* PyBool_Type was introduced in Python 2.3 */
 #define PyBool_Check(_x_) (0)
 #define PyBool_FromLong(_x_) PyInt_FromLong(_x_)
+#define PyObjC_HAVE_PYTHON_BOOL
 
 #endif /* Python < 2.3.0a */
 

Modules/objc/wrapper-const-table.h

+/*
+ *  This file contains type and function definitions that are helpfull for
+ *  adding constants to the python module
+ *
+ *  NOTE: The functions are defined as 'static inline' to avoid compiler 
+ *  warnings.
+ *  NOTE2: The functions are not in a seperate file because I am lazy and
+ *  to make using this file easier
+ *  NOTE3: This file is used by the files generated by the scripts in
+ *         ~/Scripts/CodeGenerators.
+ *
+ */
+struct inttable {
+	char* 	name;
+	int	value;
+};
+
+struct stringtable {
+	char*	  name;
+	NSString* const* value;
+};
+
+#define xSTR(x) #x
+#define STR(x) xSTR(x)
+
+#define CONST_ENTRY(var) { STR(var), var }
+#define STR_ENTRY(var) { STR(var), &var }
+#define STR_VAR(var) if (add_string(d, STR(var), var) < 0) return
+#define INT_VAR(var) if (add_int(d, STR(var), var) < 0) return
+
+static inline int add_double(PyObject*d, char* name, double value)
+{
+	int res;
+	PyObject* v;
+
+	v = PyFloat_FromDouble(value);
+	if (v == NULL) return -1;
+
+	res = PyDict_SetItemString(d, name, v);
+	if (res < 0) return -1;
+	return 0;
+}
+
+static inline int add_float(PyObject*d, char* name, float value)
+{
+	int res;
+	PyObject* v;
+
+	v = PyFloat_FromDouble(value);
+	if (v == NULL) return -1;
+
+	res = PyDict_SetItemString(d, name, v);
+	if (res < 0) return -1;
+	return 0;
+}
+
+static inline int add_unsigned(PyObject*d, char* name, unsigned value)
+{
+	int res;
+	PyObject* v;
+
+	v = PyInt_FromLong(value);
+	if (v == NULL) return -1;
+
+	res = PyDict_SetItemString(d, name, v);
+	if (res < 0) return -1;
+	return 0;
+}
+
+static inline int add_BOOL(PyObject*d, char* name, BOOL value)
+{
+	int res;
+	PyObject* v;
+
+	v = PyBool_FromLong(value);
+	if (v == NULL) return -1;
+
+	res = PyDict_SetItemString(d, name, v);
+	if (res < 0) return -1;
+	return 0;
+}
+
+static inline int add_int(PyObject*d, char* name, int value)
+{
+	int res;
+	PyObject* v;
+
+	v = PyInt_FromLong(value);
+	if (v == NULL) return -1;
+
+	res = PyDict_SetItemString(d, name, v);
+	if (res < 0) return -1;
+	return 0;
+}
+
+static inline int register_ints(PyObject* d, struct inttable* table)
+{
+	while (table->name != NULL) {
+		if (add_int(d, table->name, table->value) < 0) return -1;	
+		table++;
+	}
+	return 0;
+}
+
+static inline int add_string(PyObject* d, char* name, NSString* value)
+{
+	int res;
+	PyObject* v;
+
+	v = ObjC_ObjCToPython("@", &value);
+	if (v == NULL) return -1;
+
+	res = PyDict_SetItemString(d, name, v);
+	if (res < 0) return -1;
+	return 0;
+}
+
+static inline int register_strings(PyObject* d, struct stringtable* table)
+{
+	while (table->name != NULL) {
+		add_string(d, table->name, *table->value);
+		table++;
+	}
+	return 0;
+}
+

Scripts/CodeGenerators/cocoa_generator.py

 # This script is based on some (not to clever) regular expressions, and seems
 # to work pretty well with the current version of the Cocoa headers.
 #
-# We recognize:
-# - enum definitions
-# - NSString constants (as 'extern NSString*' variables)
+# NOTES:
+# - This script is probably MacOSX specific.
 #
-# TODO:
-# - Generate stubs for function wrappers (but: will most likely need manual
-#   work to get the actual function wrappers)
 import enum_generator
 import strconst_generator
 import var_generator
 import func_collector
 import func_builder
 import os
+import sys
+
+if not os.path.isdir('Modules'):
+    print "Run me from the root of the PyObjC source tree"
+    sys.exit(1)
 
 FRAMEWORKS="/System/Library/Frameworks"
 FOUNDATION=os.path.join(FRAMEWORKS, "Foundation.framework")
 PREFPANES_HDRS=os.path.join(PREFPANES, 'Headers')
 IB_HDRS=os.path.join(IB, 'Headers')
 
-enum_generator.generate(FOUNDATION_HDRS, '_Fnd_Enum.inc')
-enum_generator.generate(APPKIT_HDRS, '_App_Enum.inc')
-enum_generator.generate(ADDRESSBOOK_HDRS, '_Addr_Enum.inc')
-enum_generator.generate(PREFPANES_HDRS, '_PrefPanes_Enum.inc')
-enum_generator.generate(IB_HDRS, '_InterfaceBuilder_Enum.inc')
+enum_generator.generate(FOUNDATION_HDRS, 'Modules/Foundation/_Fnd_Enum.inc')
+enum_generator.generate(APPKIT_HDRS, 'Modules/AppKit/_App_Enum.inc')
+enum_generator.generate(ADDRESSBOOK_HDRS, 'Modules/AddressBook/_Addr_Enum.inc')
+enum_generator.generate(PREFPANES_HDRS, 'Modules/PreferencePanes/_PrefPanes_Enum.inc')
+enum_generator.generate(IB_HDRS, 'Modules/InterfaceBuilder/_InterfaceBuilder_Enum.inc')
 
-strconst_generator.generate(FOUNDATION_HDRS, '_Fnd_Str.inc')
-strconst_generator.generate(APPKIT_HDRS, '_App_Str.inc')
-strconst_generator.generate(ADDRESSBOOK_HDRS, '_Addr_Str.inc')
-strconst_generator.generate(PREFPANES_HDRS, '_PrefPanes_Str.inc')
-strconst_generator.generate(IB_HDRS, '_InterfaceBuilder_Str.inc')
+strconst_generator.generate(FOUNDATION_HDRS, 'Modules/Foundation/_Fnd_Str.inc')
+strconst_generator.generate(APPKIT_HDRS, 'Modules/AppKit/_App_Str.inc')
+strconst_generator.generate(ADDRESSBOOK_HDRS, 'Modules/AddressBook/_Addr_Str.inc')
+strconst_generator.generate(PREFPANES_HDRS, 'Modules/PreferencePanes/_PrefPanes_Str.inc')
+strconst_generator.generate(IB_HDRS, 'Modules/InterfaceBuilder/_InterfaceBuilder_Str.inc')
 
 FOUNDATION_PREFIX="FOUNDATION_EXPORT"
 FOUNDATION_IGNORE_LIST=(
         "NSHangOnMallocError",
 )
 
-var_generator.generate(FOUNDATION_HDRS, '_Fnd_Var.inc', FOUNDATION_PREFIX, FOUNDATION_IGNORE_LIST)
+var_generator.generate(FOUNDATION_HDRS, 'Modules/Foundation/_Fnd_Var.inc', FOUNDATION_PREFIX, FOUNDATION_IGNORE_LIST)
 
 APPKIT_PREFIX="APPKIT_EXTERN"
 APPKIT_IGNORE_LIST=(
 	# NSApp is a 'real' variable, will probably add get/set functions
 	'NSApp')
 
-var_generator.generate(APPKIT_HDRS, '_App_Var.inc', APPKIT_PREFIX, APPKIT_IGNORE_LIST)
+var_generator.generate(APPKIT_HDRS, 'Modules/AppKit/_App_Var.inc', APPKIT_PREFIX, APPKIT_IGNORE_LIST)
 
 FOUNDATION_IGNORE_LIST=(
 	# Private functions in NSException.h 
         'NSCountWindowsForContext(',
         'NSAvailableWindowDepths(',
         'NSRectFillList(',
+        'NSGetWindowServerMemory(',
 )
-func_collector.generate(FOUNDATION_HDRS, 'Foundation.prototypes', 
+func_collector.generate(FOUNDATION_HDRS, 'Modules/Foundation/Foundation.prototypes', 
 	FOUNDATION_PREFIX, FOUNDATION_IGNORE_LIST)
-func_collector.generate(APPKIT_HDRS, 'AppKit.prototypes', 
+func_collector.generate(APPKIT_HDRS, 'Modules/AppKit/AppKit.prototypes', 
 	APPKIT_PREFIX, APPKIT_IGNORE_LIST)
 
 # Add easy to handle types in Foundation:
 func_builder.FUNC_MAP['NSBeginInformationalAlertSheet'] = BeginSheetMapper
 func_builder.FUNC_MAP['NSBeginCriticalAlertSheet'] = BeginSheetMapper
 
-fd = file('_Fnd_Functions.inc', 'w')
+fd = file('Modules/Foundation/_Fnd_Functions.inc', 'w')
 structs = ['NSPoint', 'NSSize', 'NSRect', 'NSRange']
 for s in structs:
 	func_builder.SIMPLE_TYPES[s] = (
 '''%{'type': s })
 
 
-func_builder.process_list(fd , file('Foundation.prototypes'))
+func_builder.process_list(fd , file('Modules/Foundation/Foundation.prototypes'))
 fd = None
 for s in structs:
 	del func_builder.SIMPLE_TYPES[s]
 
-fd = file('_App_Functions.inc', 'w')
+fd = file('Modules/AppKit/_App_Functions.inc', 'w')
 structs = ['NSAffineTransformStruct', 'NSRect', 'NSPoint']
 for s in structs:
 	func_builder.SIMPLE_TYPES[s] = (
 ])
 
 
-func_builder.process_list(fd, file('AppKit.prototypes'))
+func_builder.process_list(fd, file('Modules/AppKit/AppKit.prototypes'))
 for s in structs:
 	del func_builder.SIMPLE_TYPES[s]

Scripts/clean-install

 import sys
 import os
 
-#os.environ['MACOSX_DEPLOYMENT_TARGET'] = '1'
+os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.2'
 
 site=None
 for e in sys.path:
         "-DMACOSX",
         "-no-cpp-precomp",
         "-Wno-long-double",
-        "-O0", "-g",
+        "-g",
+        #"-O0", "-g",
         ]
 
     OBJC_LDFLAGS=[