[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.40,2.41
Guido van Rossum
gvanrossum@users.sourceforge.net
Fri, 17 Aug 2001 13:32:38 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv21167
Modified Files:
typeobject.c
Log Message:
Weak reference support, closing SF bug #451773.
Classes that don't use __slots__ have a __weakref__ member added in
the same way as __dict__ is added (i.e. only if the base didn't
already have one). Classes using __slots__ can enable weak
referenceability by adding '__weakref__' to the __slots__ list.
Renamed the __weaklistoffset__ class member to __weakrefoffset__ --
it's not always a list, it seems. (Is tp_weaklistoffset a historical
misnomer, or do I misunderstand this?)
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.40
retrieving revision 2.41
diff -C2 -d -r2.40 -r2.41
*** typeobject.c 2001/08/17 16:47:50 2.40
--- typeobject.c 2001/08/17 20:32:36 2.41
***************
*** 10,14 ****
{"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY},
{"__doc__", T_STRING, offsetof(PyTypeObject, tp_doc), READONLY},
! {"__weaklistoffset__", T_LONG,
offsetof(PyTypeObject, tp_weaklistoffset), READONLY},
{"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY},
--- 10,14 ----
{"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY},
{"__doc__", T_STRING, offsetof(PyTypeObject, tp_doc), READONLY},
! {"__weakrefoffset__", T_LONG,
offsetof(PyTypeObject, tp_weaklistoffset), READONLY},
{"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY},
***************
*** 202,205 ****
--- 202,206 ----
{
int dictoffset = self->ob_type->tp_dictoffset;
+ int weaklistoffset = self->ob_type->tp_weaklistoffset;
PyTypeObject *type, *base;
destructor f;
***************
*** 225,228 ****
--- 226,233 ----
}
+ /* If we added weaklist, we clear it */
+ if (weaklistoffset && !base->tp_weaklistoffset)
+ PyObject_ClearWeakRefs(self);
+
/* Finalize GC if the base doesn't do GC and we do */
if (PyType_IS_GC(type) && !PyType_IS_GC(base))
***************
*** 456,463 ****
extra_ivars(PyTypeObject *type, PyTypeObject *base)
{
! int t_size = PyType_BASICSIZE(type);
! int b_size = PyType_BASICSIZE(base);
! assert(t_size >= b_size); /* type smaller than base! */
if (type->tp_itemsize || base->tp_itemsize) {
/* If itemsize is involved, stricter rules */
--- 461,468 ----
extra_ivars(PyTypeObject *type, PyTypeObject *base)
{
! size_t t_size = PyType_BASICSIZE(type);
! size_t b_size = PyType_BASICSIZE(base);
! assert(t_size >= b_size); /* Else type smaller than base! */
if (type->tp_itemsize || base->tp_itemsize) {
/* If itemsize is involved, stricter rules */
***************
*** 465,475 ****
type->tp_itemsize != base->tp_itemsize;
}
! if (t_size == b_size)
! return 0;
! if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
! type->tp_dictoffset == b_size &&
! (size_t)t_size == b_size + sizeof(PyObject *))
! return 0; /* "Forgive" adding a __dict__ only */
! return 1;
}
--- 470,481 ----
type->tp_itemsize != base->tp_itemsize;
}
! if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 &&
! type->tp_weaklistoffset + sizeof(PyObject *) == t_size)
! t_size -= sizeof(PyObject *);
! if (type->tp_dictoffset && base->tp_dictoffset == 0 &&
! type->tp_dictoffset + sizeof(PyObject *) == t_size)
! t_size -= sizeof(PyObject *);
!
! return t_size != b_size;
}
***************
*** 501,505 ****
etype *et;
struct memberlist *mp;
! int i, nbases, nslots, slotoffset, dynamic;
/* Special case: type(x) should return x->ob_type */
--- 507,511 ----
etype *et;
struct memberlist *mp;
! int i, nbases, nslots, slotoffset, dynamic, add_dict, add_weak;
/* Special case: type(x) should return x->ob_type */
***************
*** 614,617 ****
--- 620,625 ----
slots = PyDict_GetItemString(dict, "__slots__");
nslots = 0;
+ add_dict = 0;
+ add_weak = 0;
if (slots != NULL) {
/* Make it into a tuple */
***************
*** 630,639 ****
return NULL;
}
}
}
if (slots == NULL && base->tp_dictoffset == 0 &&
(base->tp_setattro == PyObject_GenericSetAttr ||
! base->tp_setattro == NULL))
! nslots = 1;
/* XXX From here until type is safely allocated,
--- 638,654 ----
return NULL;
}
+ /* XXX Check against null bytes in name */
}
}
if (slots == NULL && base->tp_dictoffset == 0 &&
(base->tp_setattro == PyObject_GenericSetAttr ||
! base->tp_setattro == NULL)) {
! nslots++;
! add_dict++;
! }
! if (slots == NULL && base->tp_weaklistoffset == 0) {
! nslots++;
! add_weak++;
! }
/* XXX From here until type is safely allocated,
***************
*** 717,730 ****
mp->type = T_OBJECT;
mp->offset = slotoffset;
slotoffset += sizeof(PyObject *);
}
}
! else if (nslots) {
! type->tp_dictoffset = slotoffset;
! mp->name = "__dict__";
! mp->type = T_OBJECT;
! mp->offset = slotoffset;
! mp->readonly = 1;
! slotoffset += sizeof(PyObject *);
}
type->tp_basicsize = slotoffset;
--- 732,760 ----
mp->type = T_OBJECT;
mp->offset = slotoffset;
+ if (base->tp_weaklistoffset == 0 &&
+ strcmp(mp->name, "__weakref__") == 0)
+ type->tp_weaklistoffset = slotoffset;
slotoffset += sizeof(PyObject *);
}
}
! else {
! if (add_dict) {
! type->tp_dictoffset = slotoffset;
! mp->name = "__dict__";
! mp->type = T_OBJECT;
! mp->offset = slotoffset;
! mp->readonly = 1;
! mp++;
! slotoffset += sizeof(PyObject *);
! }
! if (add_weak) {
! type->tp_weaklistoffset = slotoffset;
! mp->name = "__weakref__";
! mp->type = T_OBJECT;
! mp->offset = slotoffset;
! mp->readonly = 1;
! mp++;
! slotoffset += sizeof(PyObject *);
! }
}
type->tp_basicsize = slotoffset;