From 6661be3bedf7ad0da8d33487672a227eb6bee6f1 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 26 Oct 2001 04:26:12 +0000 Subject: Allow assignment to newinstance.__dict__. --- Lib/test/test_descr.py | 26 ++++++++++++++++++++++++++ Objects/typeobject.c | 25 ++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) 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 @@ 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() 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 @@ 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}, }; -- cgit v0.12