on Wed Oct 29 2008, Hans Meine <hans_meine-AT-gmx.net> wrote: > On Mittwoch 29 Oktober 2008, Dan Eloff wrote: >> When creating an object from a PyObject *, how do you distinguish >> between a PyObject pointer that is a new reference (must not be >> increfed, but must be decrefed) versus a PyObject * that is a borrowed >> reference? (should be increfed and decrefed) >> >> A very simple question for which there is no documented answer, >> conflicting answers in the archives of this mailing list, and hours of >> googling has turned up conflicting information. >> >> The best I could find was object(borrowed(ptr)) for new references and >> object(handle<>(ptr)) for borrowed pointers. I'm not sure if that is >> accurate, but if so that deserves a nomination for a terrible >> interface award. >> >> Please someone put me out of my misery. What's the interface for this? > > IIRC I have complained about this in the past, too. I think it was actually > discussed in the BPL tutorial (and only there AFAIK), but was eventually > deleted (probably because it was not the best place for that kind of > information). > > Actually, I have the same question as you, and the same impression that the > above two ways are the "correct" ways. Err, no - you did swap the two, > right?
Guidelines: - handle, essentially a smart pointer. Use when necessary. * a handle<> can be NULL, and maintains a reference count on the object it points to * handle<> y(null_ok(x)) allows y to become NULL * handle<> y(x), where x is not the result of null_ok, never results in a NULL y. An exception will be thrown if x is NULL * handle<> y(borrowed(x)) presumes that *x is borrowed and thus increments its reference count. * handle<> y(x), where x is not the result of borrowed, presumes that someone has already incremented the reference count on *x for us. * you can combine borrowed and null_ok in any order, so handle<> y(borrowed(null_ok(x))) and handle<> y(null_ok(borrowed(x))) are equivalent. - object, a higher-level notion. Use wherever possible. * an object can't be constructed from a raw PyObject* because there's no information in that type about whether the refcount has been incremented for this additional reference * an object can only be constructed from a handle<>. Other interfaces are not for public consumption and thus not documented. Use at your own peril. * an instance of object always "points to" something (maybe None). If the constructor argument (handle) is NULL, an exception will be thrown. > Looking back at my code, I think I used boost::python::detail::new_reference. > > And for turning a Foo* pointer to an object of an exported class Foo, I used > something as ugly as: > bp::detail::new_reference(typename manage_new_object::apply<T *>::type()(p) > > AFAICS, I repeated my questions a total of three times (in the "How about > class_<...>.enable_copy() ?" thead), but nobody answered so far. The above should be a complete guide. Any questions? -- Dave Abrahams BoostPro Computing http://www.boostpro.com _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig