# HG changeset patch # User Mike Miller # Date 1472068875 25200 # Node ID 4c2b748eaea085336985a406aa8129f1fd25ca35 # Parent d41fc23d4b9ffe9e3fdd62af2dfeb781c23e04b5 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. diff -r d41fc23d4b9f -r 4c2b748eaea0 oct-py-eval.cc --- 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 * diff -r d41fc23d4b9f -r 4c2b748eaea0 pycall.cc --- 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 (result)); + Py_DECREF (callable); // Ensure reasonable "ans" behaviour, consistent with Python's "_". if (nargout > 0 || ! res.is_none ())