[Python-Dev] Issue 10194 - Adding a gc.remap() function

Hrvoje Niksic hrvoje.niksic at avl.com
Tue Oct 26 13:07:02 CEST 2010


On 10/26/2010 07:04 AM, Peter Ingebretson wrote:
> I have a patch that adds a new function to the gc module.  The gc.remap()
> function uses the tp_traverse mechanism to find all references to any keys
> in a provided mapping, and remaps these references in-place to instead point
> to the value corresponding to each key.

What about objects that don't implement tp_traverse because they cannot 
take part in cycles?

Changing immutable objects such as tuples and frozensets doesn't exactly 
sound appealing.

> A potentially controversial aspect of this change is that the signature of the
> visitproc has been modified to take (PyObject **) as an argument instead of
> (PyObject *) so that a visitor can modify fields visited with Py_VISIT.

This sounds like a bad idea -- visitproc is not limited to visiting 
struct members.  Visited objects can be stored in data structures where 
their address cannot be directly obtained.  For example, in C++, you 
could have an std::map with PyObject* keys, and it wouldn't be legal to 
pass addresses of those.  Various C++ bindings also implement 
smart_ptr-style wrappers over PyObject* that handle Python reference 
counting, and those will also have problems with visitproc taking 
PyObject **.

And this is not just some oddball C++ thing.  Many extensions wrap 
arbitrary C objects which can reach Python data through other C objects, 
which expose the PyObject* only through a generic "void 
*get_user_data()"-style accessor.  For such objects to cooperate with 
the GC, they must be able to visit arbitrary PyObject pointers without 
knowing their address.  PyGTK and pygobject are the obvious examples of 
this, but I'm sure there are many others.

If you want to go this route, rather create an extended visit procedure 
(visitchangeproc?) that accepts a function that can change the 
reference.  A convenience function or macro could implement this for the 
common case of struct member or PyObject**.


More information about the Python-Dev mailing list