Skip to content

Commit 9ef8632

Browse files
committed
Create __dict__ and __weakref__ descriptors for object
1 parent c82d86b commit 9ef8632

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

Objects/typeobject.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4038,22 +4038,25 @@ subtype_getweakref(PyObject *obj, void *context)
40384038

40394039
/* Three variants on the subtype_getsets list. */
40404040

4041+
static char subtype_getset_dict_name[] = "__dict__";
4042+
static char subtype_getset_weakref_name[] = "__weakref__";
4043+
40414044
static PyGetSetDef subtype_getsets_full[] = {
4042-
{"__dict__", subtype_dict, subtype_setdict,
4045+
{subtype_getset_dict_name, subtype_dict, subtype_setdict,
40434046
PyDoc_STR("dictionary for instance variables")},
4044-
{"__weakref__", subtype_getweakref, NULL,
4047+
{subtype_getset_weakref_name, subtype_getweakref, NULL,
40454048
PyDoc_STR("list of weak references to the object")},
40464049
{0}
40474050
};
40484051

40494052
static PyGetSetDef subtype_getsets_dict_only[] = {
4050-
{"__dict__", subtype_dict, subtype_setdict,
4053+
{subtype_getset_dict_name, subtype_dict, subtype_setdict,
40514054
PyDoc_STR("dictionary for instance variables")},
40524055
{0}
40534056
};
40544057

40554058
static PyGetSetDef subtype_getsets_weakref_only[] = {
4056-
{"__weakref__", subtype_getweakref, NULL,
4059+
{subtype_getset_weakref_name, subtype_getweakref, NULL,
40574060
PyDoc_STR("list of weak references to the object")},
40584061
{0}
40594062
};
@@ -8329,7 +8332,16 @@ type_add_getset(PyTypeObject *type)
83298332

83308333
PyObject *dict = lookup_tp_dict(type);
83318334
for (; gsp->name != NULL; gsp++) {
8332-
PyObject *descr = PyDescr_NewGetSet(type, gsp);
8335+
PyTypeObject *descr_type = type;
8336+
// Hack: dict and weakref descriptors are created for `object`,
8337+
// rather than this specific type.
8338+
// We identify their PyGetSetDef by pointer equality on name.
8339+
if (gsp->name == subtype_getset_dict_name
8340+
|| gsp->name == subtype_getset_weakref_name)
8341+
{
8342+
descr_type = &PyBaseObject_Type;
8343+
}
8344+
PyObject *descr = PyDescr_NewGetSet(descr_type, gsp);
83338345
if (descr == NULL) {
83348346
return -1;
83358347
}

0 commit comments

Comments
 (0)