Hi, I’m hacking through CPython 3.12. I’m calling PyObject_GetIter()
within a loop to see whether each PyObject is potentially, iterable. If so, get its tp_iter
and iterate it, psudo code like this:
for (;;) // some conditions
{
PyObject *each_op = obtain_from_some_source();
PyObject *iterable = PyObject_GetIter(each_op);
if (!iterable)
{
return;
}
PyObject *inner_op;
while ((inner_op = PyIter_Next(iterable)))
{
// do some logic
}
...
}
Also providing the code snippet of PyObject_GetIter()
implementation:
PyObject *PyObject_GetIter(PyObject *o)
{
PyTypeObject *t = Py_TYPE(o);
getiterfunc f;
f = t->tp_iter;
if (f == NULL)
{
if (PySequence_Check(o))
return PySeqIter_New(o);
return type_error("'%.200s' object is not iterable", o);
}
else
{
PyObject *res = (*f)(o);
if (res != NULL && !PyIter_Check(res))
{
PyErr_Format(PyExc_TypeError,
"iter() returned non-iterator "
"of type '%.100s'",
Py_TYPE(res)->tp_name);
Py_SETREF(res, NULL);
}
return res;
}
}
However, my call segfaults in f = t->tp_iter;
, GDB shows:
(gdb) p o
$1 = (PyObject *) 0x7ffff772bac0
(gdb) p t->tp_iter
Cannot access memory at address 0xd7
(gdb) p t
$2 = (PyTypeObject *) 0xffffffffffffffff
(gdb)
It seems the PyObject o
is a valid object (I guess?), but it does not have tp_iter
field. And I don’t know what object it is since I cannot call PyObject_Print()
or any other.
Is that supposed to happen, or any ways to debug? Thanks for any replying.