"Jim Bosch"  wrote in message news:4e4ad9d9.9000...@gmail.com...

Unfortunately, there's no "best-match" type checking in Boost.Python; when trying to convert a Python object to a particular C++ type, it simply runs over a list of all the converters registered (using RTTI) for that C++ type.

Each of those converters then gets a chance to check whether it "matches" the Python object; if it thinks it does, none of the other converters get tried.

I'd guess that's what's happening to you - implicitly_convertible doesn't really do enough work in that match stage, so the first conversion you've registered says "I match!" and then fails by throwing an exception.

The fix might be in how you've written your vector<> conversions; when given a list or tuple that contains the wrong element type, they need to report that they "don't match", rather than matching any list or tuple and then throwing an exception when the element type is incorrect.

Good luck!

Jim Bosch

I change my vector<> conversion(see it in my last reply) to add specialization for int, float, string etc.
I added type check in convertible() function:

   template <>
   struct vector_from_python <float>
   {
       vector_from_python()
       {
           python::converter::registry::push_back(&convertible, &construct,
python::type_id<vector<float> >());
       }

       static void* convertible(PyObject* obj_ptr)
       {
           if (!(PyList_Check(obj_ptr) || PyTuple_Check(obj_ptr)
                 || PyIter_Check(obj_ptr)  || PyRange_Check(obj_ptr))) {
               return 0;
           }

PyObject * first_obj = PyObject_GetItem(obj_ptr, PyInt_FromLong(0));
           if( !PyObject_TypeCheck(first_obj, &PyFloat_Type) ) {
               return 0;
           }

           return obj_ptr;
       }


       static void construct(PyObject* obj_ptr,
python::converter::rvalue_from_python_stage1_data* data)
       {
           void* storage =
((python::converter::rvalue_from_python_storage<vector<float> >*)
                            data)->storage.bytes;
           new (storage) vector<float>();

           data->convertible = storage;

           vector<float>& result = *((vector<float>*) storage);

           python::handle<> obj_iter(PyObject_GetIter(obj_ptr));

           while(1) {
               python::handle<>
py_elem_hdl(python::allow_null(PyIter_Next(obj_iter.get())));
               if (PyErr_Occurred()) {
                   python::throw_error_already_set();
               }

               if (!py_elem_hdl.get()) {
                   break;
               }

               python::object py_elem_obj(py_elem_hdl);
               python::extract<float> elem_proxy(py_elem_obj);
               result.push_back(elem_proxy());
           }
       }
   };

This time the implicit type conversion works perfectly. But I got a new problem: the memory leak! The memory leak happens only for float type, whenever I convert the float list in python to vector of float in c++, the memory for float list is leaked. I put the call in a function, and called the gc.collect()
after exit the function, the memory is still not recycled.

Why is the memory of the python list is not freed after exit the scope?

Grant

_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to