mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
Add implementations of Py_Repr{Enter,Leave}.
(Jeremy will hardly recognize his patch :-)
This commit is contained in:
parent
26d4ac30be
commit
8661036cb8
1 changed files with 64 additions and 0 deletions
|
@ -790,3 +790,67 @@ PyMem_Free(p)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue