[Python-Dev] GC and ExtensionClass

Guido van Rossum guido@digicool.com
Sun, 13 May 2001 17:26:39 -0500


> > Now, if you are using the 1.4 version of ExtensionClasses you might
> > not have the tp_flags field either (I don't know, I can't easily
> > check) but the 1.5.2-compatible version of ExtensionClasses doesn't
> > even require recompilation to work with Python 2.1.
> 
> I'll attach a copy below of the struct as defined in
> pygtk-0.7.0-unstable-dont-use.tar.gz

Hmm...  I like that filename. :-)

> (0.6.6 does not use extension
> classes). As you can see, it does not provide tp_flags, but has a
> field of tp_xxx4 for it.

Sorry, that's what I meant.  This is guaranteed to be initialized to 0
(unless a module goes out of its way to put a value in it, in which
case they deserve what they get).

> That *should* work, except that it also has its 'methods' field where
> tp_traverse would go, and its class_flags field where tp_clear would
> go.
> 
> Now, you write
> 
> > ExtensionClasses (at least recent versions that worked with 1.5.2)
> > contain a copy of the type object up to and including the tp_flags
> > field, and the 2.1 code is careful not to use any newer fields
> > without first checking the corresponding flag bit.
> 
> In this generality, it is apparently not true: Modules/gcmodule.c has,
> in delete_garbage,
> 
> 			if ((clear = op->ob_type->tp_clear) != NULL) {
> ...
> 		traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
> 		(void) traverse(PyObject_FROM_GC(gc),
> 			       (visitproc)visit_decref,
> 			       NULL);
> 
> which does not check any flags. That still shouldn't cause any
> problems, since the Gtk objects should never end up in the GC lists -
> but may be I'm missing something.

I agree with your analysis: op here is gotten from a PyGC_Head, so it
cannot be a PyExtensionClass instance, so Neil's code should be safe.
Objects never have a GC head unless they specifically request it;
PyExtensionClass certainly doesn't request a GC head.

--Guido van Rossum (home page: http://www.python.org/~guido/)