summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-10-26 04:26:12 (GMT)
committerGuido van Rossum <guido@python.org>2001-10-26 04:26:12 (GMT)
commit6661be3bedf7ad0da8d33487672a227eb6bee6f1 (patch)
treea9915bc35a9dbc759b3843f9a11aa8aed0f6b6fb
parent0afde13b435f484ecbc3e95107d2318415f21d29 (diff)
downloadcpython-6661be3bedf7ad0da8d33487672a227eb6bee6f1.zip
cpython-6661be3bedf7ad0da8d33487672a227eb6bee6f1.tar.gz
cpython-6661be3bedf7ad0da8d33487672a227eb6bee6f1.tar.bz2
Allow assignment to newinstance.__dict__.
-rw-r--r--Lib/test/test_descr.py26
-rw-r--r--Objects/typeobject.c25
2 files changed, 50 insertions, 1 deletions
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},
};