diff options
author | James Henstridge <james@daa.com.au> | 2001-09-28 23:43:46 +0000 |
---|---|---|
committer | James Henstridge <jamesh@src.gnome.org> | 2001-09-28 23:43:46 +0000 |
commit | f788885180a531abbcb5ccf383b86ee1a902fde7 (patch) | |
tree | ce86d4d80b9d2d5aa76128ce6685c112ab626786 | |
parent | 88e11889f6a96868a1aca2c695984f0ef9576926 (diff) | |
download | pygobject-f788885180a531abbcb5ccf383b86ee1a902fde7.tar.gz pygobject-f788885180a531abbcb5ccf383b86ee1a902fde7.tar.xz pygobject-f788885180a531abbcb5ccf383b86ee1a902fde7.zip |
use pyg_type_from_object instead. Based on patch from Elliot.
2001-09-29 James Henstridge <james@daa.com.au>
* gtk/pygtktreemodel.c (pygtk_tree_model_get_column_type): use
pyg_type_from_object instead. Based on patch from Elliot.
* gtk/gtk.override (_wrap_gtk_selection_data__get_data): convert
getter to a function to match codegen changes.
* : merge in python22-branch (see changelog entries below).
-rw-r--r-- | gobject/gobjectmodule.c | 536 | ||||
-rw-r--r-- | gobject/pygobject.h | 17 |
2 files changed, 249 insertions, 304 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index 8bf83d0..14fe42e 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -7,13 +7,21 @@ static GHashTable *class_hash; static GQuark pygobject_wrapper_key = 0; static GQuark pygobject_ownedref_key = 0; -staticforward PyExtensionClass PyGObject_Type; -static void pygobject_dealloc(PyGObject *self); -static PyObject *pygobject_getattro(PyGObject *self, PyObject *attro); -static int pygobject_setattr(PyGObject *self, char *attr, PyObject *val); -static int pygobject_compare(PyGObject *self, PyGObject *v); -static long pygobject_hash(PyGObject *self); -static PyObject *pygobject_repr(PyGObject *self); +staticforward PyTypeObject PyGObject_Type; +static void pygobject_dealloc(PyGObject *self); +static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg); + +static void +object_free(PyObject *op) +{ + PyObject_FREE(op); +} + +static void +object_gc_free(PyObject *op) +{ + PyObject_GC_Del(op); +} /* -------------- __gtype__ objects ---------------------------- */ @@ -103,7 +111,7 @@ pygobject_destroy_notify(gpointer user_data) static void pygobject_register_class(PyObject *dict, const gchar *type_name, - GType type, PyExtensionClass *ec, + GType gtype, PyTypeObject *type, PyObject *bases) { PyObject *o; @@ -112,28 +120,35 @@ pygobject_register_class(PyObject *dict, const gchar *type_name, if (!class_hash) class_hash = g_hash_table_new(g_str_hash, g_str_equal); - class_name = ec->tp_name; - /* set standard pyobject class functions if they aren't already set */ - if (!ec->tp_dealloc) ec->tp_dealloc = (destructor)pygobject_dealloc; - if (!ec->tp_getattro) ec->tp_getattro = (getattrofunc)pygobject_getattro; - if (!ec->tp_setattr) ec->tp_setattr = (setattrfunc)pygobject_setattr; - if (!ec->tp_compare) ec->tp_compare = (cmpfunc)pygobject_compare; - if (!ec->tp_repr) ec->tp_repr = (reprfunc)pygobject_repr; - if (!ec->tp_hash) ec->tp_hash = (hashfunc)pygobject_hash; + class_name = type->tp_name; + type->ob_type = &PyType_Type; if (bases) { - PyExtensionClass_ExportSubclass(dict, (char *)class_name, - *ec, bases); - } else { - PyExtensionClass_Export(dict, (char *)class_name, *ec); + type->tp_bases = bases; + type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0); } - if (type) { - o = pyg_type_wrapper_new(type); - PyDict_SetItemString(ec->class_dictionary, "__gtype__", o); + type->tp_dealloc = (destructor)pygobject_dealloc; + type->tp_traverse = (traverseproc)pygobject_traverse; + type->tp_flags |= Py_TPFLAGS_HAVE_GC; + type->tp_weaklistoffset = offsetof(PyGObject, weakreflist); + type->tp_dictoffset = offsetof(PyGObject, inst_dict); + + if (PyType_Ready(type) < 0) { + g_warning ("couldn't make the type `%s' ready", type->tp_name); + return; + } + + if (gtype) { + o = pyg_type_wrapper_new(gtype); + PyDict_SetItemString(type->tp_dict, "__gtype__", o); + PyDict_SetItemString(type->tp_defined, "__gtype__", o); Py_DECREF(o); } - g_hash_table_insert(class_hash, g_strdup(type_name), ec); + + g_hash_table_insert(class_hash, g_strdup(type_name), type); + + PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); } void @@ -145,17 +160,17 @@ pygobject_register_wrapper(PyObject *self) g_object_set_qdata(obj, pygobject_wrapper_key, self); } -static PyExtensionClass * -pygobject_lookup_class(GType type) +static PyTypeObject * +pygobject_lookup_class(GType gtype) { - PyExtensionClass *ec; + PyTypeObject *type; /* find the python type for this object. If not found, use parent. */ - while ((ec = g_hash_table_lookup(class_hash, g_type_name(type))) == NULL - && type != 0) - type = g_type_parent(type); - g_assert(ec != NULL); - return ec; + while ((type = g_hash_table_lookup(class_hash, g_type_name(gtype))) == NULL + && gtype != 0) + gtype = g_type_parent(gtype); + g_assert(type != NULL); + return type; } static PyObject * @@ -181,8 +196,8 @@ pygobject_new(GObject *obj) return (PyObject *)self; } - tp = (PyTypeObject *)pygobject_lookup_class(G_TYPE_FROM_INSTANCE(obj)); - self = PyObject_NEW(PyGObject, tp); + tp = pygobject_lookup_class(G_TYPE_FROM_INSTANCE(obj)); + self = PyObject_GC_New(PyGObject, tp); if (self == NULL) return NULL; @@ -190,7 +205,6 @@ pygobject_new(GObject *obj) g_object_ref(obj); /* save wrapper pointer so we can access it later */ g_object_set_qdata(obj, pygobject_wrapper_key, self); - self->inst_dict = PyDict_New(); return (PyObject *)self; } @@ -221,7 +235,8 @@ pyg_boxed_dealloc(PyGBoxed *self) { if (self->free_on_dealloc && self->boxed) g_boxed_free(self->gtype, self->boxed); - PyMem_DEL(self); + + self->ob_type->tp_free((PyObject *)self); } static int @@ -248,46 +263,13 @@ pyg_boxed_repr(PyGBoxed *self) return PyString_FromString(buf); } -static PyObject * -pyg_boxed_getattro(PyGBoxed *self, PyObject *attro) -{ - char *attr; - PyObject *ret; - - attr = PyString_AsString(attro); - - ret = Py_FindAttrString((PyObject *)self, attr); - if (ret) - return ret; - PyErr_Clear(); - - if (self->ob_type->tp_getattr) - return (* self->ob_type->tp_getattr)((PyObject *)self, attr); - - PyErr_SetString(PyExc_AttributeError, attr); - return NULL; -} - -static PyObject * -pyg_boxed__class_init__(PyObject *self, PyObject *args) -{ - PyExtensionClass *subclass; - - if (!PyArg_ParseTuple(args, "O:GBoxed.__class_init__", &subclass)) - return NULL; - - g_message("subclassing GBoxed types is bad m'kay"); - PyErr_SetString(PyExc_TypeError, "attempt to subclass a boxed type"); - return NULL; -} - -static PyObject * -pyg_boxed_init(PyGBoxed *self, PyObject *args) +static int +pyg_boxed_init(PyGBoxed *self, PyObject *args, PyObject *kwargs) { gchar buf[512]; if (!PyArg_ParseTuple(args, ":GBoxed.__init__")) - return NULL; + return -1; self->boxed = NULL; self->gtype = 0; @@ -295,16 +277,10 @@ pyg_boxed_init(PyGBoxed *self, PyObject *args) g_snprintf(buf, sizeof(buf), "%s can not be constructed", self->ob_type->tp_name); PyErr_SetString(PyExc_NotImplementedError, buf); - return NULL; + return -1; } -static PyMethodDef pyg_boxed_methods[] = { - {"__class_init__",pyg_boxed__class_init__, METH_VARARGS|METH_CLASS_METHOD}, - {"__init__", (PyCFunction)pyg_boxed_init, METH_VARARGS}, - {NULL,NULL,0} -}; - -static PyExtensionClass PyGBoxed_Type = { +static PyTypeObject PyGBoxed_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "GBoxed", /* tp_name */ @@ -323,43 +299,64 @@ static PyExtensionClass PyGBoxed_Type = { (hashfunc)pyg_boxed_hash, /* tp_hash */ (ternaryfunc)0, /* tp_call */ (reprfunc)0, /* tp_str */ - (getattrofunc)pyg_boxed_getattro, /* tp_getattro */ + (getattrofunc)0, /* tp_getattro */ (setattrofunc)0, /* tp_setattro */ - /* Space for future expansion */ - 0L, 0L, + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ NULL, /* Documentation string */ - METHOD_CHAIN(pyg_boxed_methods), - 0, + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + (PyTypeObject *)0, /* tp_base */ + (PyObject *)0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pyg_boxed_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + object_free, /* tp_free */ + (PyObject *)0, /* tp_bases */ }; static GHashTable *boxed_types = NULL; static void pyg_register_boxed(PyObject *dict, const gchar *class_name, - GType boxed_type, PyExtensionClass *ec) + GType boxed_type, PyTypeObject *type) { PyObject *o; g_return_if_fail(dict != NULL); g_return_if_fail(class_name != NULL); g_return_if_fail(boxed_type != 0); - g_return_if_fail(ec != NULL); if (!boxed_types) boxed_types = g_hash_table_new(g_direct_hash, g_direct_equal); - if (!ec->tp_dealloc) ec->tp_dealloc = (destructor)pyg_boxed_dealloc; - if (!ec->tp_compare) ec->tp_compare = (cmpfunc)pyg_boxed_compare; - if (!ec->tp_hash) ec->tp_hash = (hashfunc)pyg_boxed_hash; - if (!ec->tp_repr) ec->tp_repr = (reprfunc)pyg_boxed_repr; - if (!ec->tp_getattro) ec->tp_getattro = (getattrofunc)pyg_boxed_getattro; + if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_boxed_dealloc; - PyExtensionClass_ExportSubclassSingle(dict, (char *)class_name, *ec, - PyGBoxed_Type); - PyDict_SetItemString(ec->class_dictionary, "__gtype__", + type->ob_type = &PyType_Type; + type->tp_base = &PyGBoxed_Type; + + if (PyType_Ready(type) < 0) { + g_warning("could not get type `%s' ready", type->tp_name); + return; + } + + PyDict_SetItemString(type->tp_dict, "__gtype__", o=pyg_type_wrapper_new(boxed_type)); + PyDict_SetItemString(type->tp_defined, "__gtype__", o); Py_DECREF(o); - g_hash_table_insert(boxed_types, GUINT_TO_POINTER(boxed_type), ec); + g_hash_table_insert(boxed_types, GUINT_TO_POINTER(boxed_type), type); + + PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); } static PyObject * @@ -641,8 +638,8 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj) break; case G_TYPE_OBJECT: { - PyExtensionClass *ec =pygobject_lookup_class(G_VALUE_TYPE(value)); - if (!ExtensionClassSubclassInstance_Check(obj, ec)) { + PyTypeObject *type =pygobject_lookup_class(G_VALUE_TYPE(value)); + if (!PyObject_TypeCheck(obj, type)) { return -1; } g_value_set_object(value, pygobject_get(obj)); @@ -670,7 +667,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj) if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) { g_value_set_boxed(value, obj); - } else if (ExtensionClassSubclassInstance_Check(obj, &PyGBoxed_Type) && + } else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) && G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype)) { g_value_set_boxed(value, pyg_boxed_get(obj, gpointer)); } else if ((bm = pyg_boxed_lookup(G_VALUE_TYPE(value))) != NULL) { @@ -955,89 +952,36 @@ pyg_signal_class_closure_get(void) } /* -------------- PyGObject behaviour ----------------- */ + static void pygobject_dealloc(PyGObject *self) { GObject *obj = self->obj; - if (obj && !(((PyExtensionClass *)self->ob_type)->class_flags & - EXTENSIONCLASS_PYSUBCLASS_FLAG)) { - /* save reference to python wrapper if there are still - * references to the GObject in such a way that it will be - * freed when the GObject is destroyed, so is the python - * wrapper, but if a python wrapper can be */ - if (obj->ref_count > 1) { - Py_INCREF(self); /* grab a reference on the wrapper */ - self->hasref = TRUE; - g_object_set_qdata_full(obj, pygobject_ownedref_key, - self, pygobject_destroy_notify); - g_object_unref(obj); - return; - } - if (!self->hasref) /* don't unref the GObject if it owns us */ - g_object_unref(obj); - } - /* subclass_dealloc (ExtensionClass.c) does this for us for python - * subclasses */ - if (self->inst_dict && - !(((PyExtensionClass *)self->ob_type)->class_flags & - EXTENSIONCLASS_PYSUBCLASS_FLAG)) { - Py_DECREF(self->inst_dict); - } - PyMem_DEL(self); -} - -/* standard getattr method */ -static PyObject * -check_bases(PyGObject *self, PyExtensionClass *class, char *attr) -{ - PyObject *ret; - - if (class->tp_getattr) { - ret = (* class->tp_getattr)((PyObject *)self, attr); - if (ret) - return ret; - else - PyErr_Clear(); + /* save reference to python wrapper if there are still + * references to the GObject in such a way that it will be + * freed when the GObject is destroyed, so is the python + * wrapper, but if a python wrapper can be */ + if (obj && obj->ref_count > 1) { + Py_INCREF(self); /* grab a reference on the wrapper */ + self->hasref = TRUE; + g_object_set_qdata_full(obj, pygobject_ownedref_key, + self, pygobject_destroy_notify); + g_object_unref(obj); + return; } - if (PyExtensionClass_Check(class) && class->bases) { - guint i, len = PyTuple_Size(class->bases); + if (obj && !self->hasref) /* don't unref the GObject if it owns us */ + g_object_unref(obj); - for (i = 0; i < len; i++) { - PyExtensionClass *base = (PyExtensionClass *)PyTuple_GetItem( - class->bases, i); - - ret = check_bases(self, base, attr); - if (ret) - return ret; - } - } - return NULL; -} -static PyObject * -pygobject_getattro(PyGObject *self, PyObject *attro) -{ - char *attr; - PyObject *ret; + PyObject_ClearWeakRefs((PyObject *)self); - attr = PyString_AsString(attro); + PyObject_GC_UnTrack((PyObject *)self); - ret = Py_FindAttrString((PyObject *)self, attr); - if (ret) - return ret; - PyErr_Clear(); - ret = check_bases(self, (PyExtensionClass *)self->ob_type, attr); - if (ret) - return ret; - PyErr_SetString(PyExc_AttributeError, attr); - return NULL; -} + if (self->inst_dict) + Py_DECREF(self->inst_dict); + self->inst_dict = NULL; -static int -pygobject_setattr(PyGObject *self, char *attr, PyObject *value) -{ - PyDict_SetItemString(INSTANCE_DICT(self), attr, value); - return 0; + self->ob_type->tp_free((PyObject *)self); } static int @@ -1064,90 +1008,43 @@ pygobject_repr(PyGObject *self) return PyString_FromString(buf); } -/* ---------------- PyGObject methods ----------------- */ -static destructor real_subclass_dealloc = NULL; -static void -pygobject_subclass_dealloc(PyGObject *self) +static int +pygobject_traverse(PyGObject *self, visitproc visit, void *arg) { - GObject *obj = self->obj; - - if (obj) { - /* save reference to python wrapper if there are still - * references to the GObject in such a way that it will be - * freed when the GObject is destroyed, so is the python - * wrapper, but if a python wrapper can be */ - if (obj->ref_count > 1) { - Py_INCREF(self); /* grab a reference on the wrapper */ - self->hasref = TRUE; - g_object_set_qdata_full(obj, pygobject_ownedref_key, - self, pygobject_destroy_notify); - g_object_unref(obj); - return; - } - if (!self->hasref) /* don't unref the GObject if it owns us */ - g_object_unref(obj); - } - if (real_subclass_dealloc) - (* real_subclass_dealloc)((PyObject *)self); + if (self->inst_dict) + return visit(self->inst_dict, arg); + return 0; } -/* more hackery to stop segfaults caused by multi deallocs on a subclass - * (which happens quite regularly in pygobject) */ -static PyObject * -pygobject__class_init__(PyObject *something, PyObject *args) -{ - PyExtensionClass *subclass; - GTypeInfo type_info = { - 0, /* class_size */ - (GBaseInitFunc) 0, - (GBaseFinalizeFunc) 0, - (GClassInitFunc) 0, - (GClassFinalizeFunc) 0, - NULL, /* class_data */ - - 0, /* instance_size */ - 0, /* n_preallocs */ - (GInstanceInitFunc) 0 - }; - - if (!PyArg_ParseTuple(args, "O:GObject.__class_init__", &subclass)) - return NULL; - g_message("__class_init__ called for %s", subclass->tp_name); - - /* make sure ExtensionClass doesn't screw up our dealloc hack */ - if ((subclass->class_flags & EXTENSIONCLASS_PYSUBCLASS_FLAG) && - subclass->tp_dealloc != (destructor)pygobject_subclass_dealloc) { - real_subclass_dealloc = subclass->tp_dealloc; - subclass->tp_dealloc = (destructor)pygobject_subclass_dealloc; - } - - /* put code in here to create a new GType for this subclass, using - * __module__.__name__ as the name for the type. Then we can add - * the code needed for adding signals to the subclass. The actual - * implementation will have to wait for a g_type_query function */ - - Py_INCREF(Py_None); - return Py_None; -} +/* ---------------- PyGObject methods ----------------- */ -static PyObject * -pygobject__init__(PyGObject *self, PyObject *args) +static int +pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs) { GType object_type; if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type)) - return NULL; + return -1; object_type = pyg_type_from_object((PyObject *)self); if (!object_type) - return NULL; + return -1; self->obj = g_object_new(object_type, NULL); if (!self->obj) { PyErr_SetString(PyExc_RuntimeError, "could not create object"); - return NULL; + return -1; } pygobject_register_wrapper((PyObject *)self); + + return 0; +} + +static PyObject * +pygobject__gobject_init__(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + if (pygobject_init(self, args, kwargs) < 0) + return NULL; Py_INCREF(Py_None); return Py_None; } @@ -1552,9 +1449,8 @@ pygobject_stop_emission(PyGObject *self, PyObject *args) } static PyMethodDef pygobject_methods[] = { - { "__class_init__", (PyCFunction)pygobject__class_init__, METH_VARARGS|METH_CLASS_METHOD }, - { "__init__", (PyCFunction)pygobject__init__, METH_VARARGS }, - { "__gobject_init__", (PyCFunction)pygobject__init__, METH_VARARGS }, + { "__gobject_init__", (PyCFunction)pygobject__gobject_init__, + METH_VARARGS|METH_KEYWORDS }, { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS }, { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS }, { "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS }, @@ -1576,7 +1472,24 @@ static PyMethodDef pygobject_methods[] = { { NULL, NULL, 0 } }; -static PyExtensionClass PyGObject_Type = { +static PyObject * +pygobject_get_dict(PyGObject *self, void *closure) +{ + if (self->inst_dict == NULL) { + self->inst_dict = PyDict_New(); + if (self->inst_dict == NULL) + return NULL; + } + Py_INCREF(self->inst_dict); + return self->inst_dict; +} + +static PyGetSetDef pygobject_getsets[] = { + { "__dict__", (getter)pygobject_get_dict, (setter)0 }, + { NULL, 0, 0 } +}; + +static PyTypeObject PyGObject_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "GObject", /* tp_name */ @@ -1586,7 +1499,7 @@ static PyExtensionClass PyGObject_Type = { (destructor)pygobject_dealloc, /* tp_dealloc */ (printfunc)0, /* tp_print */ (getattrfunc)0, /* tp_getattr */ - (setattrfunc)pygobject_setattr, /* tp_setattr */ + (setattrfunc)0, /* tp_setattr */ (cmpfunc)pygobject_compare, /* tp_compare */ (reprfunc)pygobject_repr, /* tp_repr */ 0, /* tp_as_number */ @@ -1597,53 +1510,51 @@ static PyExtensionClass PyGObject_Type = { (reprfunc)0, /* tp_str */ (getattrofunc)0, /* tp_getattro */ (setattrofunc)0, /* tp_setattro */ - /* Space for future expansion */ - 0L, 0L, + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC, /* tp_flags */ NULL, /* Documentation string */ - METHOD_CHAIN(pygobject_methods), - EXTENSIONCLASS_INSTDICT_FLAG, + (traverseproc)pygobject_traverse, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + pygobject_methods, /* tp_methods */ + 0, /* tp_members */ + pygobject_getsets, /* tp_getset */ + (PyTypeObject *)0, /* tp_base */ + (PyObject *)0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(PyGObject, inst_dict), /* tp_dictoffset */ + (initproc)pygobject_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + object_gc_free, /* tp_free */ + (PyObject *)0, /* tp_bases */ }; /* ---------------- GInterface functions -------------------- */ -static PyObject * -pyg_interface__class_init__(PyObject *self, PyObject *args) -{ - PyExtensionClass *subclass; - - if (!PyArg_ParseTuple(args, "O:GInterface.__class_init__", &subclass)) - return NULL; - - g_message("subclassing GInterface types is bad m'kay"); - PyErr_SetString(PyExc_TypeError, "attempt to subclass an interface"); - return NULL; -} - -static PyObject * -pyg_interface_init(PyObject *self, PyObject *args) +static int +pyg_interface_init(PyObject *self, PyObject *args, PyObject *kwargs) { gchar buf[512]; if (!PyArg_ParseTuple(args, ":GInterface.__init__")) - return NULL; + return -1; g_snprintf(buf, sizeof(buf), "%s can not be constructed", self->ob_type->tp_name); PyErr_SetString(PyExc_NotImplementedError, buf); - return NULL; + return -1; } -static PyMethodDef pyg_interface_methods[] = { - {"__class_init__", pyg_interface__class_init__, - METH_VARARGS|METH_CLASS_METHOD}, - {"__init__", pyg_interface_init, METH_VARARGS}, - {NULL,NULL,0} -}; - -static PyExtensionClass PyGInterface_Type = { +static PyTypeObject PyGInterface_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "GInterface", /* tp_name */ - sizeof(PyPureMixinObject), /* tp_basicsize */ + sizeof(PyObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)0, /* tp_dealloc */ @@ -1660,27 +1571,52 @@ static PyExtensionClass PyGInterface_Type = { (reprfunc)0, /* tp_str */ (getattrofunc)0, /* tp_getattro */ (setattrofunc)0, /* tp_setattro */ - /* Space for future expansion */ - 0L, 0L, + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ NULL, /* Documentation string */ - METHOD_CHAIN(pyg_interface_methods), - 0, + (traverseproc)0, /* tp_traverse */ + (inquiry)0, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + (PyTypeObject *)0, /* tp_base */ + (PyObject *)0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pyg_interface_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + object_free, /* tp_free */ + (PyObject *)0, /* tp_bases */ }; static void pyg_register_interface(PyObject *dict, const gchar *class_name, - GType type, PyExtensionClass *ec) + GType gtype, PyTypeObject *type) { PyObject *o; - PyExtensionClass_ExportSubclassSingle(dict, (char *)class_name, - *ec, PyGInterface_Type); + type->ob_type = &PyType_Type; + type->tp_base = &PyGInterface_Type; + + if (PyType_Ready(type) < 0) { + g_warning("could not ready `%s'", type->tp_name); + return; + } - if (type) { - o = pyg_type_wrapper_new(type); - PyDict_SetItemString(ec->class_dictionary, "__gtype__", o); + if (gtype) { + o = pyg_type_wrapper_new(gtype); + PyDict_SetItemString(type->tp_dict, "__gtype__", o); + PyDict_SetItemString(type->tp_defined, "__gtype__", o); Py_DECREF(o); } + + PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); } @@ -1806,7 +1742,8 @@ pyg_type_interfaces (PyObject *self, PyObject *args) static PyObject * pyg_type_register(PyObject *self, PyObject *args) { - PyObject *class, *gtype, *module; + PyObject *gtype, *module; + PyTypeObject *class; GType parent_type, instance_type; gchar *type_name = NULL; gint i; @@ -1828,28 +1765,28 @@ pyg_type_register(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O:gobject.type_register", &class)) return NULL; - if (!ExtensionClassSubclass_Check(class, &PyGObject_Type)) { + if (!PyType_IsSubtype(class, &PyGObject_Type)) { PyErr_SetString(PyExc_TypeError,"argument must be a GObject subclass"); return NULL; } /* find the GType of the parent */ - parent_type = pyg_type_from_object(class); + parent_type = pyg_type_from_object((PyObject *)class); if (!parent_type) { return NULL; } /* make name for new widget */ - module = PyObject_GetAttrString(class, "__module__"); + module = PyObject_GetAttrString((PyObject *)class, "__module__"); if (module && PyString_Check(module)) { type_name = g_strconcat(PyString_AsString(module), ".", - ((PyExtensionClass *)class)->tp_name, NULL); + class->tp_name, NULL); } else { if (module) Py_DECREF(module); else PyErr_Clear(); - type_name = g_strdup(((PyExtensionClass *)class)->tp_name); + type_name = g_strdup(class->tp_name); } /* convert '.' in type name to '+', which isn't banned (grumble) */ for (i = 0; type_name[i] != '\0'; i++) @@ -1872,7 +1809,8 @@ pyg_type_register(PyObject *self, PyObject *args) /* set new value of __gtype__ on class */ gtype = pyg_type_wrapper_new(instance_type); - PyObject_SetAttrString(class, "__gtype__", gtype); + PyDict_SetItemString(class->tp_dict, "__gtype__", gtype); + PyDict_SetItemString(class->tp_defined, "__gtype__", gtype); Py_DECREF(gtype); Py_INCREF(Py_None); @@ -2159,14 +2097,22 @@ initgobject(void) pygobject_register_class(d, "GObject", G_TYPE_OBJECT, &PyGObject_Type, NULL); - PyExtensionClass_Export(d, "GInterface", PyGInterface_Type); - PyDict_SetItemString(PyGInterface_Type.class_dictionary, "__gtype__", + PyGInterface_Type.ob_type = &PyType_Type; + if (PyType_Ready(&PyGInterface_Type)) + return; + PyDict_SetItemString(d, "GInterface", (PyObject *)&PyGInterface_Type); + PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gtype__", o=pyg_type_wrapper_new(G_TYPE_INTERFACE)); + PyDict_SetItemString(PyGInterface_Type.tp_defined, "__gtype__", o); Py_DECREF(o); - PyExtensionClass_Export(d, "GBoxed", PyGBoxed_Type); - PyDict_SetItemString(PyGBoxed_Type.class_dictionary, "__gtype__", + PyGBoxed_Type.ob_type = &PyType_Type; + if (PyType_Ready(&PyGBoxed_Type)) + return; + PyDict_SetItemString(d, "GBoxed", (PyObject *)&PyGBoxed_Type); + PyDict_SetItemString(PyGBoxed_Type.tp_dict, "__gtype__", o=pyg_type_wrapper_new(G_TYPE_BOXED)); + PyDict_SetItemString(PyGBoxed_Type.tp_defined, "__gtype__", o); Py_DECREF(o); boxed_marshalers = g_hash_table_new(g_direct_hash, g_direct_equal); diff --git a/gobject/pygobject.h b/gobject/pygobject.h index 2b031a1..4be17b9 100644 --- a/gobject/pygobject.h +++ b/gobject/pygobject.h @@ -3,7 +3,6 @@ #define _PYGOBJECT_H_ #include <Python.h> -#include <ExtensionClass.h> #include <glib.h> #include <glib-object.h> @@ -13,10 +12,11 @@ typedef struct { GObject *obj; gboolean hasref; /* the GObject owns this reference */ PyObject *inst_dict; /* the instance dictionary -- must be last */ + PyObject *weakreflist; /* list of weak references */ } PyGObject; #define pygobject_get(v) (((PyGObject *)(v))->obj) -#define pygobject_check(v,base) (ExtensionClassSubclassInstance_Check(v,base)) +#define pygobject_check(v,base) (PyObject_TypeCheck(v,base)) typedef struct { PyObject_HEAD @@ -26,13 +26,13 @@ typedef struct { } PyGBoxed; #define pyg_boxed_get(v,t) ((t *)((PyGBoxed *)(v))->boxed) -#define pyg_boxed_check(v,typecode) (ExtensionClassSubclassInstance_Check(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode) +#define pyg_boxed_check(v,typecode) (PyObject_TypeCheck(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode) struct _PyGObject_Functions { void (* register_class)(PyObject *dict, const gchar *class_name, - GType type, PyExtensionClass *ec, PyObject *bases); + GType gtype, PyTypeObject *type, PyObject *bases); void (* register_wrapper)(PyObject *self); - PyExtensionClass *(* lookup_class)(GType type); + PyTypeObject *(* lookup_class)(GType type); PyObject *(* newgobj)(GObject *obj); GClosure *(* closure_new)(PyObject *callback, PyObject *extra_args, PyObject *swap_data); @@ -49,11 +49,11 @@ struct _PyGObject_Functions { PyObject *(* value_as_pyobject)(const GValue *value); void (* register_interface)(PyObject *dict, const gchar *class_name, - GType type, PyExtensionClass *ec); + GType gtype, PyTypeObject *type); - PyExtensionClass *boxed_type; + PyTypeObject *boxed_type; void (* register_boxed)(PyObject *dict, const gchar *class_name, - GType boxed_type, PyExtensionClass *ec); + GType boxed_type, PyTypeObject *type); PyObject *(* boxed_new)(GType boxed_type, gpointer boxed, gboolean copy_boxed, gboolean own_ref); @@ -105,7 +105,6 @@ struct _PyGObject_Functions *_PyGObject_API; Py_FatalError("could not import gobject"); \ return; \ } \ - ExtensionClassImported; \ } #endif /* !_INSIDE_PYGOBJECT_ */ |