changeset 404:aef165ff92b0

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.
author Mike Miller <mtmiller@octave.org>
date Fri, 28 Apr 2017 16:21:39 -0700
parents 3644df6564bc
children 478d83448b0b
files __py_struct_from_dict__.cc exceptions.cc oct-py-eval.cc oct-py-types.cc pycall.cc
diffstat 5 files changed, 43 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- 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);
 }
--- 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
       {
--- 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 <octave/ovl.h>
 
 #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 *
--- 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<const char *> (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");
       }
--- 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<PyObject> (result));
-      Py_DECREF (callable);
 
       // Ensure reasonable "ans" behaviour, consistent with Python's "_".
       if (nargout > 0 || ! res.is_none ())