[libvirt] [PATCH 1/2] python: Add new helper functions for python to C integral conversion

int libvirt_intUnwrap(PyObject *obj, int *val); int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); int libvirt_longUnwrap(PyObject *obj, long *val); int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); int libvirt_longlongUnwrap(PyObject *obj, long long *val); int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); int libvirt_doubleUnwrap(PyObject *obj, double *val); int libvirt_boolUnwrap(PyObject *obj, bool *val); --- python/typewrappers.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ python/typewrappers.h | 9 +++ 2 files changed, 151 insertions(+), 0 deletions(-) diff --git a/python/typewrappers.c b/python/typewrappers.c index 3f200b3..6ad01df 100644 --- a/python/typewrappers.c +++ b/python/typewrappers.c @@ -119,6 +119,148 @@ libvirt_constcharPtrWrap(const char *str) return (ret); } +int +libvirt_intUnwrap(PyObject *obj, int *val) +{ + long long_val; + + /* If obj is type of PyInt_Type, PyInt_AsLong converts it + * to C long type directly. If it is of PyLong_Type, PyInt_AsLong + * will call PyLong_AsLong() to deal with it automatically. + */ + long_val = PyInt_AsLong(obj); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + + if ((int)long_val == long_val) { + *val = long_val; + } else { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C int"); + return -1; + } + return 0; +} + +int +libvirt_uintUnwrap(PyObject *obj, unsigned int *val) +{ + long long_val; + + long_val = PyInt_AsLong(obj); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + + if ((unsigned int)long_val == long_val) { + *val = long_val; + } else { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C unsigned int"); + return -1; + } + return 0; +} + +int +libvirt_longUnwrap(PyObject *obj, long *val) +{ + long long_val; + + long_val = PyInt_AsLong(obj); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + + *val = long_val; + return 0; +} + +int +libvirt_ulongUnwrap(PyObject *obj, unsigned long *val) +{ + long long_val; + + long_val = PyInt_AsLong(obj); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + + *val = long_val; + return 0; +} + +int +libvirt_longlongUnwrap(PyObject *obj, long long *val) +{ + long long llong_val; + + /* If obj is of PyInt_Type, PyLong_AsLongLong + * will call PyInt_AsLong() to handle it automatically. + */ + llong_val = PyLong_AsLongLong(obj); + if ((llong_val == -1) && PyErr_Occurred()) + return -1; + + *val = llong_val; + return 0; +} + +int +libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val) +{ + unsigned long long ullong_val = -1; + + /* The PyLong_AsUnsignedLongLong doesn't check the type of + * obj, only accept argument of PyLong_Type, so we check it instead. + */ + if (PyInt_Check(obj)) { + ullong_val = PyInt_AsLong(obj); + } else if (PyLong_Check(obj)) { + ullong_val = PyLong_AsUnsignedLongLong(obj); + } else { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + } + + if ((ullong_val == -1) && PyErr_Occurred()) + return -1; + + *val = ullong_val; + return 0; +} + +int +libvirt_doubleUnwrap(PyObject *obj, double *val) +{ + double double_val; + + double_val = PyFloat_AsDouble(obj); + if ((double_val == -1) && PyErr_Occurred()) + return -1; + + *val = double_val; + return 0; +} + +int +libvirt_boolUnwrap(PyObject *obj, bool *val) +{ + int ret = -1; + + /* We only accept PyInt_Type, PyLong_Type and PyBool_Type + * as the boolean representation. + */ + if (PyInt_Check(obj) || + PyLong_Check(obj) || PyBool_Check(obj)) { + ret = PyObject_IsTrue(obj); + if (ret < 0) + return ret; + + *val = ret > 0; + return 0; + } else { + PyErr_SetString(PyExc_TypeError, "an integer or bool is required"); + } + return ret; +} + PyObject * libvirt_virDomainPtrWrap(virDomainPtr node) { diff --git a/python/typewrappers.h b/python/typewrappers.h index 1e34dfa..af68bce 100644 --- a/python/typewrappers.h +++ b/python/typewrappers.h @@ -7,6 +7,7 @@ */ #include <Python.h> +#include <stdbool.h> #include "libvirt/libvirt.h" #include "libvirt/virterror.h" @@ -163,6 +164,14 @@ PyObject * libvirt_ulonglongWrap(unsigned long long val); PyObject * libvirt_charPtrWrap(char *str); PyObject * libvirt_charPtrSizeWrap(char *str, Py_ssize_t size); PyObject * libvirt_constcharPtrWrap(const char *str); +int libvirt_intUnwrap(PyObject *obj, int *val); +int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); +int libvirt_longUnwrap(PyObject *obj, long *val); +int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); +int libvirt_longlongUnwrap(PyObject *obj, long long *val); +int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); +int libvirt_doubleUnwrap(PyObject *obj, double *val); +int libvirt_boolUnwrap(PyObject *obj, bool *val); PyObject * libvirt_virConnectPtrWrap(virConnectPtr node); PyObject * libvirt_virDomainPtrWrap(virDomainPtr node); PyObject * libvirt_virNetworkPtrWrap(virNetworkPtr node); -- 1.7.7.5

*libvirt_virDomainGetCPUStats *setPyVirTypedParameter --- python/libvirt-override-api.xml | 4 +- python/libvirt-override.c | 62 +++++--------------------------------- 2 files changed, 11 insertions(+), 55 deletions(-) diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index 06986ec..0bafd21 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -151,11 +151,11 @@ </function> <function name='virDomainGetCPUStats' file='python'> <info>Extracts CPU statistics for a running domain. On success it will - return a list of data of dictionary type. If boolean total is False, the + return a list of data of dictionary type. If boolean total is False or 0, the first element of the list refers to CPU0 on the host, second element is CPU1, and so on. The format of data struct is as follows: [{cpu_time:xxx}, {cpu_time:xxx}, ...] - If it is True, it returns total domain CPU statistics in the format of + If it is True or 1, it returns total domain CPU statistics in the format of [{cpu_time:xxx, user_time:xxx, system_time:xxx}]</info> <return type='str *' info='returns a list of dictionary in case of success, None in case of error'/> <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> diff --git a/python/libvirt-override.c b/python/libvirt-override.c index da1bceb..6d2e3f1 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -195,73 +195,38 @@ setPyVirTypedParameter(PyObject *info, switch(params[i].type) { case VIR_TYPED_PARAM_INT: { - long long_val = PyInt_AsLong(value); - if ((long_val == -1) && PyErr_Occurred()) + if (libvirt_intUnwrap(value, &temp->value.i) < 0) goto cleanup; - if ((int)long_val == long_val) { - temp->value.i = long_val; - } else { - PyErr_Format(PyExc_ValueError, - "The value of " - "attribute \"%s\" is out of int range", keystr); - goto cleanup; - } } break; case VIR_TYPED_PARAM_UINT: { - long long_val = PyInt_AsLong(value); - if ((long_val == -1) && PyErr_Occurred()) + if (libvirt_uintUnwrap(value, &temp->value.ui) < 0) goto cleanup; - if ((unsigned int)long_val == long_val) { - temp->value.ui = long_val; - } else { - PyErr_Format(PyExc_ValueError, - "The value of " - "attribute \"%s\" is out of int range", keystr); - goto cleanup; - } } break; case VIR_TYPED_PARAM_LLONG: { - long long llong_val = PyLong_AsLongLong(value); - if ((llong_val == -1) && PyErr_Occurred()) + if (libvirt_longlongUnwrap(value, &temp->value.l) < 0) goto cleanup; - temp->value.l = llong_val; } break; case VIR_TYPED_PARAM_ULLONG: { - unsigned long long ullong_val = PyLong_AsUnsignedLongLong(value); - if ((ullong_val == -1) && PyErr_Occurred()) + if (libvirt_ulonglongUnwrap(value, &temp->value.ul) < 0) goto cleanup; - temp->value.ul = ullong_val; } break; case VIR_TYPED_PARAM_DOUBLE: { - double double_val = PyFloat_AsDouble(value); - if ((double_val == -1) && PyErr_Occurred()) + if (libvirt_doubleUnwrap(value, &temp->value.d) < 0) goto cleanup; - temp->value.d = double_val; } break; case VIR_TYPED_PARAM_BOOLEAN: { - /* Hack - Python's definition of Py_True breaks strict - * aliasing rules, so can't directly compare - */ - if (PyBool_Check(value)) { - PyObject *hacktrue = PyBool_FromLong(1); - temp->value.b = hacktrue == value ? 1 : 0; - Py_DECREF(hacktrue); - } else { - PyErr_Format(PyExc_TypeError, - "The value type of " - "attribute \"%s\" must be bool", keystr); + if (libvirt_boolUnwrap(value, (bool *)&temp->value.b) < 0) goto cleanup; - } } break; case VIR_TYPED_PARAM_STRING: @@ -388,7 +353,8 @@ libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) int ncpus = -1, start_cpu = 0; int sumparams = 0, nparams = -1; int i, i_retval; - unsigned int flags, totalflag; + unsigned int flags; + bool totalflag; virTypedParameterPtr params = NULL, cpuparams; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainGetCPUStats", @@ -396,18 +362,8 @@ libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); - if (!PyBool_Check(totalbool)) { - PyErr_Format(PyExc_TypeError, - "The \"total\" attribute must be bool"); + if (libvirt_boolUnwrap(totalbool, &totalflag) < 0) return NULL; - } else { - /* Hack - Python's definition of Py_True breaks strict - * aliasing rules, so can't directly compare - */ - PyObject *hacktrue = PyBool_FromLong(1); - totalflag = hacktrue == totalbool ? 1 : 0; - Py_DECREF(hacktrue); - } if ((ret = PyList_New(0)) == NULL) return NULL; -- 1.7.7.5

On 03/26/2012 12:11 AM, Guannan Ren wrote:
*libvirt_virDomainGetCPUStats *setPyVirTypedParameter --- python/libvirt-override-api.xml | 4 +- python/libvirt-override.c | 62 +++++--------------------------------- 2 files changed, 11 insertions(+), 55 deletions(-)
Nice ratio for size reduction.
case VIR_TYPED_PARAM_INT: { - long long_val = PyInt_AsLong(value); - if ((long_val == -1) && PyErr_Occurred()) + if (libvirt_intUnwrap(value, &temp->value.i) < 0) goto cleanup; - if ((int)long_val == long_val) { - temp->value.i = long_val; - } else { - PyErr_Format(PyExc_ValueError, - "The value of " - "attribute \"%s\" is out of int range", keystr); - goto cleanup; - } }
Nit: now that you are no longer declaring a variable in each 'case label:', you can also get rid of the outermost {} after the case and before the break.
case VIR_TYPED_PARAM_BOOLEAN: { - /* Hack - Python's definition of Py_True breaks strict - * aliasing rules, so can't directly compare - */ - if (PyBool_Check(value)) { - PyObject *hacktrue = PyBool_FromLong(1); - temp->value.b = hacktrue == value ? 1 : 0; - Py_DECREF(hacktrue); - } else { - PyErr_Format(PyExc_TypeError, - "The value type of " - "attribute \"%s\" must be bool", keystr); + if (libvirt_boolUnwrap(value, (bool *)&temp->value.b) < 0)
This can break in strict C99 compilers, as it is not type-safe (we are _not_ guaranteed that char and bool are the same size). Here, you need a temporary variable: bool b; if (libvirt_boolUnwrap(value, &b) < 0) goto cleanup; temp->value.b = b; Also, there are a lot of other places where we have the 'hacktrue' or 'hackfalse' code; we should be fixing all of those call-sites to use the new libvirt_boolUnwrap() (although it's fine if you want to break the cleanup into multiple commits). -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 03/27/2012 07:11 AM, Eric Blake wrote:
On 03/26/2012 12:11 AM, Guannan Ren wrote:
*libvirt_virDomainGetCPUStats *setPyVirTypedParameter --- python/libvirt-override-api.xml | 4 +- python/libvirt-override.c | 62 +++++--------------------------------- 2 files changed, 11 insertions(+), 55 deletions(-)
Also, there are a lot of other places where we have the 'hacktrue' or 'hackfalse' code; we should be fixing all of those call-sites to use the new libvirt_boolUnwrap() (although it's fine if you want to break the cleanup into multiple commits).
libvirt_virDomainPinVcpu and libvirt_virDomainPinVcpuFlags are using hacktrue or hackfalse to check for bool value. But there are some other places needed to change besides only this. So I will submit patches later for these two APIs. Guannan Ren

*setPyVirTypedParameter *libvirt_virDomainGetCPUStats --- python/libvirt-override-api.xml | 4 +- python/libvirt-override.c | 91 +++++++++----------------------------- 2 files changed, 24 insertions(+), 71 deletions(-) diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index 06986ec..0bafd21 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -151,11 +151,11 @@ </function> <function name='virDomainGetCPUStats' file='python'> <info>Extracts CPU statistics for a running domain. On success it will - return a list of data of dictionary type. If boolean total is False, the + return a list of data of dictionary type. If boolean total is False or 0, the first element of the list refers to CPU0 on the host, second element is CPU1, and so on. The format of data struct is as follows: [{cpu_time:xxx}, {cpu_time:xxx}, ...] - If it is True, it returns total domain CPU statistics in the format of + If it is True or 1, it returns total domain CPU statistics in the format of [{cpu_time:xxx, user_time:xxx, system_time:xxx}]</info> <return type='str *' info='returns a list of dictionary in case of success, None in case of error'/> <arg name='domain' type='virDomainPtr' info='pointer to domain object'/> diff --git a/python/libvirt-override.c b/python/libvirt-override.c index da1bceb..c67f3d6 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -194,76 +194,38 @@ setPyVirTypedParameter(PyObject *info, switch(params[i].type) { case VIR_TYPED_PARAM_INT: - { - long long_val = PyInt_AsLong(value); - if ((long_val == -1) && PyErr_Occurred()) - goto cleanup; - if ((int)long_val == long_val) { - temp->value.i = long_val; - } else { - PyErr_Format(PyExc_ValueError, - "The value of " - "attribute \"%s\" is out of int range", keystr); + if (libvirt_intUnwrap(value, &temp->value.i) < 0) goto cleanup; - } - } - break; + break; + case VIR_TYPED_PARAM_UINT: - { - long long_val = PyInt_AsLong(value); - if ((long_val == -1) && PyErr_Occurred()) + if (libvirt_uintUnwrap(value, &temp->value.ui) < 0) goto cleanup; - if ((unsigned int)long_val == long_val) { - temp->value.ui = long_val; - } else { - PyErr_Format(PyExc_ValueError, - "The value of " - "attribute \"%s\" is out of int range", keystr); - goto cleanup; - } - } - break; + break; + case VIR_TYPED_PARAM_LLONG: - { - long long llong_val = PyLong_AsLongLong(value); - if ((llong_val == -1) && PyErr_Occurred()) + if (libvirt_longlongUnwrap(value, &temp->value.l) < 0) goto cleanup; - temp->value.l = llong_val; - } - break; + break; + case VIR_TYPED_PARAM_ULLONG: - { - unsigned long long ullong_val = PyLong_AsUnsignedLongLong(value); - if ((ullong_val == -1) && PyErr_Occurred()) + if (libvirt_ulonglongUnwrap(value, &temp->value.ul) < 0) goto cleanup; - temp->value.ul = ullong_val; - } - break; + break; + case VIR_TYPED_PARAM_DOUBLE: - { - double double_val = PyFloat_AsDouble(value); - if ((double_val == -1) && PyErr_Occurred()) + if (libvirt_doubleUnwrap(value, &temp->value.d) < 0) goto cleanup; - temp->value.d = double_val; - } - break; + break; + case VIR_TYPED_PARAM_BOOLEAN: { - /* Hack - Python's definition of Py_True breaks strict - * aliasing rules, so can't directly compare - */ - if (PyBool_Check(value)) { - PyObject *hacktrue = PyBool_FromLong(1); - temp->value.b = hacktrue == value ? 1 : 0; - Py_DECREF(hacktrue); - } else { - PyErr_Format(PyExc_TypeError, - "The value type of " - "attribute \"%s\" must be bool", keystr); + bool b; + if (libvirt_boolUnwrap(value, &b) < 0) goto cleanup; - } + temp->value.b = b; + break; } - break; case VIR_TYPED_PARAM_STRING: { char *string_val = PyString_AsString(value); @@ -388,7 +350,8 @@ libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) int ncpus = -1, start_cpu = 0; int sumparams = 0, nparams = -1; int i, i_retval; - unsigned int flags, totalflag; + unsigned int flags; + bool totalflag; virTypedParameterPtr params = NULL, cpuparams; if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainGetCPUStats", @@ -396,18 +359,8 @@ libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) return NULL; domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); - if (!PyBool_Check(totalbool)) { - PyErr_Format(PyExc_TypeError, - "The \"total\" attribute must be bool"); + if (libvirt_boolUnwrap(totalbool, &totalflag) < 0) return NULL; - } else { - /* Hack - Python's definition of Py_True breaks strict - * aliasing rules, so can't directly compare - */ - PyObject *hacktrue = PyBool_FromLong(1); - totalflag = hacktrue == totalbool ? 1 : 0; - Py_DECREF(hacktrue); - } if ((ret = PyList_New(0)) == NULL) return NULL; -- 1.7.7.5

On 03/27/2012 12:06 AM, Guannan Ren wrote:
*setPyVirTypedParameter *libvirt_virDomainGetCPUStats --- python/libvirt-override-api.xml | 4 +- python/libvirt-override.c | 91 +++++++++----------------------------- 2 files changed, 24 insertions(+), 71 deletions(-)
ACK, and looking forward to your additional further cleanups. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 03/26/2012 12:10 AM, Guannan Ren wrote:
int libvirt_intUnwrap(PyObject *obj, int *val); int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); int libvirt_longUnwrap(PyObject *obj, long *val); int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); int libvirt_longlongUnwrap(PyObject *obj, long long *val); int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); int libvirt_doubleUnwrap(PyObject *obj, double *val); int libvirt_boolUnwrap(PyObject *obj, bool *val); --- python/typewrappers.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ python/typewrappers.h | 9 +++ 2 files changed, 151 insertions(+), 0 deletions(-)
+int +libvirt_boolUnwrap(PyObject *obj, bool *val) +{ + int ret = -1; + + /* We only accept PyInt_Type, PyLong_Type and PyBool_Type + * as the boolean representation.
Why?
+ */ + if (PyInt_Check(obj) || + PyLong_Check(obj) || PyBool_Check(obj)) { + ret = PyObject_IsTrue(obj);
Why not blindly use PyObject_IsTrue(obj), and accept _all_ objects that can be converted to python truth values, rather than forcing things to be PyInt, PyBool, or PyLong? ACK to the rest of the patch, but I think we want libvirt_boolUnwrap to be more forgiving. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 03/27/2012 07:03 AM, Eric Blake wrote:
+int +libvirt_boolUnwrap(PyObject *obj, bool *val) +{ + int ret = -1; + + /* We only accept PyInt_Type, PyLong_Type and PyBool_Type + * as the boolean representation. Why?
+ */ + if (PyInt_Check(obj) || + PyLong_Check(obj) || PyBool_Check(obj)) { + ret = PyObject_IsTrue(obj); Why not blindly use PyObject_IsTrue(obj), and accept _all_ objects that can be converted to python truth values, rather than forcing things to be PyInt, PyBool, or PyLong?
If we don't check here, these APIs which use libvirt_boolUnwrap will not have any checking for its type of arguments in bool wise. The upper python code could pass a null list or dictionary as a False. Maybe a little bit loose use here. but It's fine to blindly use it actually. Guannan Ren

int libvirt_intUnwrap(PyObject *obj, int *val); int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); int libvirt_longUnwrap(PyObject *obj, long *val); int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); int libvirt_longlongUnwrap(PyObject *obj, long long *val); int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); int libvirt_doubleUnwrap(PyObject *obj, double *val); int libvirt_boolUnwrap(PyObject *obj, bool *val); --- python/typewrappers.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ python/typewrappers.h | 9 +++ 2 files changed, 141 insertions(+), 0 deletions(-) diff --git a/python/typewrappers.c b/python/typewrappers.c index 3f200b3..8b9df75 100644 --- a/python/typewrappers.c +++ b/python/typewrappers.c @@ -119,6 +119,138 @@ libvirt_constcharPtrWrap(const char *str) return (ret); } +int +libvirt_intUnwrap(PyObject *obj, int *val) +{ + long long_val; + + /* If obj is type of PyInt_Type, PyInt_AsLong converts it + * to C long type directly. If it is of PyLong_Type, PyInt_AsLong + * will call PyLong_AsLong() to deal with it automatically. + */ + long_val = PyInt_AsLong(obj); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + + if ((int)long_val == long_val) { + *val = long_val; + } else { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C int"); + return -1; + } + return 0; +} + +int +libvirt_uintUnwrap(PyObject *obj, unsigned int *val) +{ + long long_val; + + long_val = PyInt_AsLong(obj); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + + if ((unsigned int)long_val == long_val) { + *val = long_val; + } else { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C unsigned int"); + return -1; + } + return 0; +} + +int +libvirt_longUnwrap(PyObject *obj, long *val) +{ + long long_val; + + long_val = PyInt_AsLong(obj); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + + *val = long_val; + return 0; +} + +int +libvirt_ulongUnwrap(PyObject *obj, unsigned long *val) +{ + long long_val; + + long_val = PyInt_AsLong(obj); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + + *val = long_val; + return 0; +} + +int +libvirt_longlongUnwrap(PyObject *obj, long long *val) +{ + long long llong_val; + + /* If obj is of PyInt_Type, PyLong_AsLongLong + * will call PyInt_AsLong() to handle it automatically. + */ + llong_val = PyLong_AsLongLong(obj); + if ((llong_val == -1) && PyErr_Occurred()) + return -1; + + *val = llong_val; + return 0; +} + +int +libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val) +{ + unsigned long long ullong_val = -1; + + /* The PyLong_AsUnsignedLongLong doesn't check the type of + * obj, only accept argument of PyLong_Type, so we check it instead. + */ + if (PyInt_Check(obj)) + ullong_val = PyInt_AsLong(obj); + else if (PyLong_Check(obj)) + ullong_val = PyLong_AsUnsignedLongLong(obj); + else + PyErr_SetString(PyExc_TypeError, "an integer is required"); + + if ((ullong_val == -1) && PyErr_Occurred()) + return -1; + + *val = ullong_val; + return 0; +} + +int +libvirt_doubleUnwrap(PyObject *obj, double *val) +{ + double double_val; + + double_val = PyFloat_AsDouble(obj); + if ((double_val == -1) && PyErr_Occurred()) + return -1; + + *val = double_val; + return 0; +} + +int +libvirt_boolUnwrap(PyObject *obj, bool *val) +{ + int ret; + + ret = PyObject_IsTrue(obj); + if (ret < 0) + return ret; + + *val = ret > 0; + return 0; +} + PyObject * libvirt_virDomainPtrWrap(virDomainPtr node) { diff --git a/python/typewrappers.h b/python/typewrappers.h index 1e34dfa..af68bce 100644 --- a/python/typewrappers.h +++ b/python/typewrappers.h @@ -7,6 +7,7 @@ */ #include <Python.h> +#include <stdbool.h> #include "libvirt/libvirt.h" #include "libvirt/virterror.h" @@ -163,6 +164,14 @@ PyObject * libvirt_ulonglongWrap(unsigned long long val); PyObject * libvirt_charPtrWrap(char *str); PyObject * libvirt_charPtrSizeWrap(char *str, Py_ssize_t size); PyObject * libvirt_constcharPtrWrap(const char *str); +int libvirt_intUnwrap(PyObject *obj, int *val); +int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); +int libvirt_longUnwrap(PyObject *obj, long *val); +int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); +int libvirt_longlongUnwrap(PyObject *obj, long long *val); +int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); +int libvirt_doubleUnwrap(PyObject *obj, double *val); +int libvirt_boolUnwrap(PyObject *obj, bool *val); PyObject * libvirt_virConnectPtrWrap(virConnectPtr node); PyObject * libvirt_virDomainPtrWrap(virDomainPtr node); PyObject * libvirt_virNetworkPtrWrap(virNetworkPtr node); -- 1.7.7.5

On 03/27/2012 12:06 AM, Guannan Ren wrote:
int libvirt_intUnwrap(PyObject *obj, int *val); int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); int libvirt_longUnwrap(PyObject *obj, long *val); int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); int libvirt_longlongUnwrap(PyObject *obj, long long *val); int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); int libvirt_doubleUnwrap(PyObject *obj, double *val); int libvirt_boolUnwrap(PyObject *obj, bool *val); --- python/typewrappers.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ python/typewrappers.h | 9 +++ 2 files changed, 141 insertions(+), 0 deletions(-)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 03/28/2012 04:07 AM, Eric Blake wrote:
On 03/27/2012 12:06 AM, Guannan Ren wrote:
int libvirt_intUnwrap(PyObject *obj, int *val); int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); int libvirt_longUnwrap(PyObject *obj, long *val); int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); int libvirt_longlongUnwrap(PyObject *obj, long long *val); int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); int libvirt_doubleUnwrap(PyObject *obj, double *val); int libvirt_boolUnwrap(PyObject *obj, bool *val); --- python/typewrappers.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ python/typewrappers.h | 9 +++ 2 files changed, 141 insertions(+), 0 deletions(-)
ACK.
Thanks, could you push for me.

On 03/28/2012 06:44 AM, Guannan Ren wrote:
On 03/28/2012 04:07 AM, Eric Blake wrote:
On 03/27/2012 12:06 AM, Guannan Ren wrote:
int libvirt_intUnwrap(PyObject *obj, int *val); int libvirt_uintUnwrap(PyObject *obj, unsigned int *val); int libvirt_longUnwrap(PyObject *obj, long *val); int libvirt_ulongUnwrap(PyObject *obj, unsigned long *val); int libvirt_longlongUnwrap(PyObject *obj, long long *val); int libvirt_ulonglongUnwrap(PyObject *obj, unsigned long long *val); int libvirt_doubleUnwrap(PyObject *obj, double *val); int libvirt_boolUnwrap(PyObject *obj, bool *val); --- python/typewrappers.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ python/typewrappers.h | 9 +++ 2 files changed, 141 insertions(+), 0 deletions(-)
ACK.
Thanks, could you push for me.
Sure, patch 1 and 2 are now pushed. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Guannan Ren