Commit c3e6ef31 authored by Guido van Rossum's avatar Guido van Rossum

Fix for SF bug #642358: only provide a new with a __dict__ or

__weaklist__ descriptor if we added __dict__ or __weaklist__,
respectively.  With unit test.
parent 4339d8ac
......@@ -3686,6 +3686,19 @@ def subclass_right_op():
vereq(E(1) / C(1), "C.__div__")
vereq(C(1) / E(1), "C.__div__") # This one would fail
def dict_type_with_metaclass():
if verbose:
print "Testing type of __dict__ when __metaclass__ set..."
class B(object):
pass
class M(type):
pass
class C:
# In 2.3a1, C.__dict__ was a real dict rather than a dict proxy
__metaclass__ = M
veris(type(C.__dict__), type(B.__dict__))
def test_main():
do_this_first()
......@@ -3771,6 +3784,7 @@ def test_main():
test_mutable_bases_catch_mro_conflict()
mutable_names()
subclass_right_op()
dict_type_with_metaclass()
if verbose: print "All OK"
......
......@@ -1353,9 +1353,9 @@ subtype_getweakref(PyObject *obj, void *context)
return result;
}
static PyGetSetDef subtype_getsets[] = {
/* Not all objects have these attributes!
The descriptor's __get__ method may raise AttributeError. */
/* Three variants on the subtype_getsets list. */
static PyGetSetDef subtype_getsets_full[] = {
{"__dict__", subtype_dict, subtype_setdict,
PyDoc_STR("dictionary for instance variables (if defined)")},
{"__weakref__", subtype_getweakref, NULL,
......@@ -1363,6 +1363,18 @@ static PyGetSetDef subtype_getsets[] = {
{0}
};
static PyGetSetDef subtype_getsets_dict_only[] = {
{"__dict__", subtype_dict, subtype_setdict,
PyDoc_STR("dictionary for instance variables (if defined)")},
{0}
};
static PyGetSetDef subtype_getsets_weakref_only[] = {
{"__weakref__", subtype_getweakref, NULL,
PyDoc_STR("list of weak references to the object (if defined)")},
{0}
};
/* bozo: __getstate__ that raises TypeError */
static PyObject *
......@@ -1810,7 +1822,15 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
type->tp_basicsize = slotoffset;
type->tp_itemsize = base->tp_itemsize;
type->tp_members = et->members;
type->tp_getset = subtype_getsets;
if (type->tp_weaklistoffset && type->tp_dictoffset)
type->tp_getset = subtype_getsets_full;
else if (type->tp_weaklistoffset && !type->tp_dictoffset)
type->tp_getset = subtype_getsets_weakref_only;
else if (!type->tp_weaklistoffset && type->tp_dictoffset)
type->tp_getset = subtype_getsets_dict_only;
else
type->tp_getset = NULL;
/* Special case some slots */
if (type->tp_dictoffset != 0 || nslots > 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