Boost.Python has a limitation: it does not allow to create class, which derives from the class defined in Python. In most use cases this should not bother you, except one - exceptions. The example will provide you with one of the possible solutions.
It is all about module interface and user expectations. If you can translate all your exceptions to built-in ones, than you are fine. You don’t have to read this guide, but Boost.Python exception translator documentation.
My use case was different. I was supposed to export the exception classes and make them play nice with the try ... except mechanism. I mean, users should be able to:
- “except” all exceptions using except Exception, err: statement
- “except” the exposed library defined exception classes
I thought about few possible solutions to the problem. My first attempt was to add a missing functionality to Boost.Python library. Well, I quickly found out that the task is not a trivial one.
The following solution, I thought about, was to expose the exception class as-is and to define new class in Python, which derives from it and the built-in Exception. I implemented it and when I run the code I’ve got TypeError: “Error when calling the metaclass bases multiple bases have instance lay-out conflict”.
The only solution left was to use “aggregation with automatic delegation”. I mean instead of deriving from the exception class, I will keep it as a member variable in a class defined in Python, which derives from the built-in Exception one. Every time user access an attribute, the class defined in Python will automatically redirect the request to the variable. This technique is explained much better here: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52295 .
All files contain comments, which describe what and why was done.