Mercurial > pytave
diff oct-py-types.cc @ 422:8247f298fd16
Raise Octave errors instead of exceptions for conversion errors
* Makefile.am (COMMON_SOURCE_FILES): Include oct-py-error.cc in the list.
(PYTAVE_HEADER_FILES): Include oct-py-error.h in the list.
* oct-py-error.cc, oct-py-error.h: New files defining error conditions.
* oct-py-types.cc (pytave::extract_py_bool, pytave::extract_py_complex,
pytave::extract_py_float, pytave::make_py_array, pytave::extract_py_scalar_map,
pytave::extract_py_int64, pytave::extract_py_uint64, pytave::extract_py_str):
Use new error condition functions instead of throwing exceptions.
(pytave::make_py_array, pytave::make_py_numeric_value, pytave::make_py_tuple):
Raise Octave error instead of throwing exceptions.
* __py_struct_from_dict__.cc (F__py_int64_scalar_value__,
F__py_uint64_scalar_value__): Remove exception handling logic.
* pycall.cc (Fpycall): Remove conversion exception handlers.
* pyeval.cc (Fpyeval): Likewise.
* pyexec.cc (Fpyexec): Likewise.
* exceptions.h (pytave::pytave_exception, pytave::octave_error_exception,
pytave::octave_parse_exception, pytave::value_convert_exception,
pytave::object_convert_exception, pytave::variable_name_exception): Delete
no longer used exception types.
author | Mike Miller <mtmiller@octave.org> |
---|---|
date | Thu, 04 May 2017 17:13:38 -0700 |
parents | 24555fba9964 |
children | 6b9de18b4bdd |
line wrap: on
line diff
--- a/oct-py-types.cc Thu May 04 13:22:20 2017 -0700 +++ b/oct-py-types.cc Thu May 04 17:13:38 2017 -0700 @@ -32,6 +32,7 @@ #include <octave/ov-null-mat.h> #include "exceptions.h" +#include "oct-py-error.h" #include "oct-py-eval.h" #include "oct-py-object.h" #include "oct-py-types.h" @@ -65,10 +66,10 @@ extract_py_bool (PyObject *obj) { if (! obj) - throw object_convert_exception ("failed to extract boolean: null object"); + error_conversion_invalid_python_object ("a boolean value"); if (! PyBool_Check (obj)) - throw object_convert_exception ("failed to extract boolean: wrong type"); + error_conversion_mismatch_python_type ("a boolean value", "bool"); return (obj == Py_True); } @@ -77,10 +78,10 @@ extract_py_complex (PyObject *obj) { if (! obj) - throw object_convert_exception ("failed to extract complex: null object"); + error_conversion_invalid_python_object ("a complex value"); if (! PyComplex_Check (obj)) - throw object_convert_exception ("failed to extract complex: wrong type"); + error_conversion_mismatch_python_type ("a complex value", "complex"); Py_complex value = PyComplex_AsCComplex (obj); return std::complex<double> {value.real, value.imag}; @@ -90,10 +91,10 @@ extract_py_float (PyObject *obj) { if (! obj) - throw object_convert_exception ("failed to extract float: null object"); + error_conversion_invalid_python_object ("a floating point value"); if (! PyFloat_Check (obj)) - throw object_convert_exception ("failed to extract float: wrong type"); + error_conversion_mismatch_python_type ("a floating point value", "float"); return PyFloat_AsDouble (obj); } @@ -138,8 +139,7 @@ make_py_array (const void *data, size_t len, char typecode) { if (! typecode) - throw object_convert_exception - ("unable to create array from Octave data"); + error ("unable to create array, invalid array type code"); std::string arg { typecode }; python_object array = py_call_function ("array.array", ovl (arg)); @@ -242,81 +242,88 @@ PyObject * make_py_numeric_value (const octave_value& value) { - if (value.is_scalar_type ()) - { - if (value.is_bool_type ()) - return make_py_bool (value.bool_value ()); + if (! value.is_scalar_type ()) + error ("unable to convert non-scalar type \"%s\" to a Python number", + value.type_name ().c_str ()); + + if (value.is_bool_type ()) + return make_py_bool (value.bool_value ()); - else if (value.is_int8_type ()) - return make_py_int (value.int8_scalar_value ().value ()); - else if (value.is_int16_type ()) - return make_py_int (value.int16_scalar_value ().value ()); - else if (value.is_int32_type ()) - return make_py_int (value.int32_scalar_value ().value ()); - else if (value.is_int64_type ()) - return make_py_int (value.int64_scalar_value ().value ()); + else if (value.is_int8_type ()) + return make_py_int (value.int8_scalar_value ().value ()); + else if (value.is_int16_type ()) + return make_py_int (value.int16_scalar_value ().value ()); + else if (value.is_int32_type ()) + return make_py_int (value.int32_scalar_value ().value ()); + else if (value.is_int64_type ()) + return make_py_int (value.int64_scalar_value ().value ()); - else if (value.is_uint8_type ()) - return make_py_int (value.uint8_scalar_value ().value ()); - else if (value.is_uint16_type ()) - return make_py_int (value.uint16_scalar_value ().value ()); - else if (value.is_uint32_type ()) - return make_py_int (value.uint32_scalar_value ().value ()); - else if (value.is_uint64_type ()) - return make_py_int (value.uint64_scalar_value ().value ()); + else if (value.is_uint8_type ()) + return make_py_int (value.uint8_scalar_value ().value ()); + else if (value.is_uint16_type ()) + return make_py_int (value.uint16_scalar_value ().value ()); + else if (value.is_uint32_type ()) + return make_py_int (value.uint32_scalar_value ().value ()); + else if (value.is_uint64_type ()) + return make_py_int (value.uint64_scalar_value ().value ()); - else if (value.is_complex_type ()) - return make_py_complex (value.complex_value ()); - else if (value.is_float_type ()) - return make_py_float (value.double_value ()); - } + else if (value.is_complex_type ()) + return make_py_complex (value.complex_value ()); + else if (value.is_float_type ()) + return make_py_float (value.double_value ()); + else + error ("unable to convert unhandled scalar type \"%s\" to a " + "Python number", value.type_name ().c_str ()); - throw value_convert_exception ("unhandled scalar type"); - return 0; + return nullptr; } PyObject * make_py_array (const octave_value& value) { - if (value.is_numeric_type () && ! value.is_complex_type () - && value.ndims () == 2 && (value.columns () <= 1 || value.rows () <= 1)) - { - if (value.is_double_type ()) - return make_py_array (value.array_value ()); - else if (value.is_single_type ()) - return make_py_array (value.float_array_value ()); + if (! (value.is_numeric_type () && ! value.is_complex_type () + && value.ndims () == 2 + && (value.columns () <= 1 || value.rows () <= 1))) + error ("unable to convert non-vector type \"%s\" to a Python array", + value.type_name ().c_str ()); + + if (value.is_double_type ()) + return make_py_array (value.array_value ()); + else if (value.is_single_type ()) + return make_py_array (value.float_array_value ()); - else if (value.is_int8_type ()) - return make_py_array (value.int8_array_value ()); - else if (value.is_int16_type ()) - return make_py_array (value.int16_array_value ()); - else if (value.is_int32_type ()) - return make_py_array (value.int32_array_value ()); - else if (value.is_int64_type ()) - return make_py_array (value.int64_array_value ()); + else if (value.is_int8_type ()) + return make_py_array (value.int8_array_value ()); + else if (value.is_int16_type ()) + return make_py_array (value.int16_array_value ()); + else if (value.is_int32_type ()) + return make_py_array (value.int32_array_value ()); + else if (value.is_int64_type ()) + return make_py_array (value.int64_array_value ()); - else if (value.is_uint8_type ()) - return make_py_array (value.uint8_array_value ()); - else if (value.is_uint16_type ()) - return make_py_array (value.uint16_array_value ()); - else if (value.is_uint32_type ()) - return make_py_array (value.uint32_array_value ()); - else if (value.is_uint64_type ()) - return make_py_array (value.uint64_array_value ()); - } + else if (value.is_uint8_type ()) + return make_py_array (value.uint8_array_value ()); + else if (value.is_uint16_type ()) + return make_py_array (value.uint16_array_value ()); + else if (value.is_uint32_type ()) + return make_py_array (value.uint32_array_value ()); + else if (value.is_uint64_type ()) + return make_py_array (value.uint64_array_value ()); + else + error ("unable to convert unhandled vector type \"%s\" to a " + "Python array", value.type_name ().c_str ()); - throw value_convert_exception ("unhandled Octave numeric vector type"); - return 0; + return nullptr; } octave_scalar_map extract_py_scalar_map (PyObject *obj) { if (! obj) - error ("unable to convert to an Octave struct, invalid Python object"); + error_conversion_invalid_python_object ("an Octave struct"); if (! PyDict_Check (obj)) - error ("unable to convert to an Octave struct, must be a Python dict"); + error_conversion_mismatch_python_type ("an Octave struct", "dict"); octave_scalar_map map; @@ -364,7 +371,7 @@ extract_py_int64 (PyObject *obj) { if (! obj) - throw object_convert_exception ("failed to extract integer: null object"); + error_conversion_invalid_python_object ("a signed integer value"); if (PyLong_Check (obj)) { @@ -388,7 +395,8 @@ return PyInt_AsLong (obj); #endif else - throw object_convert_exception ("failed to extract integer: wrong type"); + error_conversion_mismatch_python_type ("a signed integer value", + "int or long"); return 0; } @@ -397,7 +405,7 @@ extract_py_uint64 (PyObject *obj) { if (! obj) - throw object_convert_exception ("failed to extract integer: null object"); + error_conversion_invalid_python_object ("an unsigned integer value"); if (PyLong_Check (obj)) { @@ -425,7 +433,8 @@ return static_cast<uint64_t> (PyInt_AsLong (obj)); #endif else - throw object_convert_exception ("failed to extract integer: wrong type"); + error_conversion_mismatch_python_type ("an unsigned integer value", + "int or long"); return 0; } @@ -434,8 +443,7 @@ make_py_tuple (const Cell& cell) { if (! (cell.is_empty () || cell.is_vector ())) - throw value_convert_exception ( - "unable to convert multidimensional cell array into Python tuple"); + error ("unable to convert multidimensional cell array to a Python tuple"); octave_idx_type size = cell.numel (); PyObject *tuple = PyTuple_New (size); @@ -457,7 +465,8 @@ std::string retval; if (! obj) - throw object_convert_exception ("failed to extract string: null object"); + error_conversion_invalid_python_object ("a string value"); + if (PyBytes_Check (obj)) { retval.assign (PyBytes_AsString (obj), PyBytes_Size (obj)); @@ -468,11 +477,10 @@ if (enc && PyBytes_Check (enc)) retval.assign (PyBytes_AsString (enc), PyBytes_Size (enc)); else - throw object_convert_exception - ("failed to extract string: UTF-8 error"); + octave_throw_bad_alloc (); } else - throw object_convert_exception ("failed to extract string: wrong type"); + error_conversion_mismatch_python_type ("a string value", "str"); return retval; }