[C++-sig] Pyste for class with private destructor

Ult Mundane ult at mundane.org
Mon Jun 13 15:53:52 CEST 2005


I think I understand what's going on a bit better now. The source of the 
problem seems to be that Pyste uses the value_holder template as long as 
there are any public constructors (including "artificial" ones created 
by the compiler), regardless of whether there is a public destructor. I 
guess what should happen is that if the destructor is private, Pyste 
should declare the class with no_init, because it will never compile.

It isn't a big deal for a simple class, because (as in the example 
below) you can just declare all the artificial constructors as private. 
But if the class contains data members which can't be constructed, an 
empty copy constructor won't compile.

What do Pyste users do for situations like this where Pyste is getting 
in the way? Just use Boost.Python directly for that class? Insert code 
using module_code()? Patch Pyste?

Thanks,

Ult


Here's some code to make it more concrete:

# --- Ah.hpp ---

#ifndef AH_HPP
#define AH_HPP

#include <string>
#include <vector>

class Hum
{
   public:
     std::string mantra;

   private:
     Hum();
     /* If I add this line, it works fine; Pyste says no_init and
      * value_holder doesn't complain. But if I have a data member
      * which can't be copied, I'm out of luck.
      */
//    Hum(Hum const & rhs) {};
     Hum(char const * mantra);
     ~Hum();

     friend class Ah;
};

class Ah
{
   public:
     Ah();
     ~Ah();

     void  addHum(char const * mantra);

     std::vector<Hum *> humlist;
};

#endif

# --- Ah.pyste ---

Ah = Class("Ah", "Ah.hpp")
Hum = Class("Hum", "Ah.hpp")
set_policy(Ah.addHum, return_internal_reference())

Include("vector")
module_code('''
   class_<std::vector<Hum *> >("vector_HumRef")
       .def("__iter__", iterator<std::vector<Hum *>,
           return_internal_reference<> >())
       ;
''')

# --- _Ah.cpp (produced from Ah.pyste) ---

// Boost Includes 
==============================================================
#include <boost/python.hpp>
#include <boost/cstdint.hpp>

// Includes 
====================================================================
#include <Ah.hpp>
#include <vector>

// Using 
=======================================================================
using namespace boost::python;

// Module 
======================================================================
void Export_pystebox_src_pyste_Ah()
{
     class_< Ah >("Ah", init<  >())
         .def(init< const Ah& >())
         .def_readwrite("humlist", &Ah::humlist)
         .def("addHum", &Ah::addHum, return_internal_reference< 1 >())
     ;

     class_< Hum >("Hum", init< const Hum& >())
         .def_readwrite("mantra", &Hum::mantra)
     ;


   class_<std::vector<Hum *> >("vector_HumRef")
       .def("__iter__", iterator<std::vector<Hum *>,
           return_internal_reference<> >())
       ;
}

# --- Errors compiling _Ah.cpp ---
pystebox/src/pyste/Ah.hpp: In constructor
 
`boost::python::objects::value_holder<Value>::value_holder(PyObject*, A0)
    [with A0 = boost::python::objects::reference_to_value<const Hum&>, 
Value =
    Hum]':
libs/boost-1.32.0/include/boost/python/object/make_holder.hpp:83: 
instantiated from `static void 
boost::python::objects::make_holder<1>::apply<Holder, 
ArgList>::execute(PyObject*, 
boost::mpl::deref<boost::mpl::begin<ArgList>::type>::type) [with Holder 
= boost::python::objects::value_holder<Hum>, ArgList = 
boost::mpl::vector1<const Hum&>]'

# [... a few pages of "instantiated from" lines like that one ...]

linux-i686-pystebox/pystebox/pystebox/_Ah.cpp:22:   instantiated from here
pystebox/src/pyste/Ah.hpp:22: `Hum::~Hum()' is private
libs/boost-1.32.0/include/boost/python/object/value_holder.hpp:133: 
within this
    context



David Abrahams wrote:
> Ult Mundane <ult at mundane.org> writes:
> 
> 
>>Hi there,
>>
>>I'm just learning to use Boost.Python and Pyste, so I thank you for your 
>>patience. I just upgraded Pyste to the current CVS sources (from Boost 
>>1.32).
>>
>>In 1.32, Pyste would not export a copy constructor if the class didn't 
>>declare one, even though the compiler would create an "artificial" copy 
>>constructor. Using the current CVS version, Pyste will export the copy 
>>constructor. This solves the problem I was having with a simple class 
>>that I wanted to be able to copy in Python.
>>
>>However, it uncovered a new issue for me. In the case that the class's 
>>constructors or destructor are private, exporting the class causes an 
>>error in value_holder.hpp when compiling the generated cpp file.
>>
>>My intention is to create a class that is instantiated on the c++ side, 
>>and referenced (but never copied or destroyed) on the Python side. 
>>Perhaps I'm using the wrong approach. Should I be using a shared_ptr, or 
>>wrapping the class?
> 
> 
> Did you read the thread entitled "wrapping a Singleton class" from
> today?  Does following that example help?
> 



More information about the Cplusplus-sig mailing list