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.
This commit is contained in:
parent
145a4a0f10
commit
373c7412f2
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue