Quantcast

how to raise exceptions when returning std::shared_ptr?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

how to raise exceptions when returning std::shared_ptr?

Burlen Loring-2
I'm having an issue when I'm trying to raise an exception inside a swig wrapped function. I think that this is because Python requires you to return a NULL to indicate an exception, but for functions returning std::shared_ptr SWIG always returns an object.

here is my source. when it fails, it sets an error string and returns nullptr.
  8215 p_teca_table as_teca_table(p_teca_dataset in_inst)                                                                                                                                        
  8216 {
  8217     p_teca_table o_inst = std::dynamic_pointer_cast<teca_table>(in_inst);
  8218     if (!o_inst)
  8219     {
  8220         teca_py_gil_state gil;
  8221         PyErr_Format(PyExc_TypeError,
  8222             "Failed to convert from \"%s\" to \"%s\"", #teca_dataset, #teca_table);
  8223     }
  8224     return o_inst;
  8225 }
and here is resulting swig generated wrapping:
 63068 SWIGINTERN PyObject *_wrap_as_teca_table(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
 63069   PyObject *resultobj = 0;
 63070   p_teca_dataset arg1 ;
 63071   void *argp1 ;
 63072   int res1 = 0 ;
 63073   PyObject * obj0 = 0 ;
 63074   p_teca_table result;
 63075
 63076   if (!PyArg_ParseTuple(args,(char *)"O:as_teca_table",&obj0)) SWIG_fail;
 63077   {
 63078     int newmem = 0;
 63079     res1 = SWIG_ConvertPtrAndOwn(obj0, &argp1, SWIGTYPE_p_std__shared_ptrT_teca_dataset_t,  0 , &newmem);
 63080     if (!SWIG_IsOK(res1)) {
 63081       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "as_teca_table" "', argument " "1"" of type '" "p_teca_dataset""'");
 63082     }
 63083     if (argp1) arg1 = *(reinterpret_cast< p_teca_dataset * >(argp1));
 63084     if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< p_teca_dataset * >(argp1);
 63085   }
 63086   {
 63087     SWIG_PYTHON_THREAD_BEGIN_ALLOW;
 63088     result = as_teca_table(arg1);
 63089     SWIG_PYTHON_THREAD_END_ALLOW;
 63090   }
 63091   {
 63092     std::shared_ptr<  teca_table > *smartresult = result ? new std::shared_ptr<  teca_table >(result) : 0;
 63093     resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_teca_table_t, SWIG_POINTER_OWN);
 63094   }
 63095   return resultobj;
 63096 fail:
 63097   return NULL;
 63098 }
on line 63093, SWIG constructs an object. This prevents Python interpreter from noticing the error.

Here is an example where I set up an exception handler and intentionally use the above to trigger the exception, but the exception never occurs. Very confusingly the error is only reported by a later Python call! or if in an interactive interpreter session if I hit enter.
Python 2.7.12 (default, Sep 27 2016, 11:20:58)
[GCC 5.3.1 20160406 (Red Hat 5.3.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from teca import *
>>> import sys
>>> def convert(ds):
...     try:
...             tab = as_teca_table(ds)
...     except:
...             sys.stderr.write('caught the exception!')
...     return tab
...
>>> ds = teca_cartesian_mesh.New()
>>> a = convert(ds)
>>>
then if I hit enter I get the error report printed in the terminal, but still no exception
TypeError: Failed to convert from "teca_dataset" to "teca_table"
>>>
I think that Python is not recognizing the exception occurred because the swig generated code never returns a NULL.

My question is: shouldn't the swig wrapper return NULL if the smart pointer points to a nullptr?
if not then the question is how does one raise an exception in functions that return std::shared_ptr?

Thanks!
Burlen

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: how to raise exceptions when returning std::shared_ptr?

Cherry, Josh (NIH/NLM/NCBI) [E]

> I'm having an issue when I'm trying to raise an exception inside a swig wrapped
> function. I think that this is because Python requires you to return a NULL to indicate
> an exception, but for functions returning std::shared_ptr SWIG always returns an object.

Rather than generating the Python exception in your wrapped function, you probably want to use %exception to make the wrapper do it.  See http://www.swig.org/Doc3.0/Python.html#Python_nn44 .

Josh



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user
Loading...