Author: ronaldoussoren
Date: Thu May 1 04:13:02 2008
New Revision: 1997
Log:
* Finish OC_PythonNumber (but: still no unittests for this)
* Add some documentation to _pycoder
Modified:
trunk/pyobjc/pyobjc-core/Lib/objc/_pycoder.py
trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonNumber.m
Modified: trunk/pyobjc/pyobjc-core/Lib/objc/_pycoder.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/Lib/objc/_pycoder.py (original)
+++ trunk/pyobjc/pyobjc-core/Lib/objc/_pycoder.py Thu May 1 04:13:02 2008
@@ -4,8 +4,11 @@
NOTE: this only works with a keyed archiver, not with a plain archiver. It
should be easy enough to change this later on if needed.
-FIXME: encoding for lists and tuples is far from optimal
-FIXME: need versioning
+A minor problem with NSCoding support is that NSCoding restores
+graphs recusively while Pickle does so depth-first (more of less).
+This can cause problems when the object state contains the
+object itself, which is why we need a 'setValue' callback for the
+load_* functions below.
"""
import objc
from types import *
@@ -283,6 +286,10 @@
cls.__name__, str(err)), sys.exc_info()[2]
+ # We now have the object, but haven't set the correct
+ # state yet. Tell the bridge about this value right
+ # away, that's needed because `value` might be part
+ # of the object state which we'll retrieve next.
setValue(value)
state = coder.decodeObjectForKey_(kSTATE)
@@ -312,13 +319,14 @@
def load_reduce(coder, setValue):
func = coder.decodeObjectForKey_(kFUNC)
-
- # XXX: a problem: ``args`` might contain
- # the object we want to recover (either
- # directly or somewhere in the object graph)
args = coder.decodeObjectForKey_(kARGS)
value = func(*args)
+
+ # We now have the object, but haven't set the correct
+ # state yet. Tell the bridge about this value right
+ # away, that's needed because `value` might be part
+ # of the object state which we'll retrieve next.
setValue(value)
listitems = coder.decodeObjectForKey_(kLIST)
Modified: trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonNumber.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonNumber.m (original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonNumber.m Thu May 1 04:13:02 2008
@@ -104,9 +104,89 @@
-(NSDecimal)decimalValue
{
- /* FIXME */
- [NSException raise:NSInvalidArgumentException
- format:@"Cannot convert python number to NSDecimal"];
+ NSDecimal result;
+ NSDecimalNumber* num;
+
+ unsigned long long mantissa = 0;
+ unsigned short exponent = 0;
+ BOOL negative = NO;
+
+ PyObjC_BEGIN_WITH_GIL
+ if (PyInt_Check(value)) {
+ long lng = PyInt_AsLong(value);
+ if (lng < 0) {
+ mantissa = -lng;
+ exponent = 0;
+ negative = YES;
+ } else {
+ mantissa = lng;
+ exponent = 0;
+ negative = NO;
+ }
+
+ } else if (PyLong_Check(value)) {
+ mantissa = PyLong_AsUnsignedLongLong(value);
+ if (PyErr_Occurred()) {
+ long long lng;
+ PyErr_Clear();
+ lng = PyLong_AsLongLong(value);
+ if (PyErr_Occurred()) {
+ PyObjC_GIL_FORWARD_EXC();
+ }
+
+ if (lng < 0) {
+ mantissa = -lng;
+ exponent = 0;
+ negative = YES;
+ } else {
+ mantissa = lng;
+ exponent = 0;
+ negative = NO;
+ }
+ } else {
+ exponent = 0;
+ negative = NO;
+ }
+
+ } else if (PyFloat_Check(value)) {
+ PyObject* strVal = PyObject_Repr(value);
+ PyObject* uniVal = NULL;
+
+ if (strVal == NULL) {
+ PyObjC_GIL_FORWARD_EXC();
+ }
+
+ uniVal = PyUnicode_FromEncodedObject(strVal, "ascii", "strict");
+ Py_DECREF(strVal);
+ if (uniVal == NULL) {
+ PyObjC_GIL_FORWARD_EXC();
+ }
+
+ NSString* stringVal = PyObjC_PythonToId(uniVal);
+ Py_DECREF(uniVal);
+
+ num = [[NSDecimalNumber alloc] initWithString:stringVal];
+ result = [num decimalValue];
+ [num release];
+ PyObjC_GIL_RETURN(result);
+
+ } else {
+ PyErr_Format(PyExc_TypeError, "cannot convert object of %s to NSDecimal",
+ value->ob_type->tp_name);
+ PyObjC_GIL_FORWARD_EXC();
+ }
+
+ PyObjC_END_WITH_GIL
+
+
+
+ num = [[NSDecimalNumber alloc]
+ initWithMantissa:mantissa
+ exponent:exponent
+ isNegative:negative];
+ result = [num decimalValue];
+ [num release];
+ return result;
}
-(double)doubleValue
@@ -296,7 +376,7 @@
} else {
[self release];
[proxy retain];
- self = (OC_PythonObject*)proxy;
+ self = (OC_PythonNumber*)proxy;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.