[PyKDE] Re: SIP help

Phil Thompson phil at river-bank.demon.co.uk
Sat Jun 3 12:09:23 BST 2000

Check my web page (http://www.river-bank.demon.co.uk/software) for a
link to the mailing list.


Sometimes a class in a library you are generating bindings for is
similar to a standard Python data type. These 3 directives combine to
allow you to automatically replace the library class with any Python
data type. To take an example from PyQt, Qt has a class QStrList which
is a QList of C strings. It's more natural for a Python programmer to
use a Python list of strings. The code you write with these directives
(see qstrlist.sip) means that a QStrList is converted to a Python list
(and vice versa) automatically wherever it is needed.

Specifically, the function generated by %ConvertFromClassCode takes a
QStrList* and returns a Python list object. The function generated by
%CanConvertToClassCode takes a Python object and returns non-zero if is
the right type to be converted to a QStrList. (This function must not
have any side effects as it is not necessarily an error if it fails.)
The function generated by %ConvertToClassCode actually does the
conversion between a Python object and a QStrList - this function will
not be called unless the %CanConvertToClassCode is successful.


Normally, if a library functions returns a pointer to an instance of a
class then SIP will create a Python object of the corresponding Python
class. In some cases the library function is actually returning a
sub-class and (usually) there is a way to determine what the sub-class
is so that (in C++) the pointer can be cast to the correct sub-class.

The example in PyQt is the QEvent class which has the type() method to
determine the actual sub-class. The %ConvertToSubClassCode directive
allows you to write code to do, in effect, the sub-class casting
automatically - see qevent.sip. Without this, event handling in PyQt
would be useless.

If a future version of SIP makes use of RTTI then this directive will go
because SIP could then generate the necessary code automatically.


Some C++ types don't have equivalents in Python (pointers to simple
types like int* for example), and it's not possible for SIP to work out
how they should be handled. Therefore, you have to provide your own code
to handle them as you want. SIP will complain if it needs handwritten
code but you haven't provided any.


%HeaderCode stuff is made available to all the relevant code in the same
SIP module. %ExportedHeaderCode stuff is made available to other SIP
modules - typically utility function declarations. PyQt exports some
handwritten functions to be used by PyKDE for example.


This is handwritten code not specific to any particular class. You'd
typically use this for the implementation of any utility functions.


This is needed for the same reasons as %MemberCode is needed, and is
used (in addition to %MemberCode) for virtual class methods.


For a set of bindings SIP generates 2 modules - the one in Python that
the programmer is aware of, and the compiled C one that the Python
module uses to do all the work.

This directive takes the name of a function that should take 2 PyObject*
arguments and return a PyObject*. The function will typically appear as
a %C++Code directive. The function will be added to the interface of the
compiled C module so that it can be called by the Python module.

In PyQt it is used to allow the Python module to determine if it is
running on a Windows systems or an X11 system.


More information about the PyQt mailing list