summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/object.h10
-rw-r--r--Objects/classobject.c88
-rw-r--r--Objects/dictobject.c35
-rw-r--r--Objects/funcobject.c40
-rw-r--r--Objects/listobject.c29
-rw-r--r--Objects/tupleobject.c19
6 files changed, 218 insertions, 3 deletions
diff --git a/Include/object.h b/Include/object.h
index f6ceba5..e18e0e8 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -145,6 +145,8 @@ typedef int (*getwritebufferproc) Py_PROTO((PyObject *, int, void **));
typedef int (*getsegcountproc) Py_PROTO((PyObject *, int *));
typedef int (*getcharbufferproc) Py_PROTO((PyObject *, int, const char **));
typedef int (*objobjproc) Py_PROTO((PyObject *, PyObject *));
+typedef int (*visitproc) Py_PROTO((PyObject *, void *));
+typedef int (*traverseproc) Py_PROTO((PyObject *, visitproc, void *));
typedef struct {
binaryfunc nb_add;
@@ -243,9 +245,13 @@ typedef struct _typeobject {
char *tp_doc; /* Documentation string */
+ /* call function for all accessible objects */
+ traverseproc tp_traverse;
+
+ /* delete references to contained objects */
+ inquiry tp_clear;
+
/* More spares */
- long tp_xxx5;
- long tp_xxx6;
long tp_xxx7;
long tp_xxx8;
diff --git a/Objects/classobject.c b/Objects/classobject.c
index bd95bc0..18908f3 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -387,6 +387,43 @@ class_str(op)
return res;
}
+static int
+class_traverse(PyClassObject *o, visitproc visit, void *arg)
+{
+ int err;
+ if (o->cl_bases) {
+ err = visit(o->cl_bases, arg);
+ if (err)
+ return err;
+ }
+ if (o->cl_dict) {
+ err = visit(o->cl_dict, arg);
+ if (err)
+ return err;
+ }
+ if (o->cl_name) {
+ err = visit(o->cl_name, arg);
+ if (err)
+ return err;
+ }
+ if (o->cl_getattr) {
+ err = visit(o->cl_getattr, arg);
+ if (err)
+ return err;
+ }
+ if (o->cl_setattr) {
+ err = visit(o->cl_setattr, arg);
+ if (err)
+ return err;
+ }
+ if (o->cl_delattr) {
+ err = visit(o->cl_delattr, arg);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
PyTypeObject PyClass_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
@@ -407,6 +444,10 @@ PyTypeObject PyClass_Type = {
(reprfunc)class_str, /*tp_str*/
(getattrofunc)class_getattr, /*tp_getattro*/
(setattrofunc)class_setattr, /*tp_setattro*/
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /* tp_doc */
+ (traverseproc)class_traverse, /* tp_traverse */
};
int
@@ -849,6 +890,23 @@ instance_hash(inst)
return outcome;
}
+static int
+instance_traverse(PyInstanceObject *o, visitproc visit, void *arg)
+{
+ int err;
+ if (o->in_class) {
+ err = visit((PyObject *)(o->in_class), arg);
+ if (err)
+ return err;
+ }
+ if (o->in_dict) {
+ err = visit(o->in_dict, arg);
+ if (err)
+ return err;
+ }
+ return 1;
+}
+
static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr;
static int
@@ -1472,7 +1530,9 @@ PyTypeObject PyInstance_Type = {
(getattrofunc)instance_getattr, /*tp_getattro*/
(setattrofunc)instance_setattr, /*tp_setattro*/
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /*tp_flags */
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /* tp_doc */
+ (traverseproc)instance_traverse, /* tp_traverse */
};
@@ -1662,6 +1722,28 @@ instancemethod_hash(a)
return x ^ y;
}
+static int
+instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)
+{
+ int err;
+ if (im->im_func) {
+ err = visit(im->im_func, arg);
+ if (err)
+ return err;
+ }
+ if (im->im_self) {
+ err = visit(im->im_self, arg);
+ if (err)
+ return err;
+ }
+ if (im->im_class) {
+ err = visit(im->im_class, arg);
+ if (err)
+ return err;
+ }
+ return 1;
+}
+
PyTypeObject PyMethod_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
@@ -1682,6 +1764,10 @@ PyTypeObject PyMethod_Type = {
0, /*tp_str*/
(getattrofunc)instancemethod_getattr, /*tp_getattro*/
0, /*tp_setattro*/
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /* tp_doc */
+ (traverseproc)instancemethod_traverse, /* tp_traverse */
};
/* Clear out the free list */
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 6e7fa3d..2d33b92 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1038,6 +1038,31 @@ dict_clear(mp, args)
return Py_None;
}
+static int
+dict_traverse(PyObject *op, visitproc visit, void *arg)
+{
+ int i = 0, err;
+ PyObject *pk;
+ PyObject *pv;
+
+ while (PyDict_Next(op, &i, &pk, &pv)) {
+ err = visit(pk, arg);
+ if (err)
+ return err;
+ err = visit(pv, arg);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int
+dict_tp_clear(PyObject *op)
+{
+ PyDict_Clear(op);
+ return 0;
+}
+
static PyMethodDef mapp_methods[] = {
{"has_key", (PyCFunction)dict_has_key, METH_VARARGS},
{"keys", (PyCFunction)dict_keys},
@@ -1073,6 +1098,16 @@ PyTypeObject PyDict_Type = {
0, /*tp_as_number*/
0, /*tp_as_sequence*/
&dict_as_mapping, /*tp_as_mapping*/
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /* tp_doc */
+ (traverseproc)dict_traverse, /* tp_traverse */
+ (inquiry)dict_tp_clear, /* tp_clear */
};
/* For backward compatibility with old dictionary interface */
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index a5e15cc..142c7e7 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -239,6 +239,38 @@ func_hash(f)
return h;
}
+static int
+func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
+{
+ int err;
+ if (f->func_code) {
+ err = visit(f->func_code, arg);
+ if (err)
+ return err;
+ }
+ if (f->func_globals) {
+ err = visit(f->func_globals, arg);
+ if (err)
+ return err;
+ }
+ if (f->func_defaults) {
+ err = visit(f->func_defaults, arg);
+ if (err)
+ return err;
+ }
+ if (f->func_doc) {
+ err = visit(f->func_doc, arg);
+ if (err)
+ return err;
+ }
+ if (f->func_name) {
+ err = visit(f->func_name, arg);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
PyTypeObject PyFunction_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
@@ -255,4 +287,12 @@ PyTypeObject PyFunction_Type = {
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
(hashfunc)func_hash, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /* tp_doc */
+ (traverseproc)func_traverse, /* tp_traverse */
};
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 163ba2a..65dfb18 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -1418,6 +1418,30 @@ listremove(self, args)
return NULL;
}
+static int
+list_traverse(PyListObject *o, visitproc visit, void *arg)
+{
+ int i, err;
+ PyObject *x;
+
+ for (i = o->ob_size; --i >= 0; ) {
+ x = o->ob_item[i];
+ if (x != NULL) {
+ err = visit(x, arg);
+ if (err)
+ return err;
+ }
+ }
+ return 0;
+}
+
+static int
+list_clear(PyListObject *lp)
+{
+ (void) PyList_SetSlice((PyObject *)lp, 0, lp->ob_size, 0);
+ return 0;
+}
+
static char append_doc[] =
"L.append(object) -- append object to end";
static char extend_doc[] =
@@ -1491,6 +1515,9 @@ PyTypeObject PyList_Type = {
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /* tp_doc */
+ (traverseproc)list_traverse, /* tp_traverse */
+ (inquiry)list_clear, /* tp_clear */
};
@@ -1567,5 +1594,7 @@ static PyTypeObject immutable_list_type = {
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /* tp_doc */
+ (traverseproc)list_traverse, /* tp_traverse */
};
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index f89fa36..bbb56b1 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -420,6 +420,23 @@ tuplerepeat(a, n)
return (PyObject *) np;
}
+static int
+tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
+{
+ int i, err;
+ PyObject *x;
+
+ for (i = o->ob_size; --i >= 0; ) {
+ x = o->ob_item[i];
+ if (x != NULL) {
+ err = visit(x, arg);
+ if (err)
+ return err;
+ }
+ }
+ return 0;
+}
+
static PySequenceMethods tuple_as_sequence = {
(inquiry)tuplelength, /*sq_length*/
(binaryfunc)tupleconcat, /*sq_concat*/
@@ -453,6 +470,8 @@ PyTypeObject PyTuple_Type = {
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ (traverseproc)tupletraverse, /* tp_traverse */
};
/* The following function breaks the notion that tuples are immutable: