]> granicus.if.org Git - python/commitdiff
Add implementations of Py_Repr{Enter,Leave}.
authorGuido van Rossum <guido@python.org>
Fri, 10 Apr 1998 22:32:46 +0000 (22:32 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 10 Apr 1998 22:32:46 +0000 (22:32 +0000)
(Jeremy will hardly recognize his patch :-)

Objects/object.c

index aa73740c99fe007e3d79431b6601e71c5dd3e41a..f84e64fa2c3e30d66c416665a460f573e22b65be 100644 (file)
@@ -790,3 +790,67 @@ PyMem_Free(p)
 {
        free(p);
 }
+
+
+/* These methods are used to control infinite recursion in repr, str, print,
+   etc.  Container objects that may recursively contain themselves,
+   e.g. builtin dictionaries and lists, should used Py_ReprEnter() and
+   Py_ReprLeave() to avoid infinite recursion.
+
+   Py_ReprEnter() returns 0 the first time it is called for a particular
+   object and 1 every time thereafter.  It returns -1 if an exception
+   occurred.  Py_ReprLeave() has no return value.
+
+   See dictobject.c and listobject.c for examples of use.
+*/
+
+#define KEY "Py_Repr"
+
+int
+Py_ReprEnter(obj)
+       PyObject *obj;
+{
+       PyObject *dict;
+       PyObject *list;
+       int i;
+
+       dict = PyThreadState_GetDict();
+       if (dict == NULL)
+               return -1;
+       list = PyDict_GetItemString(dict, KEY);
+       if (list == NULL) {
+               list = PyList_New(0);
+               if (list == NULL)
+                       return -1;
+               if (PyDict_SetItemString(dict, KEY, list) < 0)
+                       return -1;
+               Py_DECREF(list);
+       }
+       i = PyList_GET_SIZE(list);
+       while (--i >= 0) {
+               if (PyList_GET_ITEM(list, i) == obj)
+                       return 1;
+       }
+       PyList_Append(list, obj);
+       return 0;
+}
+
+void
+Py_ReprLeave(obj)
+       PyObject *obj;
+{
+       PyObject *dict;
+       PyObject *list;
+       int i;
+
+       dict = PyThreadState_GetDict();
+       list = PyDict_GetItemString(dict, KEY);
+       i = PyList_GET_SIZE(list);
+       /* Count backwards because we always expect obj to be list[-1] */
+       while (--i >= 0) {
+               if (PyList_GET_ITEM(list, i) == obj) {
+                       PyList_SetSlice(list, i, i + 1, NULL);
+                       break;
+               }
+       }
+}