[C++-sig] Getting object for PyObject (reference counting)
I can't find any definitive documentation that tells me how I should get a boost::python::object to wrap an existing PyObject*. I guess that there's a way to do it that uses an existing reference, and a way that takes an extra reference. -- [email protected] www.murrayc.com www.openismus.com ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting object for PyObject (reference counting)
The trick is to use boost::python::handle: http://www.boost.org/doc/libs/1_38_0/libs/python/doc/v2/handle.html For example: object python_file((handle<>(borrowed(obj_ptr; - Original Message From: Murray Cumming To: [email protected] Sent: Friday, February 27, 2009 1:33:10 AM Subject: [C++-sig] Getting object for PyObject (reference counting) I can't find any definitive documentation that tells me how I should get a boost::python::object to wrap an existing PyObject*. I guess that there's a way to do it that uses an existing reference, and a way that takes an extra reference. -- [email protected] www.murrayc.com www.openismus.com ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting object for PyObject (reference counting)
On Fri, 2009-02-27 at 07:35 -0800, Ralf W. Grosse-Kunstleve wrote: > The trick is to use boost::python::handle: > > http://www.boost.org/doc/libs/1_38_0/libs/python/doc/v2/handle.html > > For example: > > object python_file((handle<>(borrowed(obj_ptr; Thanks, but like much of the documentation, I find that page very unclear. Is there anything that states more obviously what should be done in the two cases I mentioned. > I can't find any definitive documentation that tells me how I should get > a boost::python::object to wrap an existing PyObject*. I guess that > there's a way to do it that uses an existing reference, and a way that > takes an extra reference. > -- Murray Cumming [email protected] www.murrayc.com www.openismus.com ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] [c++-sig] Making a Python tuple from a Boost.Fusion sequence
Hello,
The topic below was opened in the Boost development mailing list,
where it's been pointed out to me that it fits better here.
You can also read the thread archive:
http://thread.gmane.org/gmane.comp.lib.boost.devel/186573
Regards
Bruno
-- Forwarded message --
Hello,
I have written a little function that converts any Boost.Fusion
sequence into a Python tuple (boost::python::tuple). If a sub-sequence
is nested in the sequence, the result will also be a nested tuple (for
instance, boost::make_tuple(0, std::make_pair(1, 2), 3) will give (0,
(1, 2), 3) in Python).
The source code is attached to this mail.
The principle is that any sequence previously adapted to Boost.Fusion
will become a tuple in Python. So, by including the right
boost/fusion/adapted/xxx header, one can convert a pair, a tuple, a
boost::array, and obviously any of the sequences provided by
Boost.Fusion. For example:
#include
#include
#include
#include
#include "make_tuple_from_fusion_sequence.hpp"
using namespace boost::python;
tuple from_sequence()
{
return make_tuple_from_fusion(
boost::fusion::make_vector(
1,
std::make_pair("first", "second"),
2,
boost::make_tuple('a', 'b', 'c'),
3
)
);
}
BOOST_PYTHON_MODULE(mymodule)
{
def("from_sequence", &from_sequence);
}
In Python we get:
>>> import mymodule
>>> mymodule.from_sequence()
(1, ('first', 'second'), 2, ('a', 'b', 'c'), 3)
Is there any interest in adding this function into Boost.Python? If
yes, I can write the doc and tests, clean the source and maybe improve
the implementation (for example, I feel that I could avoid the use of
m_iteration with a better use of Boost.Fusion...).
Regards
Bruno
#ifndef BOOST_PYTHON_MAKE_TUPLE_FROM_FUSION_H_
#define BOOST_PYTHON_MAKE_TUPLE_FROM_FUSION_H_
#include
#include
#include
#include
#include
namespace boost {
namespace python {
class tuple_maker
{
public:
tuple_maker(tuple& t):
m_tuple(t),
m_iteration(0)
{}
template
typename disable_if, void>::type
operator() (const T& element) const
{ add_element(element); }
template
typename enable_if, void>::type
operator() (const Sequence& s) const
{ add_element(make_tuple_from_fusion(s)); }
private:
template
void add_element(const T& element) const
{
PyTuple_SET_ITEM(
m_tuple.ptr(),
m_iteration++,
incref(object(element).ptr())
);
}
tuple& m_tuple;
mutable int m_iteration;
};
template
tuple make_tuple_from_fusion(const Sequence& s)
{
tuple result((detail::new_reference)::PyTuple_New(fusion::size(s)));
fusion::for_each(s, tuple_maker(result));
return result;
}
} // namespace python
} // namespace boost
#endif
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting object for PyObject (reference counting)
Murray Cumming wrote: I can't find any definitive documentation that tells me how I should get a boost::python::object to wrap an existing PyObject*. I guess that there's a way to do it that uses an existing reference, and a way that takes an extra reference. You can construct a boost::python::object with a boost::python::handle<>. boost::python::handle<> is sort of a "smart" PyObject *. It manages the python object reference count automatically. When you create a boost::python::handle<> you can tell it whether to bump the reference count or not. Given a PyObject *p: // Use with a "new reference" -- *doesn't* bump ref count. handle<>(p); // Use with a "borrowed reference" -- *does* bump ref count. handle<>(borrowed(p)); Alex ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting object for PyObject (reference counting)
Murray Cumming wrote: On Fri, 2009-02-27 at 07:35 -0800, Ralf W. Grosse-Kunstleve wrote: The trick is to use boost::python::handle: http://www.boost.org/doc/libs/1_38_0/libs/python/doc/v2/handle.html For example: object python_file((handle<>(borrowed(obj_ptr; Thanks, but like much of the documentation, I find that page very unclear. Is there anything that states more obviously what should be done in the two cases I mentioned. The best documentation I could find was this page on the Python wiki, taken from a email to this list: http://wiki.python.org/moin/boost.python/handle The only error is that references to "null_ok" should be "allow_null". At least that's the way I got it to work. -- Anthony Foglia Princeton Consultants (609) 987-8787 x233 ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting object for PyObject (reference counting)
On Fri, 2009-02-27 at 08:34 -0800, Alex Mohr wrote: > Murray Cumming wrote: > > I can't find any definitive documentation that tells me how I should get > > a boost::python::object to wrap an existing PyObject*. I guess that > > there's a way to do it that uses an existing reference, and a way that > > takes an extra reference. > > You can construct a boost::python::object with a > boost::python::handle<>. boost::python::handle<> is sort of a "smart" > PyObject *. It manages the python object reference count automatically. Oh, I assumed that boost::python::object did this already. If not, is there any reason not to use boost::python::handle everywhere instead of a boost::python::object? One of my main reasons for using boost::python instead of the C API is to avoid worrying so much about the reference counting. For instance, I don't want to explicitly increment the ref when returning a PyObject, or remember whether I should take a ref when given a PyObject from various functions. > When you create a boost::python::handle<> you can tell it whether to > bump the reference count or not. Given a PyObject *p: > > // Use with a "new reference" -- *doesn't* bump ref count. > handle<>(p); > > // Use with a "borrowed reference" -- *does* bump ref count. > handle<>(borrowed(p)); > > Alex > ___ > Cplusplus-sig mailing list > [email protected] > http://mail.python.org/mailman/listinfo/cplusplus-sig -- Murray Cumming [email protected] www.murrayc.com www.openismus.com ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting object for PyObject (reference counting)
Murray Cumming wrote: On Fri, 2009-02-27 at 08:34 -0800, Alex Mohr wrote: Murray Cumming wrote: I can't find any definitive documentation that tells me how I should get a boost::python::object to wrap an existing PyObject*. I guess that there's a way to do it that uses an existing reference, and a way that takes an extra reference. You can construct a boost::python::object with a boost::python::handle<>. boost::python::handle<> is sort of a "smart" PyObject *. It manages the python object reference count automatically. Oh, I assumed that boost::python::object did this already. If not, is there any reason not to use boost::python::handle everywhere instead of a boost::python::object? One of my main reasons for using boost::python instead of the C API is to avoid worrying so much about the reference counting. For instance, I don't want to explicitly increment the ref when returning a PyObject, or remember whether I should take a ref when given a PyObject from various functions. I believe, but could be wrong, that boost::python::objects must be made from handles. If not that's not a requirement, it's at least a strong suggestion. That way, the underlying handle in the object will handle the reference counting for you. The way I understand it, the handle takes care of the reference counting, and the object is a wrapper to make it easier to interact with the pointer to PyObject in a more OO-like manner. Also, I'm not sure you can make a boost::python::handle. The instance the handle points to should be laid out like a PyObject. (Remember, the underlying Python code is C-based, so pointer layout is required to start the same to approximate inheritance.) I don't think boost::python::object can make that guarantee. -- Anthony Foglia Princeton Consultants (609) 987-8787 x233 ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting object for PyObject (reference counting)
Oh, I assumed that boost::python::object did this already.
It does. Think of bp::handle<> as a low-level, bare-bones, smart
PyObject*. Think of bp::object as that, *plus* all the fancy c++ API
that maps to python API (like obj.attr("foo"), []-operator, ()-operator,
etc).
I believe bp::object holds a handle<> internally.
If not, is there any reason not to use
boost::python::handle everywhere instead of a
boost::python::object?
Don't do that. You can't do that. It won't compile. Use bp::object
everywhere unless you're convinced you have a good reason to do
otherwise. If you have a PyObject *p and you want a bp::object,
construct it via:
object(handle<>(p)) // when p's a new reference
object(handle<>(borrowed(p))) // when p's a borrowed reference
One of my main reasons for using boost::python instead of the C API is
to avoid worrying so much about the reference counting. For instance, I
don't want to explicitly increment the ref when returning a PyObject, or
remember whether I should take a ref when given a PyObject from various
functions.
Yup. Just use bp::object everywhere. I recommend you read through the
reference manual:
http://www.boost.org/doc/libs/1_38_0/libs/python/doc/v2/object.html
http://www.boost.org/doc/libs/1_38_0/libs/python/doc/v2/handle.html
Also look at the tutorials and examples and tests in the boost.python
distribution.
Alex
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
