Boost.Python C++ pointer object to python: Attribute does not exist.
Hi, I'm struggling with the following issue in a boost.python implementation: I have a list of std::shared_ptr in C++, I am accessing this list from Python. - When I access an element in the list, the elements does not have any attributes apparently. I get an error trying to access an attribute, hasattr returns false on the attribute, but dir informs me that it exist. - When I change the C++ implementation from shared_ptr to raw ptr's everything works as expected. - I want to use shared_ptrs for what I feel: obvious reasons. Below is the C++ code and the Python code. ################### ### garage_ext.cpp ### ################### #include<memory> #include<vector> namespace boost { template<class T> T* get_pointer(std::shared_ptr<T>& p){ return p.get(); }} 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<std::shared_ptr<Vehicle>>& vehicleList() { return m_VehicleList; } std::vector<std::shared_ptr<Boat>>& boatList() { return m_BoatList; } std::vector<std::shared_ptr<Vehicle>> m_VehicleList; std::vector<std::shared_ptr<Boat>> m_BoatList; }; #include <boost/python.hpp> #include <boost/python/suite/indexing/vector_indexing_suite.hpp> class BoatWrap : public Boat, public boost::python::wrapper<Boat> { public: static std::shared_ptr<Boat> cast(std::shared_ptr<Vehicle> const& v) { return std::dynamic_pointer_cast<Boat>(v); } }; BOOST_PYTHON_MODULE(garage_ext) { using namespace boost::python; class_<Garage>("Garage") .def("vehicleList", &Garage::vehicleList, return_internal_reference<1>()) .def("boatList", &Garage::boatList, return_internal_reference<1>()) ; class_<Vehicle, std::shared_ptr<Vehicle>,boost::noncopyable>("Vehicle", no_init) .def_readwrite("testAttribute", &Vehicle::testAttribute) ; class_<BoatWrap,std::shared_ptr<Boat>,bases<Vehicle>>("Boat") .def("cast", &BoatWrap::cast) .staticmethod("cast") .def_readwrite("testBoatAttribute", &Boat::testBoatAttribute) ; implicitly_convertible<std::shared_ptr<Boat>,std::shared_ptr<Vehicle>>(); class_<std::vector<std::shared_ptr<Vehicle>> >("stl_vector_Vehicle_ptr") .def(vector_indexing_suite<std::vector<std::shared_ptr<Vehicle>>
()); class_<std::vector<std::shared_ptr<Boat>> >("stl_vector_Boat_ptr") .def(vector_indexing_suite<std::vector<std::shared_ptr<Boat>> >()); }
##################### ### Python test code ### ##################### g = Garage() l = g.boatList() newboat = Boat() l.append(newboat) boatFromList = l[0] print(type(boatFromList)) print(str(hasattr(newboat,"testBoatAttribute"))) dir(boatFromList) # The following line throws the error. print(str(hasattr(boatFromList,"testBoatAttribute"))) I created a cast method for boat. If I cast l[0] to Boat using: boatFromList = Boat.cast(l[0]) print(str(hasattr(boatFromList,"testBoatAttribute"))) works. This is all very strange to me. It feels very buggy. Could someone please help me clarify the reason for this behavious? Regards, Christoff
participants (1)
-
Christoff Kok