Index: gobject/pygobject.c
===================================================================
--- gobject/pygobject.c	(revision 934)
+++ gobject/pygobject.c	(working copy)
@@ -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_pick_slot_value(PyTypeObject *type, PyObject *types, 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_pick_slot_value(type, bases, offsetof(PyTypeObject, tp_richcompare));
+    pygobject_pick_slot_value(type, bases, offsetof(PyTypeObject, tp_compare));
+    pygobject_pick_slot_value(type, bases, offsetof(PyTypeObject, tp_hash));
+    pygobject_pick_slot_value(type, bases, offsetof(PyTypeObject, tp_iter));
+    pygobject_pick_slot_value(type, bases, offsetof(PyTypeObject, tp_repr));
+    pygobject_pick_slot_value(type, bases, offsetof(PyTypeObject, tp_str));
+    pygobject_pick_slot_value(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,49 @@
     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_pick_slot_value(PyTypeObject *type, PyObject *types, int slot_offset)
+{
+    void *gobject_value = * (void **) (((char *) &PyGObject_Type) + slot_offset);
+    void *object_value = * (void **) (((char *) &PyBaseObject_Type) + slot_offset);
+    void *value = NULL;
+    int k;
+    int num_types;
+
+    for (k = 0, num_types = PyTuple_Size(types); k < num_types; ++k) {
+	PyTypeObject *type = (PyTypeObject *) PyTuple_GetItem(types, k);
+	void *slot_value = * (void **) (((char *) type) + slot_offset);
+
+	if (slot_value && slot_value != gobject_value && slot_value != object_value) {
+	    if (value) {
+		value = NULL;
+		break;
+	    }
+	    else
+		value = slot_value;
+	}
+    }
+
+    if (value)
+	* (void **) (((char *) type) + slot_offset) = value;
+}
+
 /**
  * pygobject_lookup_class:
  * @gtype: the GType of the GObject subclass.
