« April 2006 | Main | June 2006 »

May 19, 2006

It's not in a box. anymore...

My family used to have a little joke we developed along with our habit of moving every few years. Every time we couldn't find something the answer was "it's in a box." I've been living here for a while, but something about my visit to the container store (a GREAT retail experience, by the way... better than the apple store) to buy a few of their exclusive-to-the-container-store white sterilite storage containers has cause an organize my house meltdown. Of course I ended up having a bunch of other organization tools delivered, thinking I would eventually start throwing stuff out to reorganize what had become a stack of white file-archiving boxes from Staples.

feng shui attack! (Yes, Jenny, I still have my Nintendo).

So here I am, happily scarfing a pop tart (you can get those delivered here in New York) looking out over the vast, comparitively desolate landscape that is my little home. I've spent the last four hours, already exhausted from a busy day, opening every box I had stored in closets and tossing old junk. I had no idea the extent to which I am a pack rat. I found the packaging for every piece of technology I have bought in the last three years, most of the corresponding techno-geekery, two years worth of magazines, too many random "to do" lists from grad school, and even the recovery disks for my very first laptop. (Toshiba Satellite, ca. 1997, P133, 32MB of RAM baby!)

And believe it or not my new macbook is resting on my bed. Earlier than expected. Unopened. Taunting me. I think it's too cool to come out until my home represents the proper environment for a computer that wears a tuxedo. My cluttered desk was ok for anodized aluminum, a RISC processor, and 1024x768 pixels. But this is flat-black (stay away from me with that spraypaint, Dad), *INTEL* (I don't need no reduced instruction set), and wide screen.

Now it's time to continue the tradition of taking a screwdriver or putty knife to my new computer before I even turn it on... time to add 2 GB of ram.

((Incoherence and probable misspellings not intentional, but I can't keep my eyes open. Now, where's my screwdriver set? I'm not going to be able to find anything for weeeeeks))

May 18, 2006

I did, I did ate a Zombie

From Ronald Oussoren to me (+ pyobjcdev and pythonmac-sig):

I haven't look at your example just yet, will do that later on. I'm
happy you took the time to create a small program that demonstrates
the problem you're seeing, that makes is so much easier to search the
problem.

> What did I learn from this:
>
> 1. Try to use cocoa objects instead of python objects in code that
> uses bindings; pay special attention to collections (lists, etc.).
> At least this *seems* safer because a python object being
> referenced from cocoa is probably more likely to cause problems
> than a cocoa object controlled from python. (?) Then again, it's
> pretty stupid to generalize from one experience...

Using Cocoa datastructures instead of python ones when KVO is
involved is always a good idea. Python doesn't have enough hooks to
allow reliable interception __setitem__. We could (but don't)
get 95% of the way by using the same class-swiffling technique as
used by the ObjC runtime, but could never go all the way.

> 2. GDB is very useful for debugging pyobjc.
> 3. There are a lot of nice pyobjc debugging features, but you have
> to turn them on (See my example project referenced above).
>
> Things I want to know:
> 1. Is there a way, when one gets the memory address of a pyobjc
> proxy object (Like OC_PythonArray) from gdb to figure out which
> python object it's proxying?
The PyObject* is stored as the instance variable 'value' on the proxy
object.

> 2. Is there a way to get the python object from a memory address?

You mean like "(PyObject*)0xDEADBEEF"?

> 3. Is there a reliable way to get (in gdb or pdb) the "Python List
> Object at 0x03423blahblahblah information from the python object
> being proxied

> 4. Can I compile pyobjc with debugging symbols? GDB without them
> hurts my brain.

PyObjC is compiled with debugging symbols by default. Py2app strips
debugging symbols, unless you build with the -A flag.

Ronald

May 04, 2006

I think I just ate a Zombie

Well, I think I've figured out the *WTF* part of my little NSZombie problem.

It really boils down to this:

Bind an NSPopubButton (contents) to a Python List object that is an attribute of a python class placed in an NSArray controlled by an NSArrayController and the OC_PythonArray object from PyObjC corresponding to the Python List gets freed too early. (There's a mouthful... Confusing enough?) Wrap that Python List object in an NSArray.alloc().initWithArray_copyItems_([u'the', u'list'], objc.NO) and (I guess) the NSArray...init... adds one more -retain than does OC_PythonArray and the binding doesn't break.

I'm always nervous to call things like this a bug because maybe I'm not *supposed* to be able to do what I'm trying to do in the way that I'm trying to do it, but this one looks like a bug to me. (With the caveat that I am currently learning pyobjc/cocoa and don't always know the *right* way to do things...)

Try it yourself. Here is the simplest example of the bug I can muster. Set BREAKME = True in testObj.py. Run this in the debugger (breakpoint is set on -[NSZombie retain] and NSZombie is enabled already in the project) and you'll see what happens. Set BREAKME = False and everybody is happy.

What did I learn from this:
1. Try to use cocoa objects instead of python objects in code that uses bindings; pay special attention to collections (lists, etc.). At least this *seems* safer because a python object being referenced from cocoa is probably more likely to cause problems than a cocoa object controlled from python. (?) Then again, it's pretty stupid to generalize from one experience...
2. GDB is very useful for debugging pyobjc.
3. There are a lot of nice pyobjc debugging features, but you have to turn them on (See my example project referenced above).

Things I want to know:
1. Is there a way, when one gets the memory address of a pyobjc proxy object (Like OC_PythonArray) from gdb to figure out which python object it's proxying?
2. Is there a reliable way to get (in gdb or pdb) the "Python List Object at 0x03423blahblahblah information from the python object being proxied?
3. Can I compile pyobjc with debugging symbols? GDB without them hurts my brain.