Re: Problem with methods

Guido.van.Rossum@cwi.nl
Wed, 19 Jan 1994 10:47:44 +0100

> To be more specific, I declare two objects. One is of class
> DraggingWidget (defined by me), and the other is of class TrashCan
> (defined by the package). If the hit and paint procedures are not
> methods of DraggingWidget, everything works fine. If they are
> methods, the call to addDisplayToObject (the code will follow) knows
> that hit and paint are methods, but as soon as the hit and paint
> procedures are called, it thinks that the hit procedure is the
> TrashCan instance and the paint procedure is a null object.

Undoubtedly your code is missing an INCREF call somewhere -- cases of
objects suddenly switching identity are usually caused by this.

The fact that things work find for function pointers but fail for
method pointers suggests to me that you are saving pointers to the
arguments without INCREF'ing them. I suspect that the problem is in
these two calls:

> SUIT_setFunctionPointer (c_object, PYTHON_PAINT, (void*)arg_paintProc);
> SUIT_setFunctionPointer (c_object, PYTHON_HIT, (void*)arg_hitProc);

At the very least you will need to call INCREF(arg_paintProc) and
INCREF(arg_hitProc) here. You should also arrange to XDECREF the
previous contents (*X* to avoid core dumps if the previous contents is
NULL) -- I don't know if you can be 100% sure that it is always a
Python object though, in which case you have somewhat of a problem
that I can't solve for you.

Some more free bits of advice about the following code:

> param = mkvalue ("(O)", SUITobjectList[SUIT_getInteger (obj, WIDGET_NUMBER)].python_object);
> call_object (pythonPaint, param);

mkvalue() returns a new object. call_object() is "refcount neutral".
The net effect is that you are leaking memory here. I suggest
DECREF(param) after the call_object().

Also note that mkvalue() may fail (when it runs out of memory -- not
impossible since you are leaking memory :-). I suggest writing the
following before the call_object():

if (param == NULL) {
printf("mkvalue() exception in SharedPythonPaint\n");
err_clear();
return;
}

The err_clear() is essential, else surrounding code will start to fail
with a random cause. Normally you should never ignore an exception
like this, but since SUIT doesn't allow callbacks to return any kind
of error indicator there is no other choice.

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
URL: <http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>