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.

Regards,
Martin
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to