Type converter not found for property
I am trying to expose a class with a boost::uuids::uuid member to Python. The class is pretty simple: class Article { public: boost::uuids::uuid uuid; }; which is exposed like this: article .def(init<boost::uuids::uuid, Article::Type>((arg("uuid"))) .def_readwrite("uuid", &Article::uuid); and I have basic converter registered (see https://gist.github.com/wichert/5543390 , it is a bit large to include in this email). This compiles fine and the uuid convertor works correctly when trying converting from python to C++, but trying to access the uuid property results in "TypeError: No Python class registered for C++ class boost::uuids::uuid". I don't understand why that doesn't work; does anyone see what I missed? Wichert.
That error means the type_id of uuid is not in the bp registry. I think you can fix this by deriving uuid_to_python from to_python_converter, as demonstrated in the pytype_function example[1]. This will add the get_pytype function call, and on initialisation, should hopefully add what's missing: a call to `registry::lookup`[2]. Cheers, Alex [1] - http://www.boost.org/doc/libs/1_53_0/libs/python/doc/v2/pytype_function.html [2] - http://www.boost.org/doc/libs/1_53_0/boost/python/converter/registry.hpp On Wed, 08 May 2013 21:33:51 +0100, Wichert Akkerman <wichert@wiggy.net> wrote:
I am trying to expose a class with a boost::uuids::uuid member to Python. The class is pretty simple:
class Article { public: boost::uuids::uuid uuid; };
which is exposed like this:
article .def(init<boost::uuids::uuid, Article::Type>((arg("uuid"))) .def_readwrite("uuid", &Article::uuid);
and I have basic converter registered (see https://gist.github.com/wichert/5543390 , it is a bit large to include in >this email). This compiles fine and the uuid convertor works correctly when trying converting from python to C++, but >trying to access the uuid property results in "TypeError: No Python class registered for C++ class >boost::uuids::uuid". I don't understand why that doesn't work; does anyone see what I missed?
Wichert.
-- Using Opera's mail client: http://www.opera.com/mail/
On May 8, 2013, at 23:31 , "Alex Leach" <beamesleach@gmail.com> wrote:
That error means the type_id of uuid is not in the bp registry.
I think you can fix this by deriving uuid_to_python from to_python_converter, as demonstrated in the pytype_function example[1]. This will add the get_pytype function call, and on initialisation, should hopefully add what's missing: a call to `registry::lookup`[2].
I'm afraid that doesn't work. To test this I changes my converter struct to derive from bp::converter::wrap_pyttype<&PyStringType> and pass has_get_type=true to the to_python_converter call, but I still get the exact same error. Regards, Wichert.
On Thu, 09 May 2013 07:55:07 +0100, Wichert Akkerman <wichert@wiggy.net> wrote:
On May 8, 2013, at 23:31 , "Alex Leach" <beamesleach@gmail.com> wrote:
That error means the type_id of uuid is not in the bp registry.
I think you can fix this by deriving uuid_to_python from
to_python_converter, as demonstrated in the pytype_function example[1]. >>This will add the get_pytype function call, and on initialisation, should >>hopefully add what's missing: a call to `registry::lookup`[2].
I'm afraid that doesn't work. To test this I changes my converter struct to derive from >bp::converter::wrap_pyttype<&PyStringType> and pass has_get_type=true to the to_python_converter call, but I still >get the exact same error.
Fair enough. I see your conversion function doesn't use bp::object, but a raw PyObject instead. Using a bp::object might do the registration for you.. Probably not. Alternatively, you could try adding this to your registration code:- converter::registration& uuid_converter = const_cast<converter::registration&>( converter::registry::lookup(type_id<boost::uuids::uuid>()) ); uuid_converter.m_class_object = # if PY_VERSION_HEX >= 0x03000000 &PyUnicode_Type; #else &PyString_Type; #endif That will get you past the current error, at least, but there's probably an easier solution... HTH, Alex
On May 9, 2013, at 12:34 , Alex Leach <beamesleach@gmail.com> wrote:
On Thu, 09 May 2013 07:55:07 +0100, Wichert Akkerman <wichert@wiggy.net> wrote:
On May 8, 2013, at 23:31 , "Alex Leach" <beamesleach@gmail.com> wrote:
That error means the type_id of uuid is not in the bp registry.
I think you can fix this by deriving uuid_to_python from to_python_converter, as demonstrated in the pytype_function example[1]. This will add the get_pytype function call, and on initialisation, should hopefully add what's missing: a call to `registry::lookup`[2].
I'm afraid that doesn't work. To test this I changes my converter struct to derive from bp::converter::wrap_pyttype<&PyStringType> and pass has_get_type=true to the to_python_converter call, but I still get the exact same error.
Fair enough. I see your conversion function doesn't use bp::object, but a raw PyObject instead. Using a bp::object might do the registration for you.. Probably not. Alternatively, you could try adding this to your registration code:-
converter::registration& uuid_converter = const_cast<converter::registration&>( converter::registry::lookup(type_id<boost::uuids::uuid>()) );
uuid_converter.m_class_object = # if PY_VERSION_HEX >= 0x03000000 &PyUnicode_Type; #else &PyString_Type; #endif
That will get you past the current error, at least, but there's probably an easier solution…
That seems to do something! But still not quite there:
a.uuid Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot create weak reference to 'str' object u=a.uuid zsh: segmentation fault
On May 10, 2013, at 11:10 , Wichert Akkerman <wichert@wiggy.net> wrote:
On May 9, 2013, at 12:34 , Alex Leach <beamesleach@gmail.com> wrote:
On Thu, 09 May 2013 07:55:07 +0100, Wichert Akkerman <wichert@wiggy.net> wrote:
On May 8, 2013, at 23:31 , "Alex Leach" <beamesleach@gmail.com> wrote:
That error means the type_id of uuid is not in the bp registry.
I think you can fix this by deriving uuid_to_python from to_python_converter, as demonstrated in the pytype_function example[1]. This will add the get_pytype function call, and on initialisation, should hopefully add what's missing: a call to `registry::lookup`[2].
I'm afraid that doesn't work. To test this I changes my converter struct to derive from bp::converter::wrap_pyttype<&PyStringType> and pass has_get_type=true to the to_python_converter call, but I still get the exact same error.
Fair enough. I see your conversion function doesn't use bp::object, but a raw PyObject instead. Using a bp::object might do the registration for you.. Probably not. Alternatively, you could try adding this to your registration code:-
converter::registration& uuid_converter = const_cast<converter::registration&>( converter::registry::lookup(type_id<boost::uuids::uuid>()) );
uuid_converter.m_class_object = # if PY_VERSION_HEX >= 0x03000000 &PyUnicode_Type; #else &PyString_Type; #endif
That will get you past the current error, at least, but there's probably an easier solution…
That seems to do something! But still not quite there:
a.uuid Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot create weak reference to 'str' object u=a.uuid zsh: segmentation fault
Which can be fixed by not using def_readwrite but a property with a getting returning a new value instead of a reference: .add_property("uuid", bp::make_getter(&Article::uuid, bp::return_value_policy<bp::return_by_value>()), bp::make_setter(&Article::uuid)) After which everything seems to work! Wichert.
On 05/08/2013 04:33 PM, Wichert Akkerman wrote:
I am trying to expose a class with a boost::uuids::uuid member to Python. The class is pretty simple:
class Article { public: boost::uuids::uuid uuid; };
which is exposed like this:
article .def(init<boost::uuids::uuid, Article::Type>((arg("uuid"))) .def_readwrite("uuid", &Article::uuid);
and I have basic converter registered (see https://gist.github.com/wichert/5543390 , it is a bit large to include in this email). This compiles fine and the uuid convertor works correctly when trying converting from python to C++, but trying to access the uuid property results in "TypeError: No Python class registered for C++ class boost::uuids::uuid". I don't understand why that doesn't work; does anyone see what I missed?
I suspect that def_readwrite requires lvalue converters, and I see that you've only implemented an rvalue converter. I think in this case you're better off just writing a getter and setter, and wrapping those using add_property. Jim
On 05/08/2013 05:48 PM, Jim Bosch wrote:
On 05/08/2013 04:33 PM, Wichert Akkerman wrote:
I am trying to expose a class with a boost::uuids::uuid member to Python. The class is pretty simple:
class Article { public: boost::uuids::uuid uuid; };
which is exposed like this:
article .def(init<boost::uuids::uuid, Article::Type>((arg("uuid"))) .def_readwrite("uuid", &Article::uuid);
and I have basic converter registered (see https://gist.github.com/wichert/5543390 , it is a bit large to include in this email). This compiles fine and the uuid convertor works correctly when trying converting from python to C++, but trying to access the uuid property results in "TypeError: No Python class registered for C++ class boost::uuids::uuid". I don't understand why that doesn't work; does anyone see what I missed?
I suspect that def_readwrite requires lvalue converters, and I see that you've only implemented an rvalue converter. I think in this case you're better off just writing a getter and setter, and wrapping those using add_property.
Ah, sorry, that didn't make any sense. There's no such thing as an lvalue to-Python converter, and to-Python is the problem here. You may want to try also registering your to-Python converter for the pointers and/or references to uuid. I ran into a similar problem with getting def_readwrite to work a while back, and specializing for pointer/reference/const variants made it go away, though I was using a different converter mechanism (by partial specialization of some template classes - not something I'd recommend here). Jim
On May 8, 2013, at 23:58 , Jim Bosch <talljimbo@gmail.com> wrote:
On 05/08/2013 05:48 PM, Jim Bosch wrote:
On 05/08/2013 04:33 PM, Wichert Akkerman wrote:
I am trying to expose a class with a boost::uuids::uuid member to Python. The class is pretty simple:
class Article { public: boost::uuids::uuid uuid; };
which is exposed like this:
article .def(init<boost::uuids::uuid, Article::Type>((arg("uuid"))) .def_readwrite("uuid", &Article::uuid);
and I have basic converter registered (see https://gist.github.com/wichert/5543390 , it is a bit large to include in this email). This compiles fine and the uuid convertor works correctly when trying converting from python to C++, but trying to access the uuid property results in "TypeError: No Python class registered for C++ class boost::uuids::uuid". I don't understand why that doesn't work; does anyone see what I missed?
I suspect that def_readwrite requires lvalue converters, and I see that you've only implemented an rvalue converter. I think in this case you're better off just writing a getter and setter, and wrapping those using add_property.
Ah, sorry, that didn't make any sense. There's no such thing as an lvalue to-Python converter, and to-Python is the problem here.
You may want to try also registering your to-Python converter for the pointers and/or references to uuid. I ran into a similar problem with getting def_readwrite to work a while back, and specializing for pointer/reference/const variants made it go away, though I was using a different converter mechanism (by partial specialization of some template classes - not something I'd recommend here).
If I try to do that by adding this: to_python_converter<boost::uuids::uuid, uuid_to_python>(); to_python_converter<boost::uuids::uuid&, uuid_to_python>() I get a compile error: /opt/local/include/boost/python/converter/as_to_python_function.hpp:21:84: error: 'type name' declared as a pointer to a reference of type 'boost::uuids::uuid &' static void convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0) {} ^ /opt/local/include/boost/python/to_python_converter.hpp:88:10: note: in instantiation of template class 'boost::python::converter::as_to_python_function<boost::uuids::uuid &, <anonymous>::uuid_to_python>' requested here &normalized::convert ^ ../../python/uuid.cc:77:2: note: in instantiation of member function 'boost::python::to_python_converter<boost::uuids::uuid &, <anonymous>::uuid_to_python, false>::to_python_converter' requested here python::to_python_converter<boost::uuids::uuid&, uuid_to_python>(); which suggests that to_python_converter doesn't really like to see references. Wichert.
On Thu, 09 May 2013 07:41:49 +0100, Wichert Akkerman <wichert@wiggy.net> wrote:
If I try to do that by adding this:
to_python_converter<boost::uuids::uuid, uuid_to_python>(); to_python_converter<boost::uuids::uuid&, uuid_to_python>()
I get a compile error:
/opt/local/include/boost/python/converter/as_to_python_function.hpp:21:84: error: 'type name' declared as a pointer to a reference of type 'boost::uuids::uuid &' static void convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0) {} ^ /opt/local/include/boost/python/to_python_converter.hpp:88:10: note: in instantiation of template class 'boost::python::converter::as_to_python_function<boost::uuids::uuid &, <anonymous>::uuid_to_python>' requested here &normalized::convert ^ ../../python/uuid.cc:77:2: note: in instantiation of member function 'boost::python::to_python_converter<boost::uuids::uuid &, <anonymous>::uuid_to_python, false>::to_python_converter' requested here python::to_python_converter<boost::uuids::uuid&, uuid_to_python>();
which suggests that to_python_converter doesn't really like to see references.
Unfortunately the convert function doesn't like non-const references; const references (and values) should work fine, though. Cheers, Alex
On May 9, 2013, at 12:42 , Alex Leach <beamesleach@gmail.com> wrote:
On Thu, 09 May 2013 07:41:49 +0100, Wichert Akkerman <wichert@wiggy.net> wrote:
If I try to do that by adding this:
to_python_converter<boost::uuids::uuid, uuid_to_python>(); to_python_converter<boost::uuids::uuid&, uuid_to_python>()
I get a compile error:
/opt/local/include/boost/python/converter/as_to_python_function.hpp:21:84: error: 'type name' declared as a pointer to a reference of type 'boost::uuids::uuid &' static void convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0) {} ^ /opt/local/include/boost/python/to_python_converter.hpp:88:10: note: in instantiation of template class 'boost::python::converter::as_to_python_function<boost::uuids::uuid &, <anonymous>::uuid_to_python>' requested here &normalized::convert ^ ../../python/uuid.cc:77:2: note: in instantiation of member function 'boost::python::to_python_converter<boost::uuids::uuid &, <anonymous>::uuid_to_python, false>::to_python_converter' requested here python::to_python_converter<boost::uuids::uuid&, uuid_to_python>();
which suggests that to_python_converter doesn't really like to see references.
Unfortunately the convert function doesn't like non-const references; const references (and values) should work fine, though.
They don't though: you can't create a pointer to a const reference. Wichert.
participants (3)
-
Alex Leach -
Jim Bosch -
Wichert Akkerman