Allow assignment to newinstance.__dict__.
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 30b0481..87f4f0f 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -2084,6 +2084,31 @@
     cant(object(), list)
     cant(list(), object)
 
+def setdict():
+    if verbose: print "Testing __dict__ assignment..."
+    class C(object): pass
+    a = C()
+    a.__dict__ = {'b': 1}
+    vereq(a.b, 1)
+    def cant(x, dict):
+        try:
+            x.__dict__ = dict
+        except TypeError:
+            pass
+        else:
+            raise TestFailed, "shouldn't allow %r.__dict__ = %r" % (x, dict)
+    cant(a, None)
+    cant(a, [])
+    cant(a, 1)
+    try:
+        del a.__dict__
+    except TypeError:
+        pass
+    else:
+        raise TestFailed, "shouldn't allow del %r.__dict__" % (a)
+    # Classes don't allow __dict__ assignment
+    cant(C, {})
+
 def pickles():
     if verbose:
         print "Testing pickling and copying new-style classes and objects..."
@@ -2391,6 +2416,7 @@
     coercions()
     descrdoc()
     setclass()
+    setdict()
     pickles()
     copies()
     binopoverride()
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 5952b4e..ba2834a 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -674,8 +674,31 @@
 	return dict;
 }
 
+static int
+subtype_setdict(PyObject *obj, PyObject *value, void *context)
+{
+	PyObject **dictptr = _PyObject_GetDictPtr(obj);
+	PyObject *dict;
+
+	if (dictptr == NULL) {
+		PyErr_SetString(PyExc_AttributeError,
+				"This object has no __dict__");
+		return -1;
+	}
+	if (value == NULL || !PyDict_Check(value)) {
+		PyErr_SetString(PyExc_TypeError,
+				"__dict__ must be set to a dictionary");
+		return -1;
+	}
+	dict = *dictptr;
+	Py_INCREF(value);
+	*dictptr = value;
+	Py_XDECREF(dict);
+	return 0;
+}
+
 static PyGetSetDef subtype_getsets[] = {
-	{"__dict__", subtype_dict, NULL, NULL},
+	{"__dict__", subtype_dict, subtype_setdict, NULL},
 	{0},
 };