Various fixups (most suggested by Armin Rigo).
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 61ba853..7ad8af0 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -12,7 +12,6 @@
 /* Fast access macros */ 
 
 #define DICT_CONTAINS(d, k)  (d->ob_type->tp_as_sequence->sq_contains(d, k))
-#define IS_SET(so)	(so->ob_type == &PySet_Type || so->ob_type == &PyFrozenSet_Type)
 
 /* set object **********************************************************/
 
@@ -42,8 +41,6 @@
 			Py_DECREF(it);
 			Py_DECREF(data);
 			Py_DECREF(item);
-			PyErr_SetString(PyExc_TypeError,
-					"all set entries must be immutable");
 			return NULL;
                 } 
 		Py_DECREF(item);
@@ -67,7 +64,7 @@
 }
 
 static PyObject *
-set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
 	PyObject *iterable = NULL;
 
@@ -76,6 +73,14 @@
 	return make_new_set(type, iterable);
 }
 
+static PyObject *
+set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *iterable = NULL;
+
+	return make_new_set(type, NULL);
+}
+
 static void
 set_dealloc(PySetObject *so)
 {
@@ -139,6 +144,8 @@
 	PyObject *item, *data, *it;
 
 	result = (PySetObject *)set_copy(so);
+	if (result == NULL)
+		return NULL;
 	it = PyObject_GetIter(other);
 	if (it == NULL) {
 		Py_DECREF(result);
@@ -150,8 +157,6 @@
 			Py_DECREF(it);
 			Py_DECREF(result);
 			Py_DECREF(item);
-			PyErr_SetString(PyExc_TypeError,
-					"all set entries must be immutable");
 			return NULL;
                 } 
 		Py_DECREF(item);
@@ -183,8 +188,6 @@
                 if (PyDict_SetItem(data, item, Py_True) == -1) {
 			Py_DECREF(it);
 			Py_DECREF(item);
-			PyErr_SetString(PyExc_TypeError,
-					"all set entries must be immutable");
 			return NULL;
                 } 
 		Py_DECREF(item);
@@ -201,7 +204,7 @@
 static PyObject *
 set_or(PySetObject *so, PyObject *other)
 {
-	if (!IS_SET(so) || !IS_SET(other)) {
+	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
@@ -213,7 +216,7 @@
 {
 	PyObject *result;
 
-	if (!IS_SET(other)) {
+	if (!PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
@@ -249,8 +252,6 @@
 				Py_DECREF(it);
 				Py_DECREF(result);
 				Py_DECREF(item);
-				PyErr_SetString(PyExc_TypeError,
-						"all set entries must be immutable");
 				return NULL;
 			}
 		}
@@ -291,8 +292,6 @@
 				Py_DECREF(newdict);
 				Py_DECREF(it);
 				Py_DECREF(item);
-				PyErr_SetString(PyExc_TypeError,
-						"all set entries must be immutable");
 				return NULL;
 			}
 		}
@@ -315,7 +314,7 @@
 static PyObject *
 set_and(PySetObject *so, PyObject *other)
 {
-	if (!IS_SET(so) || !IS_SET(other)) {
+	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
@@ -327,7 +326,7 @@
 {
 	PyObject *result;
 
-	if (!IS_SET(other)) {
+	if (!PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
@@ -416,7 +415,7 @@
 static PyObject *
 set_sub(PySetObject *so, PyObject *other)
 {
-	if (!IS_SET(so) || !IS_SET(other)) {
+	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
@@ -428,7 +427,7 @@
 {
 	PyObject *result;
 
-	if (!IS_SET(other)) {
+	if (!PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
@@ -475,8 +474,6 @@
 				Py_DECREF(otherset);
 				Py_DECREF(result);
 				Py_DECREF(item);
-				PyErr_SetString(PyExc_TypeError,
-						"all set entries must be immutable");
 				return NULL;
 			} 
 		}
@@ -506,7 +503,7 @@
 
 	if (PyDict_Check(other))
 		otherdata = other;
-	else if (IS_SET(other))
+	else if (PyAnySet_Check(other))
 		otherdata = ((PySetObject *)other)->data;
 	else {
 		otherset = (PySetObject *)make_new_set(so->ob_type, other);
@@ -525,8 +522,6 @@
 				Py_XDECREF(otherset);
 				Py_DECREF(it);
 				Py_DECREF(item);
-				PyErr_SetString(PyExc_TypeError,
-						"all set entries must be immutable");
 				return NULL;
 			}
 		} else {
@@ -534,8 +529,6 @@
 				Py_XDECREF(otherset);
 				Py_DECREF(it);
 				Py_DECREF(item);
-				PyErr_SetString(PyExc_TypeError,
-						"all set entries must be immutable");
 				return NULL;
 			}
 		}
@@ -554,7 +547,7 @@
 static PyObject *
 set_xor(PySetObject *so, PyObject *other)
 {
-	if (!IS_SET(so) || !IS_SET(other)) {
+	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
@@ -566,7 +559,7 @@
 {
 	PyObject *result;
 
-	if (!IS_SET(other)) {
+	if (!PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
@@ -583,7 +576,7 @@
 {
 	PyObject *otherdata, *it, *item;
 
-	if (!IS_SET(other)) {
+	if (!PyAnySet_Check(other)) {
 		PyErr_SetString(PyExc_TypeError, "can only compare to a set");
 		return NULL;
 	}
@@ -604,6 +597,8 @@
 		Py_DECREF(item);
 	}
 	Py_DECREF(it);
+	if (PyErr_Occurred()) 
+		return NULL;
 	Py_RETURN_TRUE;
 }
 
@@ -612,7 +607,7 @@
 static PyObject *
 set_issuperset(PySetObject *so, PyObject *other)
 {
-	if (!IS_SET(other)) {
+	if (!PyAnySet_Check(other)) {
 		PyErr_SetString(PyExc_TypeError, "can only compare to a set");
 		return NULL;
 	}
@@ -653,20 +648,21 @@
 		hash ^= PyObject_Hash(item);
 		Py_DECREF(item);
 	}
-	so->hash = hash;
 	Py_DECREF(it);
+	if (PyErr_Occurred()) 
+		return -1;
+	so->hash = hash;
 	return hash;
 }
 
 static PyObject *
 set_richcompare(PySetObject *v, PyObject *w, int op)
 {
-	/* XXX factor out is_set test */
-	if (op == Py_EQ && !IS_SET(w))
-		Py_RETURN_FALSE;
-	else if (op == Py_NE && !IS_SET(w))
-		Py_RETURN_TRUE;
-	if (!IS_SET(w)) {
+	if(!PyAnySet_Check(w)) {
+		if (op == Py_EQ)
+			Py_RETURN_FALSE;
+		if (op == Py_NE)
+			Py_RETURN_TRUE;
 		PyErr_SetString(PyExc_TypeError, "can only compare to a set");
 		return NULL;
 	}
@@ -698,8 +694,12 @@
 	PyObject *keys, *result, *listrepr;
 
 	keys = PyDict_Keys(so->data);
+	if (keys == NULL)
+		return NULL;
 	listrepr = PyObject_Repr(keys);
 	Py_DECREF(keys);
+	if (listrepr == NULL)
+		return NULL;
 
 	result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
 		PyString_AS_STRING(listrepr));
@@ -732,6 +732,8 @@
 	}
 	Py_DECREF(it);
 	fprintf(fp, "])");
+	if (PyErr_Occurred()) 
+		return -1;
 	return 0;
 }
 
@@ -810,8 +812,10 @@
 		return NULL;
 	}
 	Py_INCREF(key);
-	if (PyDict_DelItem(so->data, key) == -1)
-		PyErr_Clear();
+	if (PyDict_DelItem(so->data, key) == -1) {
+		Py_DECREF(key);
+		return NULL;
+	}
 	return key;
 }
 
@@ -837,6 +841,28 @@
 
 PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
 
+static int
+set_init(PySetObject *self, PyObject *args, PyObject *kwds)
+{
+	PyObject *iterable = NULL;
+	PyObject *result;
+
+	if (!PyAnySet_Check(self))
+		return -1;
+	if (!PyArg_UnpackTuple(args, self->ob_type->tp_name, 0, 1, &iterable))
+		return -1;
+	PyDict_Clear(self->data);
+	self->hash = -1;
+	if (iterable == NULL)
+		return 0;
+	result = set_union_update(self, iterable);
+	if (result != NULL) {
+		Py_DECREF(result);
+		return 0;
+	}
+	return -1;
+}
+
 static PySequenceMethods set_as_sequence = {
 	(inquiry)set_len,		/* sq_length */
 	0,				/* sq_concat */
@@ -971,7 +997,7 @@
 	0,				/* tp_descr_get */
 	0,				/* tp_descr_set */
 	0,				/* tp_dictoffset */
-	0,				/* tp_init */
+	(initproc)set_init,		/* tp_init */
 	PyType_GenericAlloc,		/* tp_alloc */
 	set_new,			/* tp_new */
 	PyObject_GC_Del,		/* tp_free */
@@ -1068,6 +1094,6 @@
 	0,				/* tp_dictoffset */
 	0,				/* tp_init */
 	PyType_GenericAlloc,		/* tp_alloc */
-	set_new,			/* tp_new */
+	frozenset_new,			/* tp_new */
 	PyObject_GC_Del,		/* tp_free */
 };