|
Boost Users : |
Subject: [Boost-users] Boost.Python shared_ptr bug?
From: Christoff Kok (christoff.kok_at_[hidden])
Date: 2014-11-10 08:21:42
Hi,
I found an issue when accessing a shared_ptr C++ object in Python using
Boost.Python.
When I try to access an attribute of the shared_ptr object read from an C++
object, I get an error telling me that the attribute does not exist.
When I use raw pointers instead of shared_ptr, then there is no issue.
Also, when using raw pointers, accessing an item in a list of base class
objects returns the object in as the derived most class. This is wanted.
When I use shared_ptrs however, the derived most object is of the base
class type. This is not wanted.
I am sure the Boost.Python developers should be aware of these two issues
by now. If so, is there any plans to fix this? If so, when?
Below is a test showing this issue:
*Raw pointers:*
#include<memory>
#include<vector>
struct Vehicle{
virtual ~Vehicle(){}
int testAttribute;
};
struct Boat: public Vehicle {
virtual ~Boat(){}
int testBoatAttribute;
};
struct Garage {
std::vector<Vehicle*>& vehicleList() { return m_VehicleList; }
std::vector<Vehicle*> m_VehicleList;
};
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
BOOST_PYTHON_MODULE(garage_ext) {
using namespace boost::python;
class_<Garage>("Garage")
.def("vehicleList", &Garage::vehicleList,
return_internal_reference<1>());
class_<Vehicle,Vehicle*,boost::noncopyable>("Vehicle", no_init)
.def_readwrite("testAttribute", &Vehicle::testAttribute);
class_<Boat,Boat*,bases<Vehicle>>("Boat")
.def_readwrite("testBoatAttribute", &Boat::testBoatAttribute);
implicitly_convertible<Boat*, Vehicle*>();
class_<std::vector<Vehicle*> >("stl_vector_Vehicle_ptr")
.def(vector_indexing_suite<std::vector<Vehicle*>>());
}
*Shared pointers:*
#include<memory>
#include<vector>
#include <boost/shared_ptr.hpp>
struct Vehicle{
virtual ~Vehicle(){}
friend bool operator==(const Vehicle& lhs, const Vehicle& rhs) { return
true; }
int testAttribute;
};
struct Boat: public Vehicle {
virtual ~Boat(){}
friend bool operator==(const Boat& lhs, const Boat& rhs) { return true; }
int testBoatAttribute;
};
struct Garage {
friend bool operator==(const Garage& lhs, const Garage& rhs) { return
true; }
std::vector<boost::shared_ptr<Vehicle>>& vehicleList() { return
m_VehicleList; }
std::vector<boost::shared_ptr<Vehicle>> m_VehicleList;
};
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
BOOST_PYTHON_MODULE(garage_ext){
using namespace boost::python;
class_<Garage>("Garage")
.def("vehicleList", &Garage::vehicleList,
return_internal_reference<1>());
class_<Vehicle,boost::shared_ptr<Vehicle>,boost::noncopyable>("Vehicle",
no_init)
.def_readwrite("testAttribute", &Vehicle::testAttribute);
class_<Boat,boost::shared_ptr<Boat>, bases<Vehicle>>("Boat")
.def_readwrite("testBoatAttribute", &Boat::testBoatAttribute);
implicitly_convertible<boost::shared_ptr<Boat>,
boost::shared_ptr<Vehicle>>();
class_<std::vector<boost::shared_ptr<Vehicle>>
>("stl_vector_Vehicle_ptr")
.def(vector_indexing_suite<std::vector<boost::shared_ptr<Vehicle>>>());
}
*Python test:*
from garage_ext import *
g = Garage()
l = g.vehicleList()
newboat = Boat()
newboat.testAttribute = 3
newboat.testBoatAttribute = 5
l.append(newboat)
print(type(l[0]))
print(str(hasattr(l[0],"testAttribute")))
print(str(l[0].testAttribute))
b = l[0]
print(type(b))
print(str(b.testBoatAttribute))
print("Done.")
*Raw pointer result:*
<class 'garage_ext.Boat'>
True
3
<class 'garage_ext.Boat'>
5
Done.
*Shared pointer result:*
<class 'garage_ext.*Vehicle*'> *// Expected it to be Boat as with Raw
pointers*
Traceback (most recent call last):
File "test_garage.py", line 9, in <module>
print(str(hasattr(l[0],"testAttribute"))) *// Expected attribute to
exist as with Raw pointers. Note: dir(l[0]) shows that it has the
attribute. Accessing the attribute however throws an error.*
Boost.Python.ArgumentError: Python argument types in
None.None(Vehicle)
did not match C++ signature:
None(Vehicle {lvalue})
Kind Regards,
Christoff
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net