Re: [Pyobjc-dev] Making List<->Array bridging transparent
Brought to you by:
ronaldoussoren
From: Ronald O. <ous...@ci...> - 2002-11-02 07:06:47
|
On Saturday, Nov 2, 2002, at 05:25 Europe/Amsterdam, Bill Bumgarner wrote: > The following is still broken when bridging ObjC objects into Python. > I have added a unit test to test this in preparation to actually fix > it (even though I have *no clue* how to fix it yet :-). > > >>> from Foundation import * > >>> y = NSMutableArray.arrayWithArray_( range(0,10) ) > >>> x = range(0,10) > >>> x[1:3] = y > Traceback (most recent call last): > File "<stdin>", line 1, in ? > TypeError: must assign list (not "NSCFArray") to slice > >>> > > OK... so, how to fix? I'll think about this. Some experimentation shows that 'y' must really be a list, iterator objects also fail here. It might be usefull to ask on comp.lang.python/pyt...@py... why this is so. > > It looks like we could augment... > > PyObject* ObjCClass_New(Class objc_class) > > ... such that if.... > > [objc_class isKindOfClass: [NSArray class]] > > ... is true, then we add <type 'list'> to the bases for the newly > created Python class object? Assuming a complete implementation of > convenience methods, this would allow bridged instances of NSArray to > function fully on the Python side of the bridge [i.e. work in contexts > like the above where the runtime is testing for a particular type and > not just a set of methods]. I've check the implementation of this feature in Python 2.3 and the code directly accesses the representation of 'y'. That explains why the want a list object instead of a object that implements the list interface. > As an experiment, I tried-- naively-- to add this to the function that > bridges classes to Python... it doesn't work. > > fprintf(stderr, "Adding.... %s\n\n", objc_class->name); > if ( [objc_class respondsToSelector: > @selector(isSubclassOfClass:)] && > [objc_class isSubclassOfClass: objc_getClass("NSArray")] > ) { > _PyTuple_Resize(&bases, 2); > PyTuple_SetItem(bases, 1, (PyObject*)&PyList_Type); > Py_INCREF((&PyList_Type)); > } > > ...... > Adding.... NSArray > > Traceback (most recent call last): > File "Lib/Foundation/test/test_nsexception.py", line 4, in ? > from Foundation import * > File "/usr/lib/python2.2/site-packages/Foundation/__init__.py", line > 42, in ? > class_list = > load_bundle('/System/Library/Frameworks/Foundation.framework') > File "/usr/lib/python2.2/site-packages/Foundation/__init__.py", line > 37, in load_bundle > classes = [ cls > TypeError: multiple bases have instance lay-out conflict I suppose this is because both base-classes contain additional fields in the C-struct: struct PyListObject { // not the actual declaration! PyObject_HEAD PyObject** data; }; struct ObjCObject { // not the actual declaration PyObject_HEAD id real_object; }; The subclass would have to have a C struct that can be casted to either one of these definitions. Ronald |