This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA 00/14] add a smart pointer for PyObject*


>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> I did wonder about shortening the name to "gdbpy_ref".  That's how I end
Pedro> up reading "gdbpy_reference" in my mind after seeing it so many
Pedro> times.  :-)  You already picked a shorter name as header file
Pedro> name -- py-ref.h -- and that's typed way less often.  :-)
Pedro> Anyway, certainly not very important.  Just mentioning in case
Pedro> you had already considered but didn't know what others would think.

I wouldn't mind.  I just erred on the side of verbosity.

Pedro> I wonder whether it'd be desirable to add more methods to 
Pedro> gdbpy_reference, so you'd have code like:

Pedro>   gdbpy_reference sort_func = module.GetAttrString ("execute_frame_filters");

Pedro> instead of:

Pedro>   gdbpy_reference sort_func (PyObject_GetAttrString (module.get (),
Pedro> 						     "execute_frame_filters"));

Pedro> etc.

This particular one I chose not to do, on the theory that assignment
from another gdbpy_reference does a Py_INCREF.  That is, this addition
would mean that one assignment operator claims ownership of an existing
reference, while another assignment operator would create a new
reference.

So, to avoid the confusion I made the PyObject* constructor explicit,
and I required the use of .reset(...) to claim ownership.

I'm open to basically any spelling of any of this.  I just thought this
approach was most likely to avoid bugs.

Pedro> And maybe add some C++ classes that inherit from gdbpy_reference for
Pedro> specific Python types (e.g python tuple or list), which would provide
Pedro> methods that would only make sense for those types.

Pedro> Did you consider things like these?  Or maybe you did but thought
Pedro> they'd obfuscate?

I did consider subclassing and also adding some convenience methods.
Other similar ideas came to mind as well, like providing wrapper
functions for all the Python APIs to try to ensure ownership sanity --
basically implementing David Malcolm's reference-checker work as a bunch
of templates or so.

I do think this would help; while the current approach definitely
improves the situation, it also leaves some bug-prone behavior.  For
example, PyTuple_SET_ITEM steals a reference, so calls end up looking
like:

  PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());

... using .get() rather than .release() would cause a bug (probably a
crash).

If we had a wrapper we could make calls look like:

  mumble_tuple_set_item (py_arg_tuple, 0, py_value_obj);

... with the first argument being unwrapped using .get() and the third
with an implicit incref (or require std::move there).  (An equivalent
using member functions could also be done.)


Anyway, I didn't do this just because it requires more thought; and
there were a lot of patches already; and I figured that it could be done
later if desirable.

Pedro> Also, somewhat related, I briefly looked at making our custom Python
Pedro> types C++ classes before, so they could themselves hold other
Pedro> C++ classes, std::string, etc., though I didn't find how to
Pedro> coerce Python to use operator new with PyTypeObject types.
Pedro> There must be some way though.

I haven't looked at all into prior art for C++ Python APIs; which might
be worth doing.  One "easy" way to do it would be to store a pointer to
a C++ object which would be "delete"d in the Python object-destruction
callback (gross due to extra allocation of course).  Another possible
way would be placement new.  But maybe there's something even nicer.

Tom


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]