Commits

Bob Ippolito  committed c4f7409

bridge number types coming in with PyObjC_NSNumberWrapper
set by _pythonify
(one test failure with plists)

  • Participants
  • Parent commits aeaac56
  • Branches pyobjc-ancient

Comments (0)

Files changed (8)

File Lib/objc/__init__.py

 from _category import *
 from _bridges import *
 from _compat import *
+from _pythonify import *
 
 ###
 # This can be usefull to hunt down memory problems in the testsuite.

File Lib/objc/_bridges.py

     if not getStrBridgeEnabled():
         warnings.warn("use unicode(str, encoding) for NSString", PyObjCStrBridgeWarning, stacklevel=2)
     return unicode(s)
+BRIDGED_TYPES.append((str, str_to_unicode))
 
-BRIDGED_TYPES.append((str, str_to_unicode))
+# XXX - these could let us remove code from OC_PythonObject
+#NSNumber = lookUpClass('NSNumber')
+#BRIDGED_TYPES.extend([
+#    (bool, NSNumber.numberWithBool_),
+#    (int, NSNumber.numberWithInt_),
+#    (float, NSNumber.numberWithDouble_),
+#    (long, NSNumber.numberWithLongLong_),
+#])
 
 try:
     from array import array

File Lib/objc/_convenience.py

             v = v.unsignedlongValue()
 
         elif tp == 'q':
-            v = v.longlongValue()
+            v = v.longLongValue()
 
         elif tp == 'Q':
             v = v.unsignedLonglongValue()

File Lib/objc/_pythonify.py

+import _objc
+
+__all__ = []
+
+class OC_PythonFloat(float):
+    def __new__(cls, obj, value):
+        self = float.__new__(cls, value)
+        self.__pyobjc_object__ = obj
+        return self
+
+    def getattr(self, attr):
+        return getattr(self.__pyobjc_object__, attr)
+
+class OC_PythonLong(long):
+    def __new__(cls, obj, value):
+        self = long.__new__(cls, value)
+        self.__pyobjc_object__ = obj
+        return self
+
+    def getattr(self, attr):
+        return getattr(self.__pyobjc_object__, attr)
+
+class OC_PythonInt(int):
+    def __new__(cls, obj, value):
+        self = int.__new__(cls, value)
+        self.__pyobjc_object__ = obj
+        return self
+
+    def getattr(self, attr):
+        return getattr(self.__pyobjc_object__, attr)
+
+NSNumber = _objc.lookUpClass('NSNumber')
+NSDecimalNumber = _objc.lookUpClass('NSDecimalNumber')
+def numberWrapper(obj):
+    if isinstance(obj, NSDecimalNumber) or not hasattr(obj, 'objCType'):
+        return obj
+    tp = obj.objCType()
+    if tp in 'qQLfd':
+        if tp == 'q':
+            return OC_PythonLong(obj, obj.longLongValue())
+        elif tp in 'QL':
+            return OC_PythonLong(obj, obj.unsignedLongLongValue())
+        else:
+            return OC_PythonFloat(obj, obj.doubleValue())
+    else:
+        return OC_PythonInt(obj, obj.longValue())
+
+_objc.setNSNumberWrapper(numberWrapper)

File Modules/objc/OC_PythonObject.m

 		r = 0;
 #endif /* MACOSX */
 	} else {
+		PyObject *anObject = PyObject_GetAttrString(argument, "__pyobjc_object__");
+		if (anObject && anObject != argument) {
+			return [self wrapPyObject:anObject toId:datum];
+		}
+		PyErr_Clear();
 		NS_DURING
 			rval = [OC_PythonObject 
 				newWithCoercedObject:argument];

File Modules/objc/module.m

 
 int PyObjC_VerboseLevel = 0;
 PyObject* PyObjCClass_DefaultModule = NULL;
+PyObject* PyObjC_NSNumberWrapper = NULL;
 int PyObjC_StrBridgeEnabled = 1;
 
 static NSAutoreleasePool* global_release_pool = nil;
 	return Py_None;
 }
 
+PyDoc_STRVAR(setNSNumberWrapper_doc,
+	"setNSNumberWrapper(wrapper) -> None\n"
+	"\n"
+	"Set the NSNumber wrapper function to the new value."
+);
+static PyObject* 
+setNSNumberWrapper(PyObject* self __attribute__((__unused__)), PyObject* args, PyObject* kwds)
+{
+static 	char* keywords[] = { "wrapper", NULL };
+	PyObject* o;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:setNSNumberWrapper",
+			keywords, &o)) {
+		return NULL;
+	}
+
+	Py_XDECREF(PyObjC_NSNumberWrapper);
+	Py_INCREF(o);
+	PyObjC_NSNumberWrapper = o;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(getNSNumberWrapper_doc,
+	"getNSNumberWrapper() -> wrapper\n"
+	"\n"
+	"Return the verbosity value."
+);
+static PyObject* 
+getNSNumberWrapper(PyObject* self __attribute__((__unused__)), PyObject* args, PyObject* kwds)
+{
+static 	char* keywords[] = { NULL };
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, ":getNSNumberWrapper",
+			keywords)) {
+		return NULL;
+	}
+
+	if (PyObjC_NSNumberWrapper == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	Py_INCREF(PyObjC_NSNumberWrapper);
+	return PyObjC_NSNumberWrapper;
+}
+
+
 PyDoc_STRVAR(setVerbose_doc,
 	"setVerbose(bool) -> None\n"
 	"\n"
 	{ "setClassExtender", (PyCFunction)set_class_extender, METH_VARARGS|METH_KEYWORDS, set_class_extender_doc  },
 	{ "setSignatureForSelector", (PyCFunction)set_signature_for_selector, METH_VARARGS|METH_KEYWORDS, set_signature_for_selector_doc },
 	{ "recycleAutoreleasePool", (PyCFunction)recycle_autorelease_pool, METH_VARARGS|METH_KEYWORDS, recycle_autorelease_pool_doc },
+	{ "setNSNumberWrapper", (PyCFunction)setNSNumberWrapper, METH_VARARGS|METH_KEYWORDS, setNSNumberWrapper_doc },
+	{ "getNSNumberWrapper", (PyCFunction)getNSNumberWrapper, METH_VARARGS|METH_KEYWORDS, getNSNumberWrapper_doc },
 	{ "setVerbose", (PyCFunction)setVerbose, METH_VARARGS|METH_KEYWORDS, setVerbose_doc },
 	{ "getVerbose", (PyCFunction)getVerbose, METH_VARARGS|METH_KEYWORDS, getVerbose_doc },
 	{ "repythonify", (PyCFunction)repythonify, METH_VARARGS|METH_KEYWORDS, repythonify_doc },

File Modules/objc/objc_support.m

 
 @end /* NSString (PyObjCSupport) */
 
+@interface NSNumber (PyObjCSupport)
+-(PyObject*)__pyobjc_PythonObject__;
+@end /* NSNumber (PyObjCSupport) */
+
+@implementation NSNumber (PyObjCSupport)
+
+-(PyObject*)__pyobjc_PythonObject__
+{
+	PyObject *rval = [super __pyobjc_PythonObject__];
+	if (PyObjC_NSNumberWrapper && rval) {
+		PyObject *val = rval;
+		rval = PyObject_CallFunctionObjArgs(PyObjC_NSNumberWrapper, val, NULL);
+		Py_DECREF(val);
+	}
+	return rval;
+}
+
 
 #ifndef MAX
 static inline int

File Modules/objc/pyobjc.h

 
 extern int PyObjC_VerboseLevel;
 extern int PyObjC_StrBridgeEnabled;
+extern PyObject *PyObjC_NSNumberWrapper;
 
 
 int PyObjCAPI_Register(PyObject* module);