# HG changeset patch # User Mike Miller # Date 1493421699 25200 # Node ID aef165ff92b0dd5ae2e20778961cbdb20e60cfad # Parent 3644df6564bc10aa4208f86ffd3bd3e8211a50ed Adopt pytave::python_object where objects are local or created and returned * __py_struct_from_dict__.cc, exceptions.cc, oct-py-eval.cc, oct-py-types.cc, pycall.cc: Use pytave::python_object in place of PyObject where objects are created locally and destroyed or returned to the caller. diff -r 3644df6564bc -r aef165ff92b0 __py_struct_from_dict__.cc --- a/__py_struct_from_dict__.cc Fri Apr 28 14:19:49 2017 -0700 +++ b/__py_struct_from_dict__.cc Fri Apr 28 16:21:39 2017 -0700 @@ -30,6 +30,7 @@ #define PYTAVE_DO_DECLARE_SYMBOL #include "arrayobjectdefs.h" #include "exceptions.h" +#include "oct-py-object.h" #include "oct-py-types.h" #include "oct-py-util.h" #include "octave_to_python.h" @@ -50,9 +51,8 @@ Py_Initialize (); - PyObject *obj = pytave::pyobject_unwrap_object (args(0)); + pytave::python_object obj = pytave::pyobject_unwrap_object (args(0)); std::string name = pytave::py_object_class_name (obj); - Py_DECREF (obj); return ovl (name); } @@ -89,7 +89,7 @@ Py_Initialize (); - PyObject *obj = pytave::pyobject_unwrap_object (args(0)); + pytave::python_object obj = pytave::pyobject_unwrap_object (args(0)); if (! obj) error ("pyobject.int64: argument must be a valid Python object"); @@ -108,7 +108,6 @@ std::string message = pytave::fetch_exception_message (); error ("pyobject.int64: %s", message.c_str ()); } - Py_DECREF (obj); return ovl (retval); } @@ -142,7 +141,7 @@ Py_Initialize (); - PyObject *obj = pytave::pyobject_unwrap_object (args(0)); + pytave::python_object obj = pytave::pyobject_unwrap_object (args(0)); if (! obj) error ("pyobject.uint64: argument must be a valid Python object"); @@ -161,7 +160,6 @@ std::string message = pytave::fetch_exception_message (); error ("pyobject.uint64: %s", message.c_str ()); } - Py_DECREF (obj); return ovl (retval); } @@ -191,12 +189,9 @@ Py_Initialize (); - PyObject *obj = pytave::pyobject_unwrap_object (args(0)); + pytave::python_object obj = pytave::pyobject_unwrap_object (args(0)); - bool retval = (obj && (obj == Py_None)); - Py_XDECREF (obj); - - return ovl (retval); + return ovl (obj.is_none ()); } /* @@ -250,9 +245,8 @@ pytave::octvalue_to_pyobj (arg, args(0)); PyObject *obj = arg.ptr (); - PyObject *type = pytave::py_find_type (typestr); + pytave::python_object type = pytave::py_find_type (typestr); retval(0) = pytave::py_isinstance (obj, type); - Py_XDECREF (type); } catch (pytave::object_convert_exception const &) { @@ -360,7 +354,7 @@ Py_Initialize (); - PyObject *obj = pytave::pyobject_unwrap_object (args(0)); + pytave::python_object obj = pytave::pyobject_unwrap_object (args(0)); if (! obj) error ("pyobject.char: argument must be a valid Python object"); @@ -370,17 +364,11 @@ str = pytave::extract_py_str (obj); else if (Py_TYPE (obj)->tp_str != nullptr) { - PyObject *s = PyObject_Str (obj); + pytave::python_object s = PyObject_Str (obj); str = pytave::extract_py_str (s); - Py_DECREF (s); } else - { - Py_DECREF (obj); - error ("pyobject.char: cannot convert Python object to string"); - } - - Py_DECREF (obj); + error ("pyobject.char: cannot convert Python object to string"); return ovl (str); } diff -r 3644df6564bc -r aef165ff92b0 exceptions.cc --- a/exceptions.cc Fri Apr 28 14:19:49 2017 -0700 +++ b/exceptions.cc Fri Apr 28 16:21:39 2017 -0700 @@ -27,6 +27,7 @@ #include "exceptions.h" #include "oct-py-eval.h" +#include "oct-py-object.h" #include "oct-py-types.h" namespace pytave @@ -37,12 +38,9 @@ PyErr_Fetch (&ptype, &pvalue, &ptraceback); PyErr_NormalizeException (&ptype, &pvalue, &ptraceback); - PyObject *args = PyTuple_New (2); - PyTuple_SetItem (args, 0, ptype); - PyTuple_SetItem (args, 1, pvalue); - PyObject *formatted_list = py_call_function - ("traceback.format_exception_only", args); - Py_DECREF (args); + python_object args = PyTuple_Pack (2, ptype, pvalue); + python_object formatted_list = py_call_function + ("traceback.format_exception_only", args); std::string message; @@ -52,7 +50,6 @@ for (int i = 0; i < len; i++) message.append (extract_py_str (PyList_GetItem (formatted_list, i))); - Py_DECREF (formatted_list); } else { diff -r 3644df6564bc -r aef165ff92b0 oct-py-eval.cc --- a/oct-py-eval.cc Fri Apr 28 14:19:49 2017 -0700 +++ b/oct-py-eval.cc Fri Apr 28 16:21:39 2017 -0700 @@ -30,6 +30,7 @@ #include #include "oct-py-eval.h" +#include "oct-py-object.h" #include "oct-py-util.h" #include "octave_to_python.h" @@ -39,26 +40,24 @@ PyObject * py_call_function (const std::string& func, const octave_value_list& args) { - PyObject *func_obj = py_find_function (func); - PyObject *retval = py_call_function (func_obj, args); - Py_DECREF (func_obj); - return retval; + python_object func_obj = py_find_function (func); + python_object retval = py_call_function (func_obj, args); + return retval.release (); } PyObject * py_call_function (const std::string& func, PyObject *args, PyObject *kwargs) { - PyObject *func_obj = py_find_function (func); - PyObject *retval = py_call_function (func_obj, args, kwargs); - Py_DECREF (func_obj); - return retval; + python_object func_obj = py_find_function (func); + python_object retval = py_call_function (func_obj, args, kwargs); + return retval.release (); } PyObject * py_call_function (PyObject *callable, const octave_value_list& args) { - PyObject *kwargs = nullptr; - PyObject *args_list = PyList_New (0); + python_object kwargs; + python_object args_list = PyList_New (0); if (! args_list) octave_throw_bad_alloc (); @@ -77,24 +76,21 @@ } } - PyObject *args_tuple = PyList_AsTuple (args_list); - Py_DECREF (args_list); + python_object args_tuple = PyList_AsTuple (args_list); - PyObject *retval = py_call_function (callable, args_tuple, kwargs); - Py_DECREF (args_tuple); - Py_XDECREF (kwargs); + python_object retval = py_call_function (callable, args_tuple, kwargs); - return retval; + return retval.release (); } PyObject * py_call_function (PyObject *callable, PyObject *args, PyObject *kwargs) { - PyObject *retval = PyEval_CallObjectWithKeywords (callable, args, kwargs); + python_object retval = PyEval_CallObjectWithKeywords (callable, args, kwargs); if (! retval) throw boost::python::error_already_set (); - return retval; + return retval.release (); } PyObject * @@ -105,9 +101,8 @@ if (! globals || (globals == Py_None)) { - PyObject *main = py_import_module ("__main__"); + python_object main = py_import_module ("__main__"); globals = PyModule_GetDict (main); - Py_DECREF (main); if (! globals) { globals = PyDict_New (); @@ -121,8 +116,8 @@ // Evaluate all expressions under "from __future__ import print_function" PyCompilerFlags flags { CO_FUTURE_PRINT_FUNCTION }; - PyObject *retval = PyRun_StringFlags (expr.c_str (), start, globals, locals, - &flags); + python_object retval = PyRun_StringFlags (expr.c_str (), start, globals, locals, + &flags); if (alloc) Py_DECREF (globals); @@ -130,7 +125,7 @@ if (! retval) throw boost::python::error_already_set (); - return retval; + return retval.release (); } PyObject * diff -r 3644df6564bc -r aef165ff92b0 oct-py-types.cc --- a/oct-py-types.cc Fri Apr 28 14:19:49 2017 -0700 +++ b/oct-py-types.cc Fri Apr 28 16:21:39 2017 -0700 @@ -31,6 +31,7 @@ #include "exceptions.h" #include "oct-py-eval.h" +#include "oct-py-object.h" #include "oct-py-types.h" // FIXME: only here to bootstrap nested conversions needed in this file @@ -143,26 +144,24 @@ ("unable to create array from Octave data"); std::string arg { typecode }; - PyObject *array = py_call_function ("array.array", ovl (arg)); + python_object array = py_call_function ("array.array", ovl (arg)); if (len > 0) { // create a byte buffer containing a copy of the array binary data const char *cdata = reinterpret_cast (data); - PyObject *buf = PyBytes_FromStringAndSize (cdata, len); + python_object buf = PyBytes_FromStringAndSize (cdata, len); if (! buf) octave_throw_bad_alloc (); PyObject *frombytes = (PyObject_HasAttrString (array, "frombytes") ? PyObject_GetAttrString (array, "frombytes") : PyObject_GetAttrString (array, "fromstring")); - PyObject *args = PyTuple_Pack (1, buf); + python_object args = PyTuple_Pack (1, buf.release ()); py_call_function (frombytes, args); - Py_DECREF (args); - Py_DECREF (buf); } - return array; + return array.release (); } // Prefer the 'q' and 'Q' typecodes if they are available (if Python 3 and @@ -485,18 +484,10 @@ } else if (PyUnicode_Check (obj)) { - bool ok = false; - PyObject *enc = PyUnicode_AsUTF8String (obj); - if (enc) - { - if (PyBytes_Check (enc)) - { - ok = true; - retval.assign (PyBytes_AsString (enc), PyBytes_Size (enc)); - } - Py_DECREF (enc); - } - if (! ok) + python_object enc = PyUnicode_AsUTF8String (obj); + 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"); } diff -r 3644df6564bc -r aef165ff92b0 pycall.cc --- a/pycall.cc Fri Apr 28 14:19:49 2017 -0700 +++ b/pycall.cc Fri Apr 28 16:21:39 2017 -0700 @@ -34,6 +34,7 @@ #include "arrayobjectdefs.h" #include "exceptions.h" #include "oct-py-eval.h" +#include "oct-py-object.h" #include "oct-py-util.h" #include "octave_to_python.h" #include "python_to_octave.h" @@ -100,7 +101,7 @@ try { - PyObject *callable = nullptr; + pytave::python_object callable; if (args(0).is_string ()) { callable = pytave::py_find_function (args(0).string_value ()); @@ -118,7 +119,6 @@ octave_value_list arglist = args.slice (1, nargin - 1); PyObject *result = pytave::py_call_function (callable, arglist); object res = object (handle (result)); - Py_DECREF (callable); // Ensure reasonable "ans" behaviour, consistent with Python's "_". if (nargout > 0 || ! res.is_none ())