comparison pycall.cc @ 333:96b78e78a235

pycall: add support for keyword arguments from pyargs (fixes issue #45) * oct-py-util.cc, oct-py-util.h (pytave::py_object_class_name, pytave::is_py_kwargs_argument, pytave::update_py_dict): New functions. * pycall.cc (Fpycall): Check for and handle keyword arguments.
author Mike Miller <mtmiller@octave.org>
date Mon, 15 Aug 2016 13:20:15 -0700
parents cee203ea6245
children 252b458bd904
comparison
equal deleted inserted replaced
332:b8128a2e0e70 333:96b78e78a235
99 object callable; 99 object callable;
100 pytave::get_object_from_python (args(0), callable); 100 pytave::get_object_from_python (args(0), callable);
101 if (callable.is_none ()) 101 if (callable.is_none ())
102 error("pycall: FUNC must be a string or a Python reference"); 102 error("pycall: FUNC must be a string or a Python reference");
103 103
104 PyObject *pyargs = PyTuple_New (nargin - 1); 104 PyObject *args_list = PyList_New (0);
105 PyObject *kwargs = 0;
105 for (int i = 1; i < nargin; i++) 106 for (int i = 1; i < nargin; i++)
106 { 107 {
107 object arg; 108 object arg;
108 pytave::octvalue_to_pyobj (arg, args(i)); 109 pytave::octvalue_to_pyobj (arg, args(i));
109 PyObject *obj = arg.ptr (); 110 PyObject *obj = arg.ptr ();
110 Py_INCREF (obj); 111
111 PyTuple_SET_ITEM (pyargs, i - 1, obj); 112 if (pytave::is_py_kwargs_argument (obj))
113 kwargs = pytave::update_py_dict (kwargs, obj);
114 else
115 {
116 Py_INCREF (obj);
117 PyList_Append (args_list, obj);
118 }
112 } 119 }
113 120
114 PyObject *result = PyEval_CallObjectWithKeywords (callable.ptr (), pyargs, 0); 121 PyObject *pyargs = PyList_AsTuple (args_list);
122 PyObject *result = PyEval_CallObjectWithKeywords (callable.ptr (), pyargs, kwargs);
115 object res = object (handle<PyObject> (result)); 123 object res = object (handle<PyObject> (result));
124
125 Py_DECREF (args_list);
126 Py_DECREF (pyargs);
127 if (kwargs)
128 Py_DECREF (kwargs);
116 129
117 // Ensure reasonable "ans" behaviour, consistent with Python's "_". 130 // Ensure reasonable "ans" behaviour, consistent with Python's "_".
118 if (nargout > 0 || ! res.is_none ()) 131 if (nargout > 0 || ! res.is_none ())
119 { 132 {
120 octave_value val; 133 octave_value val;