[PySide] Python bindings generation

Alexandre alexandre.gauthier-foichat at inria.fr
Wed Oct 22 09:19:11 CEST 2014


Hi,

First of all thank you for the amazing development regarding Pyside. We’re currently in the process of implementing Python bindings for the C++ based application Natron (https://github.com/MrKepzie/Natron <https://github.com/MrKepzie/Natron>). We’re using Shiboken and are running into some issues which maybe some of you can answer ;)

1) One of the main issue I have is to understand what needs to have a conversion-rule and what needs not. For example is this kind of conversion really needed ? 

<primitive-type name="std::size_t" target-lang-api-name="PyLong">
        <conversion-rule>
            <native-to-target>
                return PyLong_FromSize_t(%in);
            </native-to-target>
            <target-to-native>
                <add-conversion type="PyLong">
                    %out = %OUTTYPE(PyLong_AsSsize_t(%in));
                </add-conversion>
            </target-to-native>
        </conversion-rule>
    </primitive-type>

Couldn't someone just write <primitive-type name="std::size_t”/> ?

What about STL types such as std::string, I’m currently providing a conversion the following way:

<primitive-type name="std::string">
        <conversion-rule>
            <native-to-target>
                PyObject* %out = PyString_AsStringAndSize(%in.c_str(),%in.size());
                return %out;
            </native-to-target>
            <target-to-native>
                <add-conversion type="PyObject">
                    char* cstr = PyString_AsString(%in);
                    %out = std::string(cstr);
                    return %out;
                </add-conversion>
            </target-to-native>
        </conversion-rule>
    </primitive-type>

But I have no clue if this is the right way to do it.

2) About STL containers I saw that for QtCore, templates are used to convert all containers, I decided then to do the same for all STL containers, this way :

<!--Templates for type conversions used many times—>
 <load-typesystem name="typesystem_templates.xml" generate="no"/>
…
<!--std::list from/to Python list-->
    <container-type name="std::list" type="list">
        <include file-name="list" location="global"/>
        <conversion-rule>
            <native-to-target>
                <insert-template name="stdListToPyList"/>
            </native-to-target>
            <target-to-native>
                <add-conversion type="PySequence">
                    <insert-template name="pyListToStdList"/>
                </add-conversion>
            </target-to-native>
        </conversion-rule>
    </container-type>

But when running shiboken2-7 with the include-paths and typesystem-paths pointing to the template files I get the following:
insert-template referring to non-existing template 'stdListToPyList'


With the templates defined as such:

<template name="stdListToPyList">
        PyObject* %out = PyList_New((int) %in.size());
        %INTYPE::const_iterator it = %in.begin();
        for (int idx = 0; it != %in.end(); ++it, ++idx) {
        %INTYPE_0 cppItem(*it);
        PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
        }
        return %out;
    </template>
    <template name="pyListToStdList">
        for (int i = 0; i < PySequence_Size(%in); i++) {
        Shiboken::AutoDecRef pyItem(PySequence_GetItem(%in, i));
        %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
        %out.push_back(cppItem);
        }
    </template>

3)  I don’t understand the separation between primitive/value/container/object types, to me they all sound the same. In which category should a C++ template class fall-in ? A container or an object ?

4) Also after reading the following documentation on Shiboken github https://github.com/PySide/shiboken-docs/blob/master/docs/typeconverters.rst <https://github.com/PySide/shiboken-docs/blob/master/docs/typeconverters.rst> I saw that this is possible to write a template Converter class with a toPython and toCpp methods to handle the conversion. What does this technique offers ? Is this just a different way to provide a conversion rule ?

5) Is it right that in order to be able to use %CONVERTTOPYTHON one must provide a conversion-rule for that primitive/value/object beforehand ?

6) I have some global functions in a namespace, such as the following : 

namespace XXX
{
inline std::list<std::string>
getPluginIDs()
{
   // Code logic
}
}

In the type system file should I list this function under then XXX namespace tag the following way:
<namespace-type name=“XXX">
    <function signature="getPluginIDs()"/>
 </namespace-type>

Or is the namespace-type tag not at all needed ?
Well whatever is the good way to bind global function in a namespace, I always get the following error: 
Global function 'getPluginIDs()' is specified in typesystem, but not defined. This could potentially lead to compilation errors.

But in mjb_rejected_functions.log I can’t see any error regarding this function.
Is this because the return type std::list<std::string> is not recognised ? That’s weird because I provided a conversion for it already in the type system.

7) Finally I reported a bug here https://bugreports.qt-project.org/browse/PYSIDE-260 <https://bugreports.qt-project.org/browse/PYSIDE-260> because I can’t figure out why there are QtGui includes in a QtCore module! Our application is really segmented and the “Core” part relies on QtCore and the “Gui” part relies on QtGui, using QtGui for the “Core” part is really not an option because we may want to use our application on a device without a display server for instance.

8) I had some segmentation faults because of boost includes, I had to define
 #define SBK_RUN   (the same way Q_MOC_RUN is defined for moc) 
in the global.h header of my library and wrap up all boost include with a #ifndef SBK_RUN and the crash was gone. Maybe you could document it somewhere;)

Anyway, that’s all for the swarm of questions for now;) Thank you for developing this and taking your time to answer to my questions.
The bindings generation looks really great but maybe a bit more explanations and guidance on how to write the type system would be great;) Having to look into the typesystem_core.xml file is quite complicated when you’re not familiar with all the philosophy around Shiboken!

Just for the record, here’s the documentation that I have read so far and I can’t seem to find more doc online:

Python binding generation with Shiboken tutorial:  http://qt-project.org/wiki/PySide_Binding_Generation_Tutorial <http://qt-project.org/wiki/PySide_Binding_Generation_Tutorial>
tests/samplebinding in the source code repository: https://qt.gitorious.org/pyside/shiboken/source/4e0031258b9098c5dc02b34e5eb570e54307e6b5:tests/samplebinding <https://qt.gitorious.org/pyside/shiboken/source/4e0031258b9098c5dc02b34e5eb570e54307e6b5:tests/samplebinding>
Typsystem files for QtCore and QtGui in the source code repository: https://qt.gitorious.org/pyside/pyside/source/0c64d1b2c6e5e0951675ad9b22294db4a10741c7:PySide/QtCore <https://qt.gitorious.org/pyside/pyside/source/0c64d1b2c6e5e0951675ad9b22294db4a10741c7:PySide/QtCore>

Alex

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20141022/ddd7ab58/attachment.html>


More information about the PySide mailing list