[Python-Dev] PySet_Next (Was: PySet API)

"Martin v. Löwis" martin at v.loewis.de
Sun Mar 26 19:59:26 CEST 2006

Raymond Hettinger wrote:
> The difference is that the PySet_Next returns pointers to the table keys and 
> that the mutation occurs AFTER the call to PySet_Next, leaving pointers to 
> invalid addresses.  IOW, the function cannot detect the mutation.

I'm coming late to the discussion: where did anybody ever suggest that
PySet_Next should return a pointer into the set? Looking over the entire
discussion, I could not find any mentioning of a specific API.

If it is similar to PyDict_Next, it will have PyObject** /input/
variables, which are really meant as PyObject* /output/ variables.
But yes, PyDict_Next returns a borrowed reference, so if the dictionary
mutates between calls, your borrowed reference might become stale.

> PyIter_Next on the other hand returns an object (not a pointer to an
> object such as those in the hash table).

PyIter_Next behaves identical wrt. to result types to PyDict_Next.
The difference is that PyIter_Next always returns a new reference
(or NULL in case of an exception).

For the caller, a clear usage strategy follows from this: either discard
the references before making a potentially-mutating call, or Py_INCREF
the set element before making that mutating call.

Of course, *after* you made the mutating call, your iteration position
might be bogus, as the set might have been reorganized. If the position
is represented as a Py_ssize_t (as it is for PyDict_Next), the only
consequence of continuing the iteration is that you might see elements
twice or not at all - you cannot cause a crash with that.


More information about the Python-Dev mailing list