Commit 6661be3b authored by Guido van Rossum's avatar Guido van Rossum

Allow assignment to newinstance.__dict__.

parent 0afde13b
......@@ -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()
......
......@@ -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},
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment