Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6661be3

Browse files
committed
Allow assignment to newinstance.__dict__.
1 parent 0afde13 commit 6661be3

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

Lib/test/test_descr.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,31 @@ def cant(x, C):
20842084
cant(object(), list)
20852085
cant(list(), object)
20862086

2087+
def setdict():
2088+
if verbose: print "Testing __dict__ assignment..."
2089+
class C(object): pass
2090+
a = C()
2091+
a.__dict__ = {'b': 1}
2092+
vereq(a.b, 1)
2093+
def cant(x, dict):
2094+
try:
2095+
x.__dict__ = dict
2096+
except TypeError:
2097+
pass
2098+
else:
2099+
raise TestFailed, "shouldn't allow %r.__dict__ = %r" % (x, dict)
2100+
cant(a, None)
2101+
cant(a, [])
2102+
cant(a, 1)
2103+
try:
2104+
del a.__dict__
2105+
except TypeError:
2106+
pass
2107+
else:
2108+
raise TestFailed, "shouldn't allow del %r.__dict__" % (a)
2109+
# Classes don't allow __dict__ assignment
2110+
cant(C, {})
2111+
20872112
def pickles():
20882113
if verbose:
20892114
print "Testing pickling and copying new-style classes and objects..."
@@ -2391,6 +2416,7 @@ def test_main():
23912416
coercions()
23922417
descrdoc()
23932418
setclass()
2419+
setdict()
23942420
pickles()
23952421
copies()
23962422
binopoverride()

Objects/typeobject.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,31 @@ subtype_dict(PyObject *obj, void *context)
674674
return dict;
675675
}
676676

677+
static int
678+
subtype_setdict(PyObject *obj, PyObject *value, void *context)
679+
{
680+
PyObject **dictptr = _PyObject_GetDictPtr(obj);
681+
PyObject *dict;
682+
683+
if (dictptr == NULL) {
684+
PyErr_SetString(PyExc_AttributeError,
685+
"This object has no __dict__");
686+
return -1;
687+
}
688+
if (value == NULL || !PyDict_Check(value)) {
689+
PyErr_SetString(PyExc_TypeError,
690+
"__dict__ must be set to a dictionary");
691+
return -1;
692+
}
693+
dict = *dictptr;
694+
Py_INCREF(value);
695+
*dictptr = value;
696+
Py_XDECREF(dict);
697+
return 0;
698+
}
699+
677700
static PyGetSetDef subtype_getsets[] = {
678-
{"__dict__", subtype_dict, NULL, NULL},
701+
{"__dict__", subtype_dict, subtype_setdict, NULL},
679702
{0},
680703
};
681704

0 commit comments

Comments
 (0)