On 04/06/2018 09:52 AM, Eric Blake wrote:
In preparation for adding other optional flag arguments to the python bindings, start by making the existing 'may_trim' flag to 'zero' be optional. That is, the plugin need not define the parameter if it does not make any semantic difference (ie. if the plugin ignores the hint and never trims); while if the parameter exists, we now pass it as a keyword argument rather than as a positional argument. This requires the plugin to give the parameter a specific name, and works whether or not the plugin provides a default for the parameter (although we do now recommend that plugins provide a default value, as it makes plugins built against newer nbdkit more likely to run even on older nbdkit). We can't see through a plugin that used '**kwargs', but that is less likely.
So far, I've only tested under Python 2, on Fedora 27. Before committing, I'll have to re-test with python 3. I already noted that:
+/* Does a callback support the given keyword parameter? */ +static int +callback_has_parameter (PyObject *fn, const char *name) +{ + int r = 0; + PyObject *inspect, *pname, *spec, *args; + + assert (script != NULL); + assert (module != NULL); + + pname = PyString_FromString ("inspect");
Needs python 2/3 protection using HAVE_PYSTRING_FROMSTRING.
+ if (!pname) + return -1; + inspect = PyImport_Import (pname); + Py_DECREF (pname); + + if (!inspect) + return -1; + +#if PY_MAJOR_VERSION >= 3 + pname = PyString_FromString ("getfullargspec");
and this should use PyUnicode_FromString.
+#else + pname = PyString_FromString ("getargspec"); +#endif + spec = PyObject_CallMethodObjArgs (inspect, pname, fn, NULL); + Py_DECREF (pname); + Py_DECREF (inspect); + if (!spec) + return -1; +
@@ -530,21 +594,31 @@ py_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
PyTuple_SetItem (args, 2, PyLong_FromUnsignedLongLong (offset)); - PyTuple_SetItem (args, 3, PyBool_FromLong (may_trim)); - r = PyObject_CallObject (fn, args); + if (zero_may_trim) + kwargs = Py_BuildValue("{s:i}", "may_trim", may_trim);
I also wonder if Py_BuildValue() is any easier to use instead of conditionals on HAVE_PYSTRING_FROMSTRING. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org