changeset 359:4c2b748eaea0

Use py_find_function where specifically searching for a function by name * oct-py-eval.cc (pytave::py_call_function): Use py_find_function to look up Python function by name. * pycall.cc (Fpycall): Likewise, when argument is a string.
author Mike Miller <mtmiller@octave.org>
date Wed, 24 Aug 2016 13:01:15 -0700
parents d41fc23d4b9f
children 77ffcaaf8000
files oct-py-eval.cc pycall.cc
diffstat 2 files changed, 31 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/oct-py-eval.cc	Tue Aug 23 18:09:17 2016 -0700
+++ b/oct-py-eval.cc	Wed Aug 24 13:01:15 2016 -0700
@@ -39,19 +39,19 @@
 PyObject *
 py_call_function (const std::string& func, const octave_value_list& args)
 {
-  // FIXME: factor out parsing of string into a function reference
-  boost::python::object obj;
-  get_object_from_python (func, obj);
-  return py_call_function (obj.ptr (), args);
+  PyObject *func_obj = py_find_function (func);
+  PyObject *retval = py_call_function (func_obj, args);
+  Py_DECREF (func_obj);
+  return retval;
 }
 
 PyObject *
 py_call_function (const std::string& func, PyObject *args, PyObject *kwargs)
 {
-  // FIXME: factor out parsing of string into a function reference
-  boost::python::object obj;
-  get_object_from_python (func, obj);
-  return py_call_function (obj.ptr (), args, kwargs);
+  PyObject *func_obj = py_find_function (func);
+  PyObject *retval = py_call_function (func_obj, args, kwargs);
+  Py_DECREF (func_obj);
+  return retval;
 }
 
 PyObject *
--- a/pycall.cc	Tue Aug 23 18:09:17 2016 -0700
+++ b/pycall.cc	Wed Aug 24 13:01:15 2016 -0700
@@ -89,6 +89,10 @@
       return retval;
     }
 
+  if (! (args(0).is_string () || (args(0).is_object ()
+                                  && args(0).class_name () == "pyobject")))
+    error ("pycall: FUNC must be a string or a Python reference");
+
   Py_Initialize ();
 
   pytave::init_exceptions ();
@@ -97,14 +101,28 @@
 
   try
     {
-      object callable;
-      pytave::get_object_from_python (args(0), callable);
-      if (callable.is_none ())
-        error("pycall: FUNC must be a string or a Python reference");
+      PyObject *callable = 0;
+      if (args(0).is_string ())
+        callable = pytave::py_find_function (args(0).string_value ());
+      else
+        {
+          // FIXME: callable = get existing pyobject reference (args(0))
+          boost::python::object obj;
+          pytave::get_object_from_python (args(0), obj);
+          if (obj.is_none ())
+            error("pycall: FUNC must be a string or a Python reference");
+          callable = obj.ptr ();
+          Py_INCREF (callable);
+        }
+
+      if (! callable)
+        error ("pycall: no such Python function or callable: %s",
+               args(0).string_value ().c_str ());
 
       octave_value_list arglist = args.slice (1, nargin - 1);
-      PyObject *result = pytave::py_call_function (callable.ptr (), arglist);
+      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 ())