[PyKDE] Dependency on sip.pyd

Giovanni Bajo rasky at develer.com
Sat Nov 11 12:19:25 GMT 2006

Phil Thompson wrote:

> A genuine question (because I don't know the answer) - do Boost and
> SWIG support the wrapping of a C++ class hierarchy across multiple
> modules? Do they support the ability for somebody else to wrap 3rd
> party libraries that derive from the wrapped C++ library? That (to me
> anyway) is SIP's most important feature.

I believe they don't. I might be wrong here, but I think you're right that SIP
is the only tool with this feature. The case of PyQt & friends, though, is
pretty unique: we have a large basic library PyQt, and many other libraries
built on top of it. I have been used SIP several times now (for about 5-6
different libraries) and I had *never* used this feature. In fact, typical
scenarios for me are:

1) You write bindings for a single C++ library (of which you might even be the
author, and thus add things directly within it). This is by far the most common
use case.
2) You need to write binding for library A, which is built on top of library B.
But you *only* need to access A's API: B is in fact just an "implementation"
detail of A. It might be that some B's types or objects are exposed, but it
does not matter, since what you really want is A. In that case, you write the
bindings for A's API (and the little part of B's API that is exposed by A), and
link A and B together into a.pyd (forgetting about B).

Thus, I have really never used the feature of a binding a large C++ hierarchy
across many modules. Instead, I have faced many problems with random crashes
whenever I updated SIP and I forgot to recompile this or that, maybe only in
branch A of project K; I have about 15 sip.pyd around in my hard disk, and I
guess they are of at least 3 or 4 different versions.

Now, I'm absolute not saying that you should remove this feature altogether.
It's of course a big winner for PyQt & friend, it works really well even only
with Qt4 separate modules, and PyQt is the primary target of SIP. I'm just
saying that you should consider that this feature can also cause problems in
many other use cases (where it is not used).

> I appreciate your problem is real, but this solution isn't the right
> one.

It's the one I devised at least: add an option to inline all the SIP code and
remove the binary dependency altogether. If there is a better way, I'm really
looking forward to hearing it.

After having looked at the code, I believe the less intrusive way would be to
keep SIP as a Python module (as in PyModule), and just "embed" it within the
same .pyd. So for instance, if I compiled my own library "foo" with SIP, I
would have its SIP library accessible through "import foo.sip", I could check
for the version it was built with through "foo.sip.SIP_VERSION_STR", I'd have
handy features like "foo.sip.isdeleted()" and so on. siplib would be built as a
static library (siplib.a) and linked to the generated code; init_foo() would
call init_sip() (from siplib.a), and then bound the created module as attribute
to module "foo".

Many things would just stay as they are: the difference is simply that there
would not be any sip.pyd file around: and since I'm not going to ever enlarge
foo's C++ hierarchy in a different module, it's only a winner.

Giovanni Bajo

More information about the PyQt mailing list