Description
I wrote a bit about this in the other repo, but you can ignore all of those insane ramblings in favor of this condensed version:
(PySide 1.2.2, Python 2.7 for 64-bit Windows)
Rarely, I experience this completely inexplicable error nestled within my logging code, miles away from anything that uses a QGLContext:
item = QtGui.QStandardItem(clean_msg(record.getMessage()))
>item.setForeground(QtGui.QBrush(fg))
AttributeError: 'PySide.QtOpenGL.QGLContext' object has no attribute 'setData'
What the fuck, right?
After reading through the baseobject and binding generation code for a bit, the best explanation I can come up with is that a binding is not being released from BindingManager
. Huh?
BindingManager
keeps track of the bindings that go from C++ objects (void *) to Python objects (SbkObject *). This serves several purposes, but only one of them seems to be of interest:
QStandardItem.setData
is a virtual function. When I instantiate a QStandardItem on the Python side, the C++ side will create a CppWrapper - a C++ subclass of QStandardItem which will dispatch its virtual functions through the Python wrapper associated with it through BindingManager
. This is meant to allow me to subclass QStandardItem in Python. Any C++ code that invokes the virtual function will call the overrides implemented on the Python side, thanks to the CppWrapper.
QStandardItem.setData
is called by the implementation of QStandardItem.setForeground
.
I think what is happening is that there is a binding in BindingManager
, mapping the C++ QGLContext to the Python QGLContext, that is not being released. Because it is not released, a QStandardItem CppWrapper will later be created at the same memory address, and the BindingManager
will then contain a mapping that says, roughly, CppWrapper<QStandardItem> -> SbkObject<QGLContext>
Thus, thanks to the CppWrapper, QStandardItem.setForeground
will try to call QGLContext.setData
, resulting in an AttributeError.
I won't speculate on why it isn't being released. I don't think I understand the problem well enough to say anything.
I haven't been able to create a minimal test case that reproduces the error. What I have been able to do is modify my application code in such a way that instead of getting the error rarely, I can now get it >90% of the times the app is launched.