[Python-Dev] A little GC confusion (original) (raw)
David Abrahams David Abrahams" <david.abrahams@rcn.com
Thu, 21 Feb 2002 08:06:05 -0500
- Previous message: [Python-Dev] Meta-reflections
- Next message: [Python-Dev] A little GC confusion
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi All,
The following extension module (AA) is a reduced example of what I'm doing to make extension classes in 2.2. I followed the examples given by typeobject.c. When I "import AA,pdb" I get a crash in GC. Investigating further, I see this makes sense: GC is enabled in class_metatype_object, yet class_type_object does not follow the first rule of objects whose type has GC enabled:
"The memory for the object must be allocated using PyObject_GC_New()
or PyObject_GC_VarNew()."
So, I guess the question is, how does PyBaseObject_Type (also statically allocated) get away with it?
TIA, Dave
// Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include <Python.h>
PyTypeObject class_metatype_object = { PyObject_HEAD_INIT(0) 0, "Boost.Python.class", PyType_Type.tp_basicsize, 0, 0, /* tp_dealloc / 0, / tp_print / 0, / tp_getattr / 0, / tp_setattr / 0, / tp_compare / 0, / tp_repr / 0, / tp_as_number / 0, / tp_as_sequence / 0, / tp_as_mapping / 0, / tp_hash / 0, / tp_call / 0, / tp_str / 0, / tp_getattro / 0, / tp_setattro / 0, / tp_as_buffer / Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, / tp_flags / 0, / tp_doc / 0, / tp_traverse / 0, / tp_clear / 0, / tp_richcompare / 0, / tp_weaklistoffset / 0, / tp_iter / 0, / tp_iternext / 0, / tp_methods / 0, / tp_members / 0, / tp_getset / 0, // &PyType_Type, / tp_base / 0, / tp_dict / 0, / tp_descr_get / 0, / tp_descr_set / 0, / tp_dictoffset / 0, / tp_init / 0, / tp_alloc / 0, // PyType_GenericNew / tp_new */ };
// Get the metatype object for all extension classes. PyObject* class_metatype() { if (class_metatype_object.tp_dict == 0) { class_metatype_object.ob_type = &PyType_Type; class_metatype_object.tp_base = &PyType_Type; if (PyType_Ready(&class_metatype_object)) return 0; } Py_INCREF(&class_metatype_object); return (PyObject*)&class_metatype_object; }
// Each extension instance will be one of these typedef struct instance { PyObject_HEAD void* objects; } instance;
static void instance_dealloc(PyObject* inst) { instance* kill_me = (instance*)inst;
inst->ob_type->tp_free(inst);
}
PyTypeObject class_type_object = { PyObject_HEAD_INIT(0) file://&class_metatype_object) 0, "Boost.Python.instance", sizeof(PyObject), 0, instance_dealloc, /* tp_dealloc / 0, / tp_print / 0, / tp_getattr / 0, / tp_setattr / 0, / tp_compare / 0, / tp_repr / 0, / tp_as_number / 0, / tp_as_sequence / 0, / tp_as_mapping / 0, / tp_hash / 0, / tp_call / 0, / tp_str / 0, / tp_getattro / 0, / tp_setattro / 0, / tp_as_buffer / Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, / tp_flags / 0, / tp_doc / 0, / tp_traverse / 0, / tp_clear / 0, / tp_richcompare / 0, / tp_weaklistoffset / 0, / tp_iter / 0, / tp_iternext / 0, / tp_methods / 0, / tp_members / 0, / tp_getset / 0, file://&PyBaseObject_Type, / tp_base / 0, / tp_dict / 0, / tp_descr_get / 0, / tp_descr_set / 0, / tp_dictoffset / 0, / tp_init / PyType_GenericAlloc, / tp_alloc */ PyType_GenericNew };
PyObject* class_type() { if (class_type_object.tp_dict == 0) { class_type_object.ob_type = (PyTypeObject*)class_metatype(); class_type_object.tp_base = &PyBaseObject_Type; if (PyType_Ready(&class_type_object)) return 0; } Py_INCREF(&class_type_object); return (PyObject*)&class_type_object; }
PyObject* make_class() { PyObject* bases, *args, *mt, *result; bases = PyTuple_New(1); PyTuple_SET_ITEM(bases, 0, class_type());
args = PyTuple_New(3);
PyTuple_SET_ITEM(args, 0, PyString_FromString("AA"));
PyTuple_SET_ITEM(args, 1, bases);
PyTuple_SET_ITEM(args, 2, PyDict_New());
mt = class_metatype();
result = PyObject_CallObject(mt, args);
Py_XDECREF(mt);
Py_XDECREF(args);
return result;
}
static PyMethodDef SpamMethods[] = { {NULL, NULL} /* Sentinel */ };
DL_EXPORT(void) initAA() { PyObject *m, *d;
m = Py_InitModule("AA", SpamMethods);
d = PyModule_GetDict(m);
PyDict_SetItemString(d, "AA", make_class());
}
+---------------------------------------------------------------+ David Abrahams C++ Booster (http://www.boost.org) O__ == Pythonista (http://www.python.org) c/ /'_ == resume: http://users.rcn.com/abrahams/resume.html () () == email: david.abrahams@rcn.com +---------------------------------------------------------------+
- Previous message: [Python-Dev] Meta-reflections
- Next message: [Python-Dev] A little GC confusion
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]