diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index cf0f86024..ebcf8bbc9 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -3717,7 +3717,7 @@ or a NULL pointer perhaps). Here is a simple example of how you might handle th $action if (!result) { PyErr_SetString(PyExc_MemoryError,"Not enough memory"); - return NULL; + SWIG_fail; } } void *malloc(size_t nbytes); @@ -3749,7 +3749,7 @@ that. For example: $action if (err_occurred()) { PyErr_SetString(PyExc_RuntimeError, err_message()); - return NULL; + SWIG_fail; } } @@ -3770,7 +3770,7 @@ C++ exceptions are also easy to handle. For example, you can write code like th $action } catch (std::out_of_range &e) { PyErr_SetString(PyExc_IndexError, const_cast<char*>(e.what())); - return NULL; + SWIG_fail; } } @@ -3784,7 +3784,8 @@ public:
When raising a Python exception from C, use the PyErr_SetString() -function as shown above. The following exception types can be used as the first argument. +function as shown above followed by SWIG_fail. +The following exception types can be used as the first argument.
+SWIG_fail is a C macro which when called within the context of SWIG wrapper function, +will jump to the error handler code. This will call any cleanup code (freeing any temp variables) +and then return from the wrapper function so that the Python interpreter can raise the Python exception. +This macro should always be called after setting a Python error in code snippets, such as typemaps and %exception, that are ultimately generated into the wrapper function. +
+The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter. @@ -4417,7 +4425,7 @@ You can refine this by supplying an optional parameter name. For example: $1 = (int) PyLong_AsLong($input); if ($1 < 0) { PyErr_SetString(PyExc_ValueError,"Expected a nonnegative value."); - return NULL; + SWIG_fail; } } %inline %{ @@ -4750,18 +4758,18 @@ object to be used as a char ** object. $1 = (char **) malloc((size+1)*sizeof(char *)); for (i = 0; i < size; i++) { PyObject *o = PyList_GetItem($input,i); - if (PyString_Check(o)) + if (PyString_Check(o)) { $1[i] = PyString_AsString(PyList_GetItem($input,i)); - else { - PyErr_SetString(PyExc_TypeError,"list must contain strings"); + } else { free($1); - return NULL; + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + SWIG_fail; } } $1[i] = 0; } else { PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; + SWIG_fail; } } @@ -4849,18 +4857,18 @@ previous example: $2 = (char **) malloc(($1+1)*sizeof(char *)); for (i = 0; i < $1; i++) { PyObject *o = PyList_GetItem($input,i); - if (PyString_Check(o)) + if (PyString_Check(o)) { $2[i] = PyString_AsString(PyList_GetItem($input,i)); - else { - PyErr_SetString(PyExc_TypeError,"list must contain strings"); + } else { free($2); - return NULL; + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + SWIG_fail; } } $2[i] = 0; } else { PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; + SWIG_fail; } } @@ -5038,12 +5046,12 @@ This too, can be handled used typemaps as follows : if (PyTuple_Check($input)) { if (!PyArg_ParseTuple($input,"dddd",temp,temp+1,temp+2,temp+3)) { PyErr_SetString(PyExc_TypeError,"tuple must have 4 elements"); - return NULL; + SWIG_fail; } $1 = &temp[0]; } else { PyErr_SetString(PyExc_TypeError,"expected a tuple."); - return NULL; + SWIG_fail; } } @@ -5078,18 +5086,18 @@ arrays of different sizes. To do this, you might write a typemap as follows: int i; if (!PySequence_Check($input)) { PyErr_SetString(PyExc_TypeError,"Expecting a sequence"); - return NULL; + SWIG_fail; } if (PyObject_Length($input) != $1_dim0) { PyErr_SetString(PyExc_ValueError,"Expecting a sequence with $1_dim0 elements"); - return NULL; + SWIG_fail; } for (i =0; i < $1_dim0; i++) { PyObject *o = PySequence_GetItem($input,i); if (!PyFloat_Check(o)) { Py_XDECREF(o); PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats"); - return NULL; + SWIG_fail; } temp[i] = PyFloat_AsDouble(o); Py_DECREF(o); @@ -5146,7 +5154,7 @@ static int convert_darray(PyObject *input, double *ptr, int size) { %typemap(in) double [ANY](double temp[$1_dim0]) { if (!convert_darray($input,temp,$1_dim0)) { - return NULL; + SWIG_fail; } $1 = &temp[0]; } diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 309984b50..d7226e33f 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -373,11 +373,11 @@ example, you could write a typemap like this:
%typemap(in) double nonnegative {
- $1 = PyFloat_AsDouble($input);
- if ($1 < 0) {
- PyErr_SetString(PyExc_ValueError,"argument must be nonnegative.");
- return NULL;
- }
+ $1 = PyFloat_AsDouble($input);
+ if ($1 < 0) {
+ PyErr_SetString(PyExc_ValueError,"argument must be nonnegative.");
+ SWIG_fail;
+ }
}
...
@@ -2964,11 +2964,11 @@ similar to this:
int i;
if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_ValueError,"Expected a sequence");
- return NULL;
+ SWIG_fail;
}
if (PySequence_Length($input) != 4) {
PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected 4 elements");
- return NULL;
+ SWIG_fail;
}
for (i = 0; i < 4; i++) {
PyObject *o = PySequence_GetItem($input,i);
@@ -2976,7 +2976,7 @@ similar to this:
temp[i] = (float) PyFloat_AsDouble(o);
} else {
PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
- return NULL;
+ SWIG_fail;
}
}
$1 = temp;
@@ -3009,11 +3009,11 @@ If you wanted to generalize the typemap to apply to arrays of all dimensions you
int i;
if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_ValueError,"Expected a sequence");
- return NULL;
+ SWIG_fail;
}
if (PySequence_Length($input) != $1_dim0) {
PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements");
- return NULL;
+ SWIG_fail;
}
for (i = 0; i < $1_dim0; i++) {
PyObject *o = PySequence_GetItem($input,i);
@@ -3021,7 +3021,7 @@ If you wanted to generalize the typemap to apply to arrays of all dimensions you
temp[i] = (float) PyFloat_AsDouble(o);
} else {
PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
- return NULL;
+ SWIG_fail;
}
}
$1 = temp;
@@ -3053,11 +3053,11 @@ as shown. To work with heap allocated data, the following technique can be use
int i;
if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_ValueError,"Expected a sequence");
- return NULL;
+ SWIG_fail;
}
if (PySequence_Length($input) != $1_dim0) {
PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements");
- return NULL;
+ SWIG_fail;
}
$1 = (float *) malloc($1_dim0*sizeof(float));
for (i = 0; i < $1_dim0; i++) {
@@ -3065,9 +3065,9 @@ as shown. To work with heap allocated data, the following technique can be use
if (PyNumber_Check(o)) {
$1[i] = (float) PyFloat_AsDouble(o);
} else {
- PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
free($1);
- return NULL;
+ PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
+ SWIG_fail;
}
}
}
@@ -3229,7 +3229,7 @@ pointers. For example:
%typemap(check) Vector * {
if ($1 == 0) {
PyErr_SetString(PyExc_TypeError,"NULL Pointer not allowed");
- return NULL;
+ SWIG_fail;
}
}
@@ -3508,7 +3508,7 @@ maps perform the conversion described for the above example:
int i;
if (!PyList_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a list");
- return NULL;
+ SWIG_fail;
}
$1 = PyList_Size($input);
$2 = (char **) malloc(($1+1)*sizeof(char *));
@@ -3517,7 +3517,7 @@ maps perform the conversion described for the above example:
if (!PyString_Check(s)) {
free($2);
PyErr_SetString(PyExc_ValueError, "List items must be strings");
- return NULL;
+ SWIG_fail;
}
$2[i] = PyString_AsString(s);
}
@@ -3633,7 +3633,7 @@ might write typemaps like this:
%typemap(in) (void *wbuffer, size_t len) {
if (!PyString_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a string");
- return NULL;
+ SWIG_fail;
}
$1 = (void *) PyString_AsString($input);
$2 = PyString_Size($input);
@@ -3643,12 +3643,12 @@ might write typemaps like this:
%typemap(in) (void *rbuffer, size_t len) {
if (!PyInt_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting an integer");
- return NULL;
+ SWIG_fail;
}
$2 = PyInt_AsLong($input);
if ($2 < 0) {
PyErr_SetString(PyExc_ValueError, "Positive integer expected");
- return NULL;
+ SWIG_fail;
}
$1 = (void *) malloc($2);
}
diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
index 1c99804f1..21a41948e 100644
--- a/Doc/Manual/Varargs.html
+++ b/Doc/Manual/Varargs.html
@@ -517,7 +517,7 @@ like this:
argc = PyTuple_Size(varargs);
if (argc > 10) {
PyErr_SetString(PyExc_ValueError, "Too many arguments");
- return NULL;
+ SWIG_fail;
}
for (i = 0; i < argc; i++) {
PyObject *pyobj = PyTuple_GetItem(varargs, i);
@@ -526,7 +526,7 @@ like this:
PyObject *pystr;
if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
- return NULL;
+ SWIG_fail;
}
pystr = PyUnicode_AsUTF8String(pyobj);
str = strdup(PyBytes_AsString(pystr));
@@ -534,7 +534,7 @@ like this:
%#else
if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
- return NULL;
+ SWIG_fail;
}
str = PyString_AsString(pyobj);
%#endif
@@ -635,9 +635,9 @@ example. For example:
for (i = 0; i < argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (!PyString_Check(o)) {
- PyErr_SetString(PyExc_ValueError,"Expected a string");
free(argv);
- return NULL;
+ PyErr_SetString(PyExc_ValueError,"Expected a string");
+ SWIG_fail;
}
argv[i] = PyString_AsString(o);
}
@@ -676,11 +676,11 @@ example. For example:
&ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) execlp, &result, values);
} else {
- PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types);
free(values);
free(arg3);
- return NULL;
+ PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
+ SWIG_fail;
}
free(types);
free(values);
@@ -744,8 +744,8 @@ As a more extreme example of libffi, here is some code that attempts to wrap 10) {
PyErr_SetString(PyExc_ValueError, "Too many arguments");
- return NULL;
+ SWIG_fail;
}
for (i = 0; i < argc; i++) {
PyObject *pyobj = PyTuple_GetItem(varargs, i);
@@ -20,7 +20,7 @@
PyObject *pystr;
if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
- return NULL;
+ SWIG_fail;
}
pystr = PyUnicode_AsUTF8String(pyobj);
str = strdup(PyBytes_AsString(pystr));
@@ -28,7 +28,7 @@
%#else
if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
- return NULL;
+ SWIG_fail;
}
str = PyString_AsString(pyobj);
%#endif