Re: [Pyobjc-dev] NSString & mutability
Brought to you by:
ronaldoussoren
From: <bb...@ma...> - 2003-02-05 16:55:57
|
On Tuesday, Feb 4, 2003, at 18:28 US/Eastern, Just van Rossum wrote: > Let's focus on making NSString instances work as much as Python strings > as possible. > > For fun, I removed the conversion, and (quite obviously) as it stands > stuff breaks horribly. The first error thrown by starting a random > PythonCocoa app is in NibClassBuilder, where an NSString is fed to an > os.path function. I _think_ for many cases it's enough if we implement > all string methods. There aren't even that many: > > 'capitalize', 'center', 'count', 'encode', 'endswith', > 'expandtabs', > 'find', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', > 'islower', 'isnumeric', 'isspace', 'istitle', 'isupper', 'join', > 'ljust', 'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust', > 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', > 'title', 'translate', 'upper', 'zfill' In objc_support.m, I changed the thing that converts from NSString to PythonStrings to this: else if ([obj isKindOfClass:[NSString class]]) { retobject = buffer_from_nsstring(obj); } It is really just a convenience hook via which I can try different recipes for converting between. I current implement buffer_from_nsstring() as: static PyObject* buffer_from_nsstring(NSString *aString) { PyObject* result; NSData* data = [aString dataUsingEncoding:NSASCIIStringEncoding]; if (data == NULL) { const char* utf8 = [aString UTF8String]; result = PyUnicode_DecodeUTF8(utf8, strlen(utf8), "strict"); } else { result = PyString_FromStringAndSize([data bytes], [data length]); } return result; } This works-- it is basically *exactly* like the implementation in CVS. I tried an implementation that returns a character buffer, but a unit test that does... self.assertEquals("foo", NSString.stringWithString_("foo")) ... fails because "foo" cannot be compared to an instance of <character buffer>. Nuts. What we really need is a way to attach the NSString instance to the PythonString instance such that any crossing of the bridge can directly grab the NSString on entry into ObjC. I have realized that I'm wrong in regards to avoiding conversion -- conversion isn't the problem. The problem is the lack of preserving the identity as a string crosses from Python to ObjC and back again. That the developer will always have to access the NSString methods via unbound methods is annoying, but not catastrophically so. Example: By 'preserving the identity', I mean that the assertion error in the following should not happen [should behave like the Python equivalent]: >>> from Foundation import * >>> a = NSMutableArray.array() >>> s = "foo bar baz" >>> a.addObject_(s) >>> id(s) 1669344 >>> id(a[0]) 6531696 >>> assert(id(s) == id(a[0])) Traceback (most recent call last): File "<stdin>", line 1, in ? AssertionError >>> k = [s] >>> assert(id(s) == id(k[0])) >>> Mutable strings raise other issues -- mainly that we have to deal with them at all. :-) b.bum |