]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Allow assignment to newinstance.__dict__.
authorGuido van Rossum <guido@python.org>
Fri, 26 Oct 2001 04:26:12 +0000 (04:26 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 26 Oct 2001 04:26:12 +0000 (04:26 +0000)
Lib/test/test_descr.py
Objects/typeobject.c

index 30b04813066150edbb137fe08b8e592b8fe701c6..87f4f0f6f47045184ac17cceb09420b23b26dffb 100644 (file)
@@ -2084,6 +2084,31 @@ def setclass():
     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 @@ def test_main():
     coercions()
     descrdoc()
     setclass()
+    setdict()
     pickles()
     copies()
     binopoverride()
index 5952b4efcff2b4d79d75dfb7a20fdfc1b5d44e0f..ba2834a08bfbca82b6e1ea6a8ae3b2d52068f09a 100644 (file)
@@ -674,8 +674,31 @@ subtype_dict(PyObject *obj, void *context)
        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},
 };