[Python-Dev] GC and ExtensionClass
Martin v. Loewis
martin@loewis.home.cs.tu-berlin.de
Sun, 13 May 2001 00:32:10 +0200
> 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 (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.
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.
Regards,
Martin
typedef struct {
PyObject_VAR_HEAD
char *tp_name; /* For printing */
int tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
printfunc tp_print;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
cmpfunc tp_compare;
reprfunc tp_repr;
/* Method suites for standard classes */
PyNumberMethods *tp_as_number;
PySequenceMethods *tp_as_sequence;
PyMappingMethods *tp_as_mapping;
/* More standard operations (at end for binary compatibility) */
hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;
/* Space for future expansion */
long tp_xxx3;
long tp_xxx4;
char *tp_doc; /* Documentation string */
#ifdef COUNT_ALLOCS
/* these must be last */
int tp_alloc;
int tp_free;
int tp_maxalloc;
struct _typeobject *tp_next;
#endif
PyMethodChain methods;
long class_flags;
PyObject *class_dictionary;
PyObject *bases;
PyObject *reserved;
} PyExtensionClass;