Change the way __hash__ is inherited; when __eq__ or __cmp__ is overridden
but __hash__ is not, set __hash__ explicitly to None (and tp_hash to NULL).
All unit tests pass now!
diff --git a/Objects/object.c b/Objects/object.c
index cb60320..80111b4 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -320,9 +320,16 @@
 	return internal_print(op, fp, flags, 0);
 }
 
+/* For debugging convenience.  Set a breakpoint here and call it from your DLL */
+void
+_Py_Break(void)
+{
+}
+
 
 /* For debugging convenience.  See Misc/gdbinit for some useful gdb hooks */
-void _PyObject_Dump(PyObject* op)
+void
+_PyObject_Dump(PyObject* op)
 {
 	if (op == NULL)
 		fprintf(stderr, "NULL\n");
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 1578801..f30a826 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2847,6 +2847,33 @@
 	COPYVAL(tp_dictoffset);
 }
 
+/* Map rich comparison operators to their __xx__ namesakes */
+static char *name_op[] = {
+	"__lt__",
+	"__le__",
+	"__eq__",
+	"__ne__",
+	"__gt__",
+	"__ge__",
+	/* These are only for overrides_cmp_or_hash(): */ 
+	"__cmp__",
+	"__hash__",
+};
+
+static int
+overrides_cmp_or_hash(PyTypeObject *type)
+{
+	int i;
+	PyObject *dict = type->tp_dict;
+
+	assert(dict != NULL);
+	for (i = 0; i < 8; i++) {
+		if (PyDict_GetItemString(dict, name_op[i]) != NULL)
+			return 1;
+	}
+	return 0;
+}
+
 static void
 inherit_slots(PyTypeObject *type, PyTypeObject *base)
 {
@@ -2970,9 +2997,12 @@
 	COPYSLOT(tp_call);
 	COPYSLOT(tp_str);
 	{
+		/* Copy comparison-related slots only when
+		   not overriding them anywhere */
 		if (type->tp_compare == NULL &&
 		    type->tp_richcompare == NULL &&
-		    type->tp_hash == NULL)
+		    type->tp_hash == NULL &&
+		    !overrides_cmp_or_hash(type))
 		{
 			type->tp_compare = base->tp_compare;
 			type->tp_richcompare = base->tp_richcompare;
@@ -3020,6 +3050,10 @@
 	PyTypeObject *base;
 	Py_ssize_t i, n;
 
+	if (strcmp(type->tp_name, "C") == 0) {
+		_Py_Break();
+	}
+
 	if (type->tp_flags & Py_TPFLAGS_READY) {
 		assert(type->tp_dict != NULL);
 		return 0;
@@ -3150,6 +3184,18 @@
 		}
 	}
 
+	/* Hack for tp_hash and __hash__.
+	   If after all that, tp_hash is still NULL, and __hash__ is not in
+	   tp_dict, set tp_dict['__hash__'] equal to None.
+	   This signals that __hash__ is not inherited.
+	 */
+	if (type->tp_hash == NULL) {
+		if (PyDict_GetItemString(type->tp_dict, "__hash__") == NULL) {
+			if (PyDict_SetItemString(type->tp_dict, "__hash__", Py_None) < 0)
+				goto error;
+		}
+	}
+
 	/* Some more special stuff */
 	base = type->tp_base;
 	if (base != NULL) {
@@ -4450,16 +4496,6 @@
 	return 0;
 }
 
-/* Map rich comparison operators to their __xx__ namesakes */
-static char *name_op[] = {
-	"__lt__",
-	"__le__",
-	"__eq__",
-	"__ne__",
-	"__gt__",
-	"__ge__",
-};
-
 static PyObject *
 half_richcompare(PyObject *self, PyObject *other, int op)
 {