Close off the "Verre Carlo hack" as discussed on python-dev.
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 507938e..37d8b65 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -3840,6 +3840,22 @@
     p = Proxy(obj)
     vereq(C.__dict__["f"](p), "B.f->C.f")
 
+def verrecarlo():
+    if verbose:
+        print "Testing prohibition of Verre Carlo's hack..."
+    try:
+        object.__setattr__(str, "foo", 42)
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "Verre Carlo __setattr__ suceeded!"
+    try:
+        object.__delattr__(str, "lower")
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "Verre Carlo __delattr__ succeeded!"
+
 
 def test_main():
     do_this_first()
@@ -3929,6 +3945,7 @@
     meth_class_get()
     isinst_isclass()
     proxysuper()
+    verrecarlo()
 
     if verbose: print "All OK"
 
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index a900f55..91c40b9 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3574,6 +3574,24 @@
 	return PyInt_FromLong((long)res);
 }
 
+/* Helper to check for object.__setattr__ or __delattr__ applied to a type.
+   This is called the Verre Carlo hack after its discoverer. */
+static int
+hackcheck(PyObject *self, setattrofunc func, char *what)
+{
+	PyTypeObject *type = self->ob_type;
+	while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+		type = type->tp_base;
+	if (type->tp_setattro != func) {
+		PyErr_Format(PyExc_TypeError,
+			     "can't apply this %s to %s object",
+			     what,
+			     type->tp_name);
+		return 0;
+	}
+	return 1;
+}
+
 static PyObject *
 wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
 {
@@ -3583,6 +3601,8 @@
 
 	if (!PyArg_ParseTuple(args, "OO", &name, &value))
 		return NULL;
+	if (!hackcheck(self, func, "__setattr__"))
+		return NULL;
 	res = (*func)(self, name, value);
 	if (res < 0)
 		return NULL;
@@ -3599,6 +3619,8 @@
 
 	if (!PyArg_ParseTuple(args, "O", &name))
 		return NULL;
+	if (!hackcheck(self, func, "__delattr__"))
+		return NULL;
 	res = (*func)(self, name, NULL);
 	if (res < 0)
 		return NULL;