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.

@@ -3818,6 +3819,13 @@ PyExc_ZeroDivisionError
+

+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