.. _words-of-advice: *************** Words of Advice *************** When writing or using Python bindings there is some things you must keep in mind. .. _duck-punching-and-virtual-methods: Duck punching and virtual methods ================================= The combination of duck punching, the practice of altering class characteristics of already instantiated objects, and virtual methods of wrapped C++ classes, can be tricky. That was an optimistic statement. Let's see duck punching in action for educational purposes. .. code-block:: python import types import Binding obj = Binding.CppClass() # CppClass has a virtual method called 'virtualMethod', # but we don't like it anymore. def myVirtualMethod(self_obj, arg): pass obj.virtualMethod = types.MethodType(myVirtualMethod, obj, Binding.CppClass) If some C++ code happens to call `CppClass::virtualMethod(...)` on the C++ object held by "obj" Python object, the new duck punched "virtualMethod" method will be properly called. That happens because the underlying C++ object is in fact an instance of a generated C++ class that inherits from `CppClass`, let's call it `CppClassWrapper`, responsible for receiving the C++ virtual method calls and finding out the proper Python override to which handle such a call. Now that you know this, consider the case when C++ has a factory method that gives you new C++ objects originated somewhere in C++-land, in opposition to the ones generated in Python-land by the usage of class constructors, like in the example above. Brief interruption to show what I was saying: .. code-block:: python import types import Binding obj = Binding.createCppClass() def myVirtualMethod(self_obj, arg): pass # Punching a dead duck... obj.virtualMethod = types.MethodType(myVirtualMethod, obj, Binding.CppClass) The `Binding.createCppClass()` factory method is just an example, C++ created objects can pop out for a number of other reasons. Objects created this way have a Python wrapper holding them as usual, but the object held is not a `CppClassWrapper`, but a regular `CppClass`. All virtual method calls originated in C++ will stay in C++ and never reach a Python virtual method overridden via duck punching. Although duck punching is an interesting Python feature, it don't mix well with wrapped C++ virtual methods, specially when you can't tell the origin of every single wrapped C++ object. In summary: don't do it! .. _pyside-old-style-class: Python old style classes and PySide =================================== Because of some architectural decisions and deprecated Python types. Since PySide 1.1 old style classes are not supported with multiple inheritance. Below you can check the examples: Example with old style class: .. code-block:: python from PySide6 import QtCore class MyOldStyleObject: pass class MyObject(QtCore, MyOldStyleObject): pass this example will raise a 'TypeError' due to the limitation on PySide, to fix this you will need use the new style class: .. code-block:: python from PySide6 import QtCore class MyOldStyleObject(object): pass class MyObject(QtCore, MyOldStyleObject): pass All classes used for multiple inheritance with other PySide types need to have 'object' as base class. ************************** Frequently Asked Questions ************************** This is a list of Frequently Asked Questions about |project|. Feel free to suggest new entries using our `Mailing list`_ or our IRC channel! General ======= What is Shiboken? ----------------- Shiboken is a Generator Runner plugin that outputs C++ code for CPython extensions. The first version of PySide had source code based on Boost templates. It was easier to produce code but a paradigm change was needed, as the next question explains. Why did you switch from Boost.Python to Shiboken? ------------------------------------------------- The main reason was the size reduction. Boost.Python makes excessive use of templates resulting in a significant increase of the binaries size. On the other hand, as Shiboken generates CPython code, the resulting binaries are smaller. Creating bindings ================= Can I wrap non-Qt libraries? ---------------------------- Yes. Check Shiboken source code for an example (libsample). Is there any runtime dependency on the generated binding? --------------------------------------------------------- Yes. Only libshiboken, and the obvious Python interpreter and the C++ library that is being wrapped. What do I have to do to create my bindings? ------------------------------------------- Most of the work is already done by the API Extractor. The developer creates a :std:doc:`typesystem ` file with any customization wanted in the generated code, like removing classes or changing method signatures. The generator will output the *.h* and *.cpp* files with the CPython code that will wrap the target library for python. Is there any recommended build system? -------------------------------------- Both API Extractor and generator uses and recommends the CMake build system. Can I write closed-source bindings with the generator? ------------------------------------------------------ Yes, as long as you use a LGPL version of Qt, due to runtime requirements. What is 'inject code'? ---------------------- That's how we call customized code that will be *injected* into the generated at specific locations. They are specified inside the typesystem. .. _`Mailing list`: http://lists.qt-project.org/mailman/listinfo/pyside