[libvirt] [PATCH libvirt-python] virPyDictToTypedParams: packing lists of values

Pack a list or a tuple of values passed to a Python method to the multi-value parameter. --- libvirt-override.c | 228 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 129 insertions(+), 99 deletions(-) diff --git a/libvirt-override.c b/libvirt-override.c index 588dac1..45c8afc 100644 --- a/libvirt-override.c +++ b/libvirt-override.c @@ -278,6 +278,126 @@ typedef virPyTypedParamsHint *virPyTypedParamsHintPtr; # define libvirt_PyString_Check PyString_Check # endif +static int +virPyDictToTypedParamOne(virTypedParameterPtr *params, + int *n, + int *max, + virPyTypedParamsHintPtr hints, + int nhints, + const char *keystr, + PyObject *value) +{ + int rv = -1, type = -1; + size_t i; + + for (i = 0; i < nhints; i++) { + if (STREQ(hints[i].name, keystr)) { + type = hints[i].type; + break; + } + } + + if (type == -1) { + if (libvirt_PyString_Check(value)) { + type = VIR_TYPED_PARAM_STRING; + } else if (PyBool_Check(value)) { + type = VIR_TYPED_PARAM_BOOLEAN; + } else if (PyLong_Check(value)) { + unsigned long long ull = PyLong_AsUnsignedLongLong(value); + if (ull == (unsigned long long) -1 && PyErr_Occurred()) + type = VIR_TYPED_PARAM_LLONG; + else + type = VIR_TYPED_PARAM_ULLONG; +#if PY_MAJOR_VERSION < 3 + } else if (PyInt_Check(value)) { + if (PyInt_AS_LONG(value) < 0) + type = VIR_TYPED_PARAM_LLONG; + else + type = VIR_TYPED_PARAM_ULLONG; +#endif + } else if (PyFloat_Check(value)) { + type = VIR_TYPED_PARAM_DOUBLE; + } + } + + if (type == -1) { + PyErr_Format(PyExc_TypeError, + "Unknown type of \"%s\" field", keystr); + goto cleanup; + } + + switch ((virTypedParameterType) type) { + case VIR_TYPED_PARAM_INT: + { + int val; + if (libvirt_intUnwrap(value, &val) < 0 || + virTypedParamsAddInt(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_UINT: + { + unsigned int val; + if (libvirt_uintUnwrap(value, &val) < 0 || + virTypedParamsAddUInt(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_LLONG: + { + long long val; + if (libvirt_longlongUnwrap(value, &val) < 0 || + virTypedParamsAddLLong(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_ULLONG: + { + unsigned long long val; + if (libvirt_ulonglongUnwrap(value, &val) < 0 || + virTypedParamsAddULLong(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_DOUBLE: + { + double val; + if (libvirt_doubleUnwrap(value, &val) < 0 || + virTypedParamsAddDouble(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_BOOLEAN: + { + bool val; + if (libvirt_boolUnwrap(value, &val) < 0 || + virTypedParamsAddBoolean(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_STRING: + { + char *val;; + if (libvirt_charPtrUnwrap(value, &val) < 0 || + !val || + virTypedParamsAddString(params, n, max, keystr, val) < 0) { + VIR_FREE(val); + goto cleanup; + } + VIR_FREE(val); + break; + } + case VIR_TYPED_PARAM_LAST: + break; /* unreachable */ + } + + rv = 0; + + cleanup: + return rv; +} + + /* Automatically convert dict into type parameters based on types reported * by python. All integer types are converted into LLONG (in case of a negative * value) or ULLONG (in case of a positive value). If you need different @@ -300,7 +420,6 @@ virPyDictToTypedParams(PyObject *dict, Py_ssize_t pos = 0; #endif virTypedParameterPtr params = NULL; - size_t i; int n = 0; int max = 0; int ret = -1; @@ -313,112 +432,23 @@ virPyDictToTypedParams(PyObject *dict, return -1; while (PyDict_Next(dict, &pos, &key, &value)) { - int type = -1; - if (libvirt_charPtrUnwrap(key, &keystr) < 0 || !keystr) goto cleanup; - for (i = 0; i < nhints; i++) { - if (STREQ(hints[i].name, keystr)) { - type = hints[i].type; - break; - } - } + if (PyList_Check(value) || PyTuple_Check(value)) { + Py_ssize_t i, size = PySequence_Size(value); - if (type == -1) { - if (libvirt_PyString_Check(value)) { - type = VIR_TYPED_PARAM_STRING; - } else if (PyBool_Check(value)) { - type = VIR_TYPED_PARAM_BOOLEAN; - } else if (PyLong_Check(value)) { - unsigned long long ull = PyLong_AsUnsignedLongLong(value); - if (ull == (unsigned long long) -1 && PyErr_Occurred()) - type = VIR_TYPED_PARAM_LLONG; - else - type = VIR_TYPED_PARAM_ULLONG; -#if PY_MAJOR_VERSION < 3 - } else if (PyInt_Check(value)) { - if (PyInt_AS_LONG(value) < 0) - type = VIR_TYPED_PARAM_LLONG; - else - type = VIR_TYPED_PARAM_ULLONG; -#endif - } else if (PyFloat_Check(value)) { - type = VIR_TYPED_PARAM_DOUBLE; + for (i = 0; i < size; i++) { + PyObject *v = PySequence_ITEM(value, i); + if (virPyDictToTypedParamOne(¶ms, &n, &max, + hints, nhints, keystr, v) < 0) + goto cleanup; } - } - - if (type == -1) { - PyErr_Format(PyExc_TypeError, - "Unknown type of \"%s\" field", keystr); + } else if (virPyDictToTypedParamOne(¶ms, &n, &max, + hints, nhints, keystr, value) < 0) goto cleanup; - } - switch ((virTypedParameterType) type) { - case VIR_TYPED_PARAM_INT: - { - int val; - if (libvirt_intUnwrap(value, &val) < 0 || - virTypedParamsAddInt(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_UINT: - { - unsigned int val; - if (libvirt_uintUnwrap(value, &val) < 0 || - virTypedParamsAddUInt(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_LLONG: - { - long long val; - if (libvirt_longlongUnwrap(value, &val) < 0 || - virTypedParamsAddLLong(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_ULLONG: - { - unsigned long long val; - if (libvirt_ulonglongUnwrap(value, &val) < 0 || - virTypedParamsAddULLong(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_DOUBLE: - { - double val; - if (libvirt_doubleUnwrap(value, &val) < 0 || - virTypedParamsAddDouble(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_BOOLEAN: - { - bool val; - if (libvirt_boolUnwrap(value, &val) < 0 || - virTypedParamsAddBoolean(¶ms, &n, &max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_STRING: - { - char *val;; - if (libvirt_charPtrUnwrap(value, &val) < 0 || - !val || - virTypedParamsAddString(¶ms, &n, &max, keystr, val) < 0) { - VIR_FREE(val); - goto cleanup; - } - VIR_FREE(val); - break; - } - case VIR_TYPED_PARAM_LAST: - break; /* unreachable */ - } VIR_FREE(keystr); } -- 1.9.1

On 16.06.2015 03:39, Pavel Boldin wrote:
Pack a list or a tuple of values passed to a Python method to the multi-value parameter. --- libvirt-override.c | 228 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 129 insertions(+), 99 deletions(-)
ACKed. Even though we are in freeze, this patch was sent early enough and I've promised to review it. Then, it makes the selective block migration possible in python bindings. Therefore I've pushed it too. Michal
participants (2)
-
Michal Privoznik
-
Pavel Boldin