map_indexing_suite does not find to-python convertors

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

map_indexing_suite does not find to-python convertors

Wichert Akkerman
I am struggling to expose a map to python code. What I am doing is
pretty simple: I have a map from an enum type to Glib::ustring, with a
convertors registered to convert Python str and unicode instances to an
ustring, and ustring to Python unicode. I've put the relevant code below.

What I am running into is that the conversion from python to C++ types
is failing with a "No Python class registered for C++ class
Glib::ustring" error. This looks very similar to the FAQ entry "Why is
my automatic to-python conversion not being found?"
(http://www.boost.org/doc/libs/1_47_0/libs/python/doc/v2/faq.html#topythonconversionfailed 
), and the workaround suggested there indeed works fine for class
properties. I can't seem to find a similar trick for map values though.
Is there a trick to get this working?

Wichert.



enum aspect_type { ... };
typedef std::map<aspect_type, Glib::ustring>  aspect_map;

struct ustring_to_python {
        static PyObject* convert(Glib::ustring const&  s) {
                PyObject* unicode;
                unicode=PyUnicode_DecodeUTF8(s.data(), static_cast<Py_ssize_t>(s.size()), "ignore");
                Py_INCREF(unicode);
                return unicode;
        }
};

struct ustring_from_python {
        ustring_from_python() {
                converter::registry::push_back(&convertible,&construct, type_id<Glib::ustring>());
        }

        static void* convertible(PyObject *obj) {
                if (PyUnicode_Check(obj) || PyString_Check(obj))
                        return obj;
                return 0;
        }

        static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data *data) {
                PyObject *str = 0;
                char* value;

                if (PyUnicode_Check(obj)) {
                        str = PyUnicode_AsUTF8String(obj);
                        if (str==0)
                                throw_error_already_set();
                }
               
                value = PyString_AsString(obj);
                if (value==0) {
                        Py_XDECREF(str);
                        throw_error_already_set();
                }

                void* storage = ((converter::rvalue_from_python_storage<Glib::ustring>*)data)->storage.bytes;
                new (storage) Glib::ustring(value);
                data->convertible = storage;
                Py_XDECREF(obj);
        }
};



BOOST_PYTHON_MODULE(mymodule) {
     to_python_converter<Glib::ustring, ustring_to_python>();
     ustring_from_python();

     class_<Article::aspect_map>("AspectMap")
         .def(map_indexing_suite<aspect_map, true>());


}


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: map_indexing_suite does not find to-python convertors

Jim Bosch-2
On 09/22/2011 09:43 AM, Wichert Akkerman wrote:

> I am struggling to expose a map to python code. What I am doing is
> pretty simple: I have a map from an enum type to Glib::ustring, with a
> convertors registered to convert Python str and unicode instances to an
> ustring, and ustring to Python unicode. I've put the relevant code below.
>
> What I am running into is that the conversion from python to C++ types
> is failing with a "No Python class registered for C++ class
> Glib::ustring" error. This looks very similar to the FAQ entry "Why is
> my automatic to-python conversion not being found?"
> (http://www.boost.org/doc/libs/1_47_0/libs/python/doc/v2/faq.html#topythonconversionfailed
> ), and the workaround suggested there indeed works fine for class
> properties. I can't seem to find a similar trick for map values though.
> Is there a trick to get this working?
>

I think the easiest solution would be to try to switch to indexing suite
v2 (I think the newest version is found in the Py++ sources, although
you don't have to use Py++ to make use of it).  With that, you can set
the call policies for returning elements from your container.

There are ways to do this with indexing suite v1 (the version that comes
with Boost.Python), but it'd be a lot harder, and I'm not certain what
approach to recommend that you try first in that case.


Jim
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: map_indexing_suite does not find to-python convertors

Wichert Akkerman
On 09/22/2011 04:31 PM, Jim Bosch wrote:

> On 09/22/2011 09:43 AM, Wichert Akkerman wrote:
>> I am struggling to expose a map to python code. What I am doing is
>> pretty simple: I have a map from an enum type to Glib::ustring, with a
>> convertors registered to convert Python str and unicode instances to an
>> ustring, and ustring to Python unicode. I've put the relevant code
>> below.
>>
>> What I am running into is that the conversion from python to C++ types
>> is failing with a "No Python class registered for C++ class
>> Glib::ustring" error. This looks very similar to the FAQ entry "Why is
>> my automatic to-python conversion not being found?"
>> (http://www.boost.org/doc/libs/1_47_0/libs/python/doc/v2/faq.html#topythonconversionfailed 
>>
>> ), and the workaround suggested there indeed works fine for class
>> properties. I can't seem to find a similar trick for map values though.
>> Is there a trick to get this working?
>>
>
> I think the easiest solution would be to try to switch to indexing
> suite v2 (I think the newest version is found in the Py++ sources,
> although you don't have to use Py++ to make use of it).  With that,
> you can set the call policies for returning elements from your container.

Is
http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/indexing_suite_v2/ 
the latest version of that? I'll give it a try.

wichert.

_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: map_indexing_suite does not find to-python convertors

Wichert Akkerman
On 09/22/2011 04:50 PM, Wichert Akkerman wrote:

> On 09/22/2011 04:31 PM, Jim Bosch wrote:
>> On 09/22/2011 09:43 AM, Wichert Akkerman wrote:
>>> I am struggling to expose a map to python code. What I am doing is
>>> pretty simple: I have a map from an enum type to Glib::ustring, with a
>>> convertors registered to convert Python str and unicode instances to an
>>> ustring, and ustring to Python unicode. I've put the relevant code
>>> below.
>>>
>>> What I am running into is that the conversion from python to C++ types
>>> is failing with a "No Python class registered for C++ class
>>> Glib::ustring" error. This looks very similar to the FAQ entry "Why is
>>> my automatic to-python conversion not being found?"
>>> (http://www.boost.org/doc/libs/1_47_0/libs/python/doc/v2/faq.html#topythonconversionfailed 
>>>
>>> ), and the workaround suggested there indeed works fine for class
>>> properties. I can't seem to find a similar trick for map values though.
>>> Is there a trick to get this working?
>>>
>>
>> I think the easiest solution would be to try to switch to indexing
>> suite v2 (I think the newest version is found in the Py++ sources,
>> although you don't have to use Py++ to make use of it).  With that,
>> you can set the call policies for returning elements from your
>> container.
>
> Is
> http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/indexing_suite_v2/ 
> the latest version of that? I'll give it a try.

That certainly seems to solve the conversion problem I have been seeing.
It does have some flaws though, such as find_or_throw  raising a
ValueError instead of a KeyError when a key is not found in a mapping.

Is there an active bug tracker for the indexing suite where this could
be filed?

Wichert.


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig