Mercurial > pytave
changeset 423:6b9de18b4bdd
Eliminate remaining custom exception handling in favor of Octave errors
* oct-py-error.cc, oct-py-error.h (pytave::error_python_exception): New function
to generate an Octave error from an active Python error condition, based on
pytave::fetch_exception_message.
* oct-py-eval.cc (pytave::py_call_function, pytave::py_run_string_safe): Use it.
* oct-py-types.cc (pytave::make_py_dict): Likewise.
* oct-py-util.cc (pytave::py_objstore): Likewise.
* pycall.cc (Fpycall): Remove exception handling logic.
* pyeval.cc (Fpyeval): Likewise.
* pyexec.cc (Fpyexec): Likewise.
* exceptions.cc, exceptions.h: Delete.
* Makefile.am (COMMON_SOURCE_FILES, PYTAVE_HEADER_FILES): Remove them.
author | Mike Miller <mtmiller@octave.org> |
---|---|
date | Thu, 04 May 2017 21:15:07 -0700 |
parents | 8247f298fd16 |
children | 9b34c17cb0fb |
files | Makefile.am exceptions.cc exceptions.h oct-py-error.cc oct-py-error.h oct-py-eval.cc oct-py-types.cc oct-py-util.cc pycall.cc pyeval.cc pyexec.cc |
diffstat | 11 files changed, 70 insertions(+), 161 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.am Thu May 04 17:13:38 2017 -0700 +++ b/Makefile.am Thu May 04 21:15:07 2017 -0700 @@ -29,7 +29,6 @@ export INCFLAGS COMMON_SOURCE_FILES = \ - exceptions.cc \ oct-py-error.cc \ oct-py-eval.cc \ oct-py-init.cc \ @@ -66,7 +65,6 @@ PYTAVE_HEADER_FILES = \ config.h \ - exceptions.h \ oct-py-error.h \ oct-py-eval.h \ oct-py-init.h \
--- a/exceptions.cc Thu May 04 17:13:38 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - -Copyright (C) 2015-2016 Mike Miller -Copyright (C) 2008 David Grundberg, Håkan Fors Nilsson - -This file is part of Pytave. - -Pytave is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. - -Pytave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Pytave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#if defined (HAVE_CONFIG_H) -# include <config.h> -#endif - -#include "exceptions.h" -#include "oct-py-eval.h" -#include "oct-py-object.h" -#include "oct-py-types.h" - -namespace pytave -{ - std::string fetch_exception_message (void) - { - PyObject *ptype, *pvalue, *ptraceback; - PyErr_Fetch (&ptype, &pvalue, &ptraceback); - PyErr_NormalizeException (&ptype, &pvalue, &ptraceback); - - python_object args = PyTuple_Pack (2, ptype, pvalue); - python_object formatted_list = py_call_function - ("traceback.format_exception_only", args); - - std::string message; - - if (formatted_list && PyList_Check (formatted_list)) - { - int len = PyList_Size (formatted_list); - - for (int i = 0; i < len; i++) - message.append (extract_py_str (PyList_GetItem (formatted_list, i))); - } - else - { - PyErr_Restore (ptype, pvalue, ptraceback); - PyErr_Print (); - message = "exceptions.cc (pytave::fetch_exception_message): cannot call 'format_exceptions_only' for the traceback"; - } - - return message; - } -}
--- a/exceptions.h Thu May 04 17:13:38 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - -Copyright (C) 2015-2016 Mike Miller -Copyright (C) 2008 David Grundberg, Håkan Fors Nilsson - -This file is part of Pytave. - -Pytave is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. - -Pytave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Pytave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#if ! defined (pytave_exceptions_h) -#define pytave_exceptions_h - -#include <Python.h> -#include <string> - -namespace pytave -{ - class error_already_set - { - }; - - std::string fetch_exception_message (void); -} - -#endif
--- a/oct-py-error.cc Thu May 04 17:13:38 2017 -0700 +++ b/oct-py-error.cc Thu May 04 21:15:07 2017 -0700 @@ -24,9 +24,13 @@ # include <config.h> #endif +#include <Python.h> #include <octave/error.h> #include "oct-py-error.h" +#include "oct-py-eval.h" +#include "oct-py-object.h" +#include "oct-py-types.h" namespace pytave { @@ -45,4 +49,36 @@ must.c_str ()); } + void + error_python_exception () + { + const char *format_exception_only = "traceback.format_exception_only"; + + PyObject *ptype, *pvalue, *ptraceback; + PyErr_Fetch (&ptype, &pvalue, &ptraceback); + PyErr_NormalizeException (&ptype, &pvalue, &ptraceback); + + python_object args = PyTuple_Pack (2, ptype, pvalue); + python_object lines = py_call_function (format_exception_only, args); + + if (lines && PySequence_Check (lines)) + { + Py_ssize_t len = PySequence_Size (lines); + python_object last_line = PySequence_GetItem (lines, len - 1); + + std::string msg = extract_py_str (last_line); + if (msg.back () == '\n') + msg.resize (msg.size () - 1); + + error ("%s", msg.c_str ()); + } + else + { + PyErr_Restore (ptype, pvalue, ptraceback); + PyErr_Print (); + error ("runtime failed to get exception information from %s", + format_exception_only); + } + } + }
--- a/oct-py-error.h Thu May 04 17:13:38 2017 -0700 +++ b/oct-py-error.h Thu May 04 21:15:07 2017 -0700 @@ -43,6 +43,10 @@ const std::string& must) PYTAVE_ATTR_NORETURN; + void + error_python_exception () + PYTAVE_ATTR_NORETURN; + } #undef PYTAVE_ATTR_NORETURN
--- a/oct-py-eval.cc Thu May 04 17:13:38 2017 -0700 +++ b/oct-py-eval.cc Thu May 04 21:15:07 2017 -0700 @@ -29,7 +29,7 @@ #include <octave/ov.h> #include <octave/ovl.h> -#include "exceptions.h" +#include "oct-py-error.h" #include "oct-py-eval.h" #include "oct-py-object.h" #include "oct-py-util.h" @@ -84,7 +84,7 @@ { python_object retval = PyEval_CallObjectWithKeywords (callable, args, kwargs); if (! retval) - throw pytave::error_already_set (); + error_python_exception (); return retval.release (); } @@ -119,7 +119,7 @@ Py_DECREF (globals); if (! retval) - throw pytave::error_already_set (); + error_python_exception (); return retval.release (); }
--- a/oct-py-types.cc Thu May 04 17:13:38 2017 -0700 +++ b/oct-py-types.cc Thu May 04 21:15:07 2017 -0700 @@ -31,7 +31,6 @@ #include <octave/quit.h> #include <octave/ov-null-mat.h> -#include "exceptions.h" #include "oct-py-error.h" #include "oct-py-eval.h" #include "oct-py-object.h" @@ -361,7 +360,7 @@ PyObject *item = py_implicitly_convert_argument (map.contents (p)); if (PyDict_SetItem (dict, key, item) < 0) - throw pytave::error_already_set (); + error_python_exception (); } return dict;
--- a/oct-py-util.cc Thu May 04 17:13:38 2017 -0700 +++ b/oct-py-util.cc Thu May 04 21:15:07 2017 -0700 @@ -28,7 +28,7 @@ #include <octave/oct.h> #include <octave/parse.h> -#include "exceptions.h" +#include "oct-py-error.h" #include "oct-py-object.h" #include "oct-py-types.h" #include "oct-py-util.h" @@ -172,7 +172,7 @@ } if (! dict) - throw pytave::error_already_set (); + error_python_exception (); objstore = dict; }
--- a/pycall.cc Thu May 04 17:13:38 2017 -0700 +++ b/pycall.cc Thu May 04 21:15:07 2017 -0700 @@ -27,7 +27,6 @@ #include <Python.h> #include <octave/oct.h> -#include "exceptions.h" #include "oct-py-eval.h" #include "oct-py-init.h" #include "oct-py-object.h" @@ -89,35 +88,27 @@ pytave::py_init (); - try + pytave::python_object callable; + if (args(0).is_string ()) + { + callable = pytave::py_find_function (args(0).string_value ()); + if (! callable) + error ("pycall: no such Python function or callable: %s", + args(0).string_value ().c_str ()); + } + else { - pytave::python_object callable; - if (args(0).is_string ()) - { - callable = pytave::py_find_function (args(0).string_value ()); - if (! callable) - error ("pycall: no such Python function or callable: %s", - args(0).string_value ().c_str ()); - } - else - { - callable = pytave::pyobject_unwrap_object (args(0)); - if (! callable) - error("pycall: FUNC must be a valid Python reference"); - } + callable = pytave::pyobject_unwrap_object (args(0)); + if (! callable) + error("pycall: FUNC must be a valid Python reference"); + } - octave_value_list arglist = args.slice (1, nargin - 1); - pytave::python_object res = pytave::py_call_function (callable, arglist); + octave_value_list arglist = args.slice (1, nargin - 1); + pytave::python_object res = pytave::py_call_function (callable, arglist); - // Ensure reasonable "ans" behaviour, consistent with Python's "_". - if (nargout > 0 || ! res.is_none ()) - retval(0) = pytave::py_implicitly_convert_return_value (res); - } - catch (pytave::error_already_set const &) - { - std::string message = pytave::fetch_exception_message (); - error ("pycall: %s", message.c_str ()); - } + // Ensure reasonable "ans" behaviour, consistent with Python's "_". + if (nargout > 0 || ! res.is_none ()) + retval(0) = pytave::py_implicitly_convert_return_value (res); return retval; }
--- a/pyeval.cc Thu May 04 17:13:38 2017 -0700 +++ b/pyeval.cc Thu May 04 21:15:07 2017 -0700 @@ -27,7 +27,6 @@ #include <Python.h> #include <octave/oct.h> -#include "exceptions.h" #include "oct-py-eval.h" #include "oct-py-init.h" #include "oct-py-object.h" @@ -81,18 +80,10 @@ error ("pyeval: NAMESPACE must be a valid Python reference"); } - try - { - pytave::python_object res = pytave::py_eval_string (code, 0, local_namespace); + pytave::python_object res = pytave::py_eval_string (code, 0, local_namespace); - if (nargout > 0 || ! res.is_none ()) - retval(0) = pytave::py_implicitly_convert_return_value (res); - } - catch (pytave::error_already_set const &) - { - std::string message = pytave::fetch_exception_message (); - error ("pyeval: %s", message.c_str ()); - } + if (nargout > 0 || ! res.is_none ()) + retval(0) = pytave::py_implicitly_convert_return_value (res); return retval; }
--- a/pyexec.cc Thu May 04 17:13:38 2017 -0700 +++ b/pyexec.cc Thu May 04 21:15:07 2017 -0700 @@ -27,7 +27,6 @@ #include <Python.h> #include <octave/oct.h> -#include "exceptions.h" #include "oct-py-eval.h" #include "oct-py-init.h" #include "oct-py-util.h" @@ -74,16 +73,9 @@ error ("pyexec: NAMESPACE must be a valid Python reference"); } - try - { - // FIXME: figure out exec return code: - pytave::py_exec_string (code, 0, local_namespace); - } - catch (pytave::error_already_set const &) - { - std::string message = pytave::fetch_exception_message (); - error ("pyexec: %s", message.c_str ()); - } + // FIXME: figure out exec return code: + pytave::py_exec_string (code, 0, local_namespace); + return retval; }