Fri 3 Sep 2010
Two weeks of knocking my head against a wall finally paid off with a one line code change.
- PyDict_SetItemString(class->tp_dict, “__gtype__”, gtype);
+ PyObject_SetAttrString(class, “__gtype__”, gtype);
For some reason GObjects created in python which inherited from an interface were crashing when running pygobject under Python 3. They worked fine in Python 2. It was a really obscure bug because the symptoms were no where near the actual cause. On a hunch I stepped through the code using gdb in both Python 2 and 3 simultaneously. What I found out was that while most of the code executed in the exact same way, at one point the Python 3 stack was returning a typecode of 80 (the typecode for the GObject type) when grabbing the __gtype__ attribute from the python wrapper. By adding a PyDict_GetItem call for the object’s tp_dict I was able to see that the correct gtype was lurking there. In Python 2 the attr and and tp_dict item both matched up but in Python 3, for some reason it did not propagate.
To be fair the pygobject codebase still contains a lot of early Python C code which combined with the Python 2 to 3 under the hood changes are going to produce a lot of pain in the short term. It just come with the territory. So while I have been cranky the last couple of weeks (the heat wave didn’t help either), that one line patch provided a euphoric release. Besides, while first chasing the bug I was able to produce an 800 line unicode handling patch which didn’t fix the issue but was needed anyway.
[read this post in: ar de es fr it ja ko pt ru zh-CN ]