Setting throw annotation when there are not throw specification in source code

Asked by Kirill Lapshin

Hi,

I've used Py++ on previous project, which worked out Ok, but was a bit dissapointed with size of resulting compiled binding as well as compile time. I'm quite thrilled with possibility to avoid these problems with PyBindGen + (py)gccxml, however struggling a bit at the moment.

One of the problems I have is that exception translation works fine if there is an exception specification in C++ header, however when there is no specification, then exception is not translated, not caught and ultimately ends up in terminate()! I understand that if it is not known what exception types can be thrown out of a function it is not easy to translate them, however would expect at least std::exception being handled in this case. Anyways, I tried to add pre_scan_hook to add 'throw' annotation like this:

        if isinstance(pygccxml_definition, member_function_t) \
                or isinstance( pygccxml_definition, free_function_t):
            global_annotations['throw'] = exc

where exc is defined right after call to parse_init in a following way:

        exc = module_parser.module.add_exception('exception', foreign_cpp_namespace='std', message_rvalue='%(EXC)s.what()')

This however had no effect -- I've got a warning during generation, and exception still not translated. The warning reads like this:

Another thing I've tried is hacking gccxmlparser.py by adding right before clause where this warning raised (line 1703):

                    elif key == 'throw':
                        kwargs['throw'] = val

With this hack a generated code fails to compile with "error: ‘retval’ was not declared in this scope"

Is there any way to enable exception translation without adding exception specification to source code?

Another problem I'm facing is support for boost::shared_ptr. I've seen another question where a partial solution involving object copying is introduced. Unfortunately it is not an option for me, even if I was willing to sacrifice performance, as many classes are noncopyable by design (copy ctor is private). I'm willing to try to implement it myself (and contribute patch) if it is not too difficult. Would you be able to provide some guidance? I see two ways -- hacking it in by somehow gaining access to boost::shared_ptr counter (not nice and may break in future if shared_ptr redesigned), or ideally make Python object hold a reference to C++ object via shared_ptr, not raw pointer as I believe current implementation does. Not sure how much of a redesign is required to implement it properly.

Kind regards,

Kirill Lapshin

Question information

Language:
English Edit question
Status:
Answered
For:
PyBindGen Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Kirill Lapshin (kirill-lapshin) said :
#1

Ops, forgot to attach a warning in previous post. Here it is:

AnnotationsWarning: Annotation 'throw=[<pybindgen.CppException 'std::exception'>]' not used (used in ::foo::bar() [member function])

Revision history for this message
Gustavo Carneiro (gjc) said :
#2

The 'throw' annotation that you expect to use is not implemented. Feel free to open a bug report.

To work around, you could iterate over all functions and all methods and add it: just set then 'throw' attribute of funtion/method wrappers to a list of CppException objects. To do this, you can override the main function of the generated script by importing the script as module, copy-paste main, and modify it to call the imported module functions (add_classes, add_methods, etc.).

Regarding the other question, indeed, I think with intrusive_ptr it can be done already (ns-3 uses something like that), but shared_ptr is another matter. You'd have to 'steal' the pointer away from shared_ptr for it to work.

To make pybindgen work with shared_ptr internally, we'd have to start by modify the python instance structure in CppClass.generate_forward_declarations, to make shared_ptr<Foo> obj, instead of "Foo* obj". Then, who knows what else is needed to make it work. I guess we'd have to try and see what happens :-P

Revision history for this message
Kirill Lapshin (kirill-lapshin) said :
#3

Thanks a lot for quick response, Gustavo. Generating script and tweaking it sounds like a good option, I'll give it a go. I'll open few bug reports to track what we've discussed, feel free to close them if they are not aligned with project goals.

Can you help with this problem?

Provide an answer of your own, or ask Kirill Lapshin for more information if necessary.

To post a message you must log in.