How to handle argument error exceptions in boost.python?
[I posted this on StackOverflow yesterday, but got nothing. Hoping you will have some insight!] I'm writing a C++ python extension. I have a boost::python extension function static void EXTrender_effect(EffectGlobals_t *effect_handle, std::string preset, bp::object dest, int xdim, int ydim) { ... } that I export as usual in my boost.python extension: def("render_effect", EXTrender_effect); When I call that from python(2.7), I get a C++ exception boost::python::error_already_set. Tracing that down in Visual Studio, I can see it's coming from a boost::python::objects::function::argument_error. So OK, I have an argument error; I'm probably calling it with the wrong args. What I'd like to do is print or throw something sensible in my python extension when this happens, so users of my extension will see the nice message that I know is lurking in PyErr_Fetch. (I can see the message getting built in the boost.python argument_error code.) But I can't catch that error_already_set; boost.python does that internally around the funcall. And I can't check for python errors in my extension code, since my function never gets called (the argument error is detected by boost.python). What ends up happening is it just silently fails. What can I hook up so I (or my users) can see the argument error messages? And ideally convert those into python exceptions? This is all Win7, Python2.7. -- . . . . . . . . . . . . . . . . . . . . . . Gary Oberbrunner garyo@genarts.com VP Engineering Tel: 617-492-2888 GenArts, Inc. www.genarts.com
Dear Gary, I am not sure if this is what you want, but what about writing a wrapper function around EXTrender_effect which takes boost::python::objects and then use boost::python::extract to check if you can convert the objects you got to what they should be (cf. https://wiki.python.org/moin/boost.python/extract)? Does this help? Regards, Charly ----- Original Message ----- From: "Gary Oberbrunner" <garyo@genarts.com> To: "Development of Python/C++ integration" <cplusplus-sig@python.org> Sent: Friday, January 10, 2014 2:16:16 PM Subject: [C++-sig] How to handle argument error exceptions in boost.python? [I posted this on StackOverflow yesterday, but got nothing. Hoping you will have some insight!] I'm writing a C++ python extension. I have a boost::python extension function static void EXTrender_effect(EffectGlobals_t *effect_handle, std::string preset, bp::object dest, int xdim, int ydim) { ... } that I export as usual in my boost.python extension: def("render_effect", EXTrender_effect); When I call that from python(2.7), I get a C++ exception boost::python::error_already_set. Tracing that down in Visual Studio, I can see it's coming from a boost::python::objects::function::argument_error. So OK, I have an argument error; I'm probably calling it with the wrong args. What I'd like to do is print or throw something sensible in my python extension when this happens, so users of my extension will see the nice message that I know is lurking in PyErr_Fetch. (I can see the message getting built in the boost.python argument_error code.) But I can't catch that error_already_set; boost.python does that internally around the funcall. And I can't check for python errors in my extension code, since my function never gets called (the argument error is detected by boost.python). What ends up happening is it just silently fails. What can I hook up so I (or my users) can see the argument error messages? And ideally convert those into python exceptions? This is all Win7, Python2.7. -- . . . . . . . . . . . . . . . . . . . . . . Gary Oberbrunner garyo@genarts.com VP Engineering Tel: 617-492-2888 GenArts, Inc. www.genarts.com _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org https://mail.python.org/mailman/listinfo/cplusplus-sig
----- Original Message -----
From: "Karl Bicker" <karl.bicker@gordiano.net> To: "Development of Python/C++ integration" <cplusplus-sig@python.org> Sent: Friday, January 10, 2014 8:36:48 AM Subject: Re: [C++-sig] How to handle argument error exceptions in boost.python?
Dear Gary,
I am not sure if this is what you want, but what about writing a wrapper function around EXTrender_effect which takes boost::python::objects and then use boost::python::extract to check if you can convert the objects you got to what they should be (cf. https://wiki.python.org/moin/boost.python/extract)? Does this help?
I suppose it might -- essentially what you're talking about is avoiding boost::python's overloading logic and putting in my own. Then I could handle arg errors any way I want, because my function would be guaranteed to be called no matter what. Right? It seems like a bad solution overall though, because it means most of the coolness of boost::python is gone. All my functions would just have to take a list of kw args and parse them out themselves, rather than boost::python doing that. Seems like there must be a better way! I mean, there is all this logic in the boost::python call framework to build nice error messages about which overloads were tried, but that message never comes out anywhere. -- Gary Oberbrunner
On 10/01/2014 14:16, Gary Oberbrunner wrote:
[I posted this on StackOverflow yesterday, but got nothing. Hoping you will have some insight!]
I'm writing a C++ python extension. I have a boost::python extension function
static void EXTrender_effect(EffectGlobals_t *effect_handle, std::string preset, bp::object dest, int xdim, int ydim) { ... } that I export as usual in my boost.python extension:
def("render_effect", EXTrender_effect);
When I call that from python(2.7), I get a C++ exception boost::python::error_already_set. Tracing that down in Visual Studio, I can see it's coming from a boost::python::objects::function::argument_error. So OK, I have an argument error; I'm probably calling it with the wrong args. What I'd like to do is print or throw something sensible in my python extension when this happens, so users of my extension will see the nice message that I know is lurking in PyErr_Fetch. (I can see the message getting built in the boost.python argument_error code.)
What is the exception you see from the python side? something like: ArgumentError: Python argument types in function_name(function_args) did not match C++ signature: cpp_function_name(cpp_args) -- Giuseppe Corbelli WASP Software Engineer, Copan Italia S.p.A Phone: +390303666318 Fax: +390302659932 E-mail: giuseppe.corbelli@copanitalia.com
----- Original Message -----
From: "Giuseppe Corbelli" <giuseppe.corbelli@copanitalia.com> ... What is the exception you see from the python side? something like:
ArgumentError: Python argument types in function_name(function_args) did not match C++ signature: cpp_function_name(cpp_args)
That's exactly what I'm trying to figure out! The c++ exception gets handled in handle_exception and it never gets turned into a python exception as far as I can tell. -- Gary Oberbrunner
On Tue, Jan 14, 2014 at 6:45 AM, Gary Oberbrunner <garyo@genarts.com> wrote:
----- Original Message -----
From: "Giuseppe Corbelli" <giuseppe.corbelli@copanitalia.com> ... What is the exception you see from the python side? something like:
ArgumentError: Python argument types in function_name(function_args) did not match C++ signature: cpp_function_name(cpp_args)
That's exactly what I'm trying to figure out! The c++ exception gets handled in handle_exception and it never gets turned into a python exception as far as I can tell.
My memory on this is a bit fuzzy, but I think it does get translated to a custom Boost.Python exception (it's either that or a built-in Python exception, which would make your task much more difficult, if not impossible). Unfortunately there's no clear-cut way to import that exception. You could try intentionally raising one in a Python try/except block when your module is imported, though, so you could store the exception type and reuse it later in subsequent try/except blocks. Jim
----- Original Message -----
From: "Jim Bosch" <talljimbo@gmail.com> ... My memory on this is a bit fuzzy, but I think it does get translated to a custom Boost.Python exception (it's either that or a built-in Python exception, which would make your task much more difficult, if not impossible). Unfortunately there's no clear-cut way to import that exception. You could try intentionally raising one in a Python try/except block when your module is imported, though, so you could store the exception type and reuse it later in subsequent try/except blocks.
Thanks Jim; if that's happening, something on the python side must be eating that exception, because I don't see it there. Still, this is a complex piece of code so it's entirely possible it is being swallowed on the python side. I'll continue to track it down based on that theory. -- Gary Oberbrunner
On 14/01/2014 12:45, Gary Oberbrunner wrote:
...
What is the exception you see from the python side? something like:
ArgumentError: Python argument types in function_name(function_args) did not match C++ signature: cpp_function_name(cpp_args)
That's exactly what I'm trying to figure out! The c++ exception gets handled in handle_exception and it never gets turned into a python exception as far as I can tell.
So, what you see in the python side? And what boost version? I've always seen an ArgumentError being raised when passing wrong argument types to the C++ code object and ValueError (I think) when the C++ code object raises an exception without a specific C++ to python exception translator installed. -- Giuseppe Corbelli WASP Software Engineer, Copan Italia S.p.A Phone: +390303666318 Fax: +390302659932 E-mail: giuseppe.corbelli@copanitalia.com
participants (4)
-
Gary Oberbrunner -
Giuseppe Corbelli -
Jim Bosch -
Karl Bicker