[C++-sig] Getting object for PyObject (reference counting)

2009-02-27 Thread Murray Cumming
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)

2009-02-27 Thread Ralf W. Grosse-Kunstleve

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)

2009-02-27 Thread Murray Cumming
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

2009-02-27 Thread Bruno Lalande
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)

2009-02-27 Thread Alex Mohr

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)

2009-02-27 Thread AFoglia

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)

2009-02-27 Thread Murray Cumming
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)

2009-02-27 Thread AFoglia

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)

2009-02-27 Thread Alex Mohr

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