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
|