New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix SWIG Python builtin custom exception #397
base: master
Are you sure you want to change the base?
Conversation
When builtin mode is enabled, triggering custom exception object didn't work and always lead to SWIG_RuntimeError exception. We can now enable the exception_order_runme test when using builtin.
@amaeldoe - did you see the Travis failures? Looks like Python 3.2 fails but 3.3 and 3.4 is okay. Do you know what is different for exception handling for the later versions? |
Apparently subclassing (which seems required for Py3 exception) does not work this way. I have no idea why, do you ?
|
We apparently need to find some way to derive custom exception object from PyExc_Exception. This could probably be done automatically when SWIG see that a given C++ class derive from std::exception. However I don't think I know the SWIG internal enough to tackle this issue. Is it something that you could do ? |
Have you seen the Builtin limitations section at http://swig.org/Doc3.0/Python.html#Python_builtin_limitations? Does deriving the Python class from PyExc_Exception (Python Exception class) result in the same? There is the 'exceptionclass' feature mentioned in the CHANGES file. Probably we should get this feature working for builtin classes. It looks like it only works for classic Python proxy classes right now though. Look for "feature:exceptionclass" in python.cxx. If it is merely a matter of adding in 'Exception' as one of the bases, it'll be easy to add this in. |
Yes, I did : this is a simple limitation, and the correct fix for this is indeed to make sure the generated exception classes wrappers derive from the PyExc_Exception PyTypeObject. However, my knowledge of SWIG internal is probably a bit limited to tackle this task. Would you be able to look into it ? |
I can do this, but have other priorities right now. If you make the changes to the generated code by hand and test it, then let me know exactly what needs changing in the generated code, I will code it up. I suggest posting a patch of the required changes to the generated code for say the Examples/python/class example. |
Examples/python/class doesn't do any exception handling, so here it is with Examples/python/exception: To me this is the primary change needed, and it should be done automatically if a classe derive from std::exception --- Examples/python/exception/example_wrap.cxx 2015-04-28 07:42:26.068165321 +0200 +++ example_wrap.cxx 2015-04-28 07:42:00.786117483 +0200 @@ -5425,7 +5425,7 @@ SwigPyBuiltin_SetMetaType(builtin_pytype, metatype); builtin_pytype->tp_new = PyType_GenericNew; builtin_base_count = 0; - builtin_bases[builtin_base_count] = NULL; + builtin_bases[builtin_base_count++] = (PyTypeObject *) PyExc_Exception; SwigPyBuiltin_InitBases(builtin_pytype, builtin_bases); PyDict_SetItemString(d, "this", this_descr); PyDict_SetItemString(d, "thisown", thisown_descr); |
The Python docs say that "All user-defined exceptions should also be derived from [class Exception]": https://docs.python.org/2/library/exceptions.html But in C++, deriving your exceptions from This ought to be hooked up to the existing Perhaps classes derived from |
Sorry, I meant to point you to the Examples/python/exceptproxy example as it is explicitly disabled for builtin. If I comment out:
then it works with your patch for Python 2, but am surprised as I havn't changed anything wrt deriving from PyExc_Exception. Using Python 3 and deriving from PyExc_Exception seg faults when run, so could take a look and let me know what patch to the generated code in the exceptproxy example is needed please. |
Agreed that %exceptionclass is needed to get this to work and it could be marked on std::exception if a user provides the declaration for std::exception as it should apply to all derived classes. |
Yes, I noticed the same problem when testing the patch more extensively. I unfortunatelly have no time to debug the issue right now, so if any of you can have a look, that would be welcome ! |
The patch here needs more work, but stalled in 2015 it seems because nobody knows how to make it work with newer Python 3.x. There's now issue #1572 tracking the issue this was trying to address, so closing this. |
I just happened upon this closed ticket while searching for something else entirely, and I notice I may have my conclusion wrong above having seemingly reversed the sense of what wsfulton actually said:
We've also since dropped support for Python 3.2 (in SWIG 4.1.0) so maybe this patch could now be merged. Hence reopening. |
I rebased and both the testcases pass, but there are still issues with the
With git master, the output is all on stdout and is:
Is this actually a problem with the example though? |
Sorry, I had lost the
I'm using Python 3.11.2. Looking at
I think I'm out of my depth at this point, but I'll tidy up my branch and push it shortly. I notice the text in the manual about this limitation makes it sound like the issue is a C/C++ struct layout incompatibility (and |
It occurred to me to try making The downside of this approach is that every In Python 3.3 (oldest we support now) the definition is:
In 3.11 (newest I have installed) it's grown by
So (allowing for removing our I suppose doing this could be conditional on However this change still doesn't seem to make it actually work... |
When builtin mode is enabled, triggering custom exception object didn't work
and always lead to SWIG_RuntimeError exception.
We can now enable the exception_order_runme test when using builtin.