pygobject r938 - in trunk: . gobject
- From: paulp svn gnome org
- To: svn-commits-list gnome org
- Subject: pygobject r938 - in trunk: . gobject
- Date: Sun, 10 Aug 2008 15:38:58 +0000 (UTC)
Author: paulp
Date: Sun Aug 10 15:38:58 2008
New Revision: 938
URL: http://svn.gnome.org/viewvc/pygobject?rev=938&view=rev
Log:
2008-08-10 Paul Pogonyshev <pogonyshev gmx net>
Bug 547104 â improve runtime type wrapper creation
* gobject/pygobject.c (pygobject_new_with_interfaces): Use new
pygobject_find_slot_for() for `tp_richcompare', `tp_compare`,
`tp_hash', `tp_iter', `tp_repr', `tp_str' and `tp_print'.
(pygobject_find_slot_for): New static function.
Modified:
trunk/ChangeLog
trunk/gobject/pygobject.c
Modified: trunk/gobject/pygobject.c
==============================================================================
--- trunk/gobject/pygobject.c (original)
+++ trunk/gobject/pygobject.c Sun Aug 10 15:38:58 2008
@@ -38,6 +38,7 @@
static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj);
static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
+static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset);
GType PY_TYPE_OBJECT = 0;
GQuark pygobject_class_key;
GQuark pygobject_class_init_key;
@@ -721,6 +722,14 @@
type->tp_traverse = py_parent_type->tp_traverse;
type->tp_clear = py_parent_type->tp_clear;
+ pygobject_find_slot_for(type, bases, offsetof(PyTypeObject, tp_richcompare));
+ pygobject_find_slot_for(type, bases, offsetof(PyTypeObject, tp_compare));
+ pygobject_find_slot_for(type, bases, offsetof(PyTypeObject, tp_hash));
+ pygobject_find_slot_for(type, bases, offsetof(PyTypeObject, tp_iter));
+ pygobject_find_slot_for(type, bases, offsetof(PyTypeObject, tp_repr));
+ pygobject_find_slot_for(type, bases, offsetof(PyTypeObject, tp_str));
+ pygobject_find_slot_for(type, bases, offsetof(PyTypeObject, tp_print));
+
if (PyType_Ready(type) < 0) {
g_warning ("couldn't make the type `%s' ready", type->tp_name);
pyglib_gil_state_release(state);
@@ -742,6 +751,60 @@
return type;
}
+/* Pick appropriate value for given slot (at slot_offset inside
+ * PyTypeObject structure). It must be a pointer, e.g. a pointer to a
+ * function. We use the following heuristic:
+ *
+ * - Scan all types listed as bases of the type.
+ * - If for exactly one base type slot value is non-NULL and
+ * different from that of 'object' and 'GObject', set current type
+ * slot into that value.
+ * - Otherwise (if there is more than one such base type or none at
+ * all) don't touch it and live with Python default.
+ *
+ * The intention here is to propagate slot from custom wrappers to
+ * wrappers created at runtime when appropriate. We prefer to be on
+ * the safe side, so if there is potential collision (more than one
+ * custom slot value), we discard custom overrides altogether.
+ */
+static void
+pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset)
+{
+#define TYPE_SLOT(type) (* (void **) (((char *) (type)) + slot_offset))
+
+ void *found_slot = NULL;
+ int num_bases = PyTuple_Size(bases);
+ int i;
+
+ for (i = 0; i < num_bases; ++i) {
+ PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i);
+ void *slot = TYPE_SLOT(base_type);
+
+ if (slot == NULL)
+ continue;
+ if (slot == TYPE_SLOT(&PyGObject_Type) ||
+ slot == TYPE_SLOT(&PyBaseObject_Type))
+ continue;
+
+ if (found_slot != NULL && found_slot != slot) {
+ /* We have a conflict: more than one base use different
+ * custom slots. To be on the safe side, we bail out.
+ */
+ return;
+ }
+
+ found_slot = slot;
+ }
+
+ /* Only perform the final assignment if at least one base has a
+ * custom value. Otherwise just leave this type's slot untouched.
+ */
+ if (found_slot != NULL)
+ TYPE_SLOT(type) = found_slot;
+
+#undef TYPE_SLOT
+}
+
/**
* pygobject_lookup_class:
* @gtype: the GType of the GObject subclass.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]