[Pyobjc-dev] Re: [Pythonmac-SIG] pyobjc / cocoa

Bill Bumgarner bbum@codefab.com
Thu, 17 Oct 2002 16:42:35 -0400


On Thursday, October 17, 2002, at 04:18 PM, Ronald Oussoren wrote:
> On Thursday, Oct 17, 2002, at 20:29 Europe/Amsterdam, Bill Bumgarner 
> wrote:
>> On Thursday, October 17, 2002, at 02:01 PM, Bob Ippolito wrote:
>>> IMHO there should also be easy to use wrappers for NSNumber and 
>>> NSData.. I use those on a pretty regular basis for stuff that needs 
>>> to get serialized for DO or plists.
> I'd prefer not to special case Objective-C classes in the extension 
> module. We currently do so for NSString and NSNumber, and I'd prefer 
> to not add other exceptions.

NSNumber is definitely bridged from Python -> ObjC, but not the other 
way around (this is what caused me to say that NSNumber wasn't bridged)?

 >>> x = NSArray.arrayWithObject_(1)
 >>> x[0]
<NSCFNumber objective-c instance 0xc1d0e0>
 >>> x.objectAtIndex_(0)
<NSCFNumber objective-c instance 0xc1d0e0>

I'm not implying that I think the above behavior is incorrect -- I'm 
not really sure if I think it is or not.... In the following, it would 
seem that bridging would be the right thing to do:

 >>> a = NSMutableArray.array()
 >>> a.addObject_(1)
 >>> a.addObject_(1)
 >>> a[0]
<NSCFNumber objective-c instance 0xca1510>
 >>> a[1]
<NSCFNumber objective-c instance 0xc905b0>
 >>> a[0] == a[1]
0
 >>> a[0].isEqual_(a[1])
1

But not always -- if the developer were to ever run into a case where 
the (id) of a[0] and a[1] are significant, the transparent bridging of 
the NSNumber->Python(int/float/long) would force the developer to go to 
ObjC for something that is likely trivial to implement.

I remember running into this issue in the Java Bridge (and in the 
Tcl<->ObjC bridge I wrote in 1990/1991/1992).

With all that said, I don't see any reason why NSNumber should not 
provide implementations for at least __eq__ and __ne__ -- and maybe 
even the full set??

__lt__(a, b)
__le__(a, b)
__eq__(a, b)
__ne__(a, b)
__ge__(a, b)
__gt__(a, b)

In any case, bridging types where the type is copied should generally 
be avoided.  It can make it impossible to deal with certain situations 
where the address of the object is meaningful, but the contents are 
not.  It can also lead to some serious inefficiency if a trip across 
the bridge implies a copy each time.

.... response continued below ....

> The current mechanism is a bit of a hack: the 'objc' module maintains 
> a list of methods that are added if a selector is present in the 
> objective-C class (e.g. if the class has 'objectForKey:' add an 
> __getitem__ method that calls objectForKey_). This should work for 
> most collection classes.

This is actually a really good solution in that it greatly automates 
the bridging process and should work transparently with the 'no cost' 
bridged CFTypes.

Anything that makes a copy of data as it is passed across the bridge 
should generally be avoided -- strings are about the only exception.

Unlike the Java bridge, we have the distinct advantage of working with 
two relatively light weight, highly dynamic, languages on either side.  
Java really wants to be a closed box -- it really wants to tightly 
control everything passed into it and, as such, the bridge often had to 
copy and recreated data as it passed across (i.e. there was no way to 
wrap an NSMutableArray instance such that it was a subclass of Vector 
in any kind of an effective fashion).

Python's embedding API provides for a heck of a lot more informal 
flexibility...

b.bum