diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-22 17:50:30 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-22 17:50:30 +0200 |
commit | 170d47f92d03b81e74e8623cf15db9282957452d (patch) | |
tree | 3da6eb4446b42619c21a4ed591988529b75b1a3e /sources/shiboken2/doc/wordsofadvice.rst | |
parent | 6c018822ba40cc0a4427bd3f9ab8c96829c207df (diff) |
move everying into sources/shiboken2
in preparation for a subtree merge.
this should not be necessary to do in a separate commit, but git is a
tad stupid about following history correctly without it.
Diffstat (limited to 'sources/shiboken2/doc/wordsofadvice.rst')
-rw-r--r-- | sources/shiboken2/doc/wordsofadvice.rst | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/sources/shiboken2/doc/wordsofadvice.rst b/sources/shiboken2/doc/wordsofadvice.rst new file mode 100644 index 000000000..b66799338 --- /dev/null +++ b/sources/shiboken2/doc/wordsofadvice.rst @@ -0,0 +1,109 @@ +.. _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 PySide2 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 PySide2 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. |