summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Privoznik <mprivozn@redhat.com>2022-07-08 08:21:58 +0200
committerMichal Privoznik <mprivozn@redhat.com>2022-07-08 08:21:58 +0200
commit3532ba2b8c804894a7e23e50380823ff055cd22f (patch)
tree8cc876bc22a60c862af3cb7905a9714c73c49e1c
parentb943a5bd18b4cc765719c0dbc628a077c3db4d52 (diff)
downloadlibvirt-python-3532ba2b8c804894a7e23e50380823ff055cd22f.tar.gz
libvirt-utils: Clear error when guessing typed param typev8.6.0
Our APIs which accept typed parameters are usually exposed in python as accepting dictionary, for instance: virDomainSetIOThreadParams(..., virTypedParameterPtr params, ...) -> virDomain.setIOThreadParams(..., {}, ...) Now, before calling the C API, the dictionary is processed by virPyDictToTypedParams() which accepts an additional argument: array that hints types for each typed parameter. However, if a key is not in the array we guess what the correct type might be. This is done by attempting conversion from python into string, if that fails then into boolean, then into long, only to fall back to double. Now, for the long type we can have two cases: the value is non-negative (ULL) or it is negative (LL). Therefore, we firstly attempt ULL case and if that fails we stick with the latter. However, after we attempted the ULL conversion, python records an error internally (which is then queried via PyErr_Occurred()), but the error is never cleared out. This leads to spurious paths taken afterwards: e.g. when libvirt_longlongUnwrap() is trying to convert -1, it fails. But not rightfully - the PyErr_Occurred() check it performs has nothing to do with any of its actions, rather than our guessing work done before. Therefore, clear the error after we've guessed the type. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
-rw-r--r--libvirt-utils.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/libvirt-utils.c b/libvirt-utils.c
index d8ff11d..a964779 100644
--- a/libvirt-utils.c
+++ b/libvirt-utils.c
@@ -408,10 +408,12 @@ virPyDictToTypedParamOne(virTypedParameterPtr *params,
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())
+ if (ull == (unsigned long long) -1 && PyErr_Occurred()) {
type = VIR_TYPED_PARAM_LLONG;
- else
+ PyErr_Clear();
+ } else {
type = VIR_TYPED_PARAM_ULLONG;
+ }
} else if (PyFloat_Check(value)) {
type = VIR_TYPED_PARAM_DOUBLE;
}