On 10/01/2012 04:08 PM, Michal Privoznik wrote:
On 28.09.2012 14:29, Guannan Ren wrote:
> libvirt_ulonglongUnwrap requires the integer type of python obj.
> But libvirt_longlongUnwrap still could handle python obj of
> Pyfloat_type which causes the float value to be rounded up
> to an integer.
>
> For example
> >>> dom.setSchedulerParameters({'vcpu_quota': 0.88})
> 0
> libvirt_longlongUnwrap treats 0.88 as a valid value 0
>
> However
> >>> dom.setSchedulerParameters({'cpu_shares': 1000.22})
> libvirt_ulonglongUnwrap will throw out an error
> "TypeError: an integer is required"
>
> The patch make this consistent.
> ---
> python/typewrappers.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/python/typewrappers.c b/python/typewrappers.c
> index 7580689..d633603 100644
> --- a/python/typewrappers.c
> +++ b/python/typewrappers.c
> @@ -220,7 +220,7 @@ libvirt_ulongUnwrap(PyObject *obj, unsigned long *val)
> int
> libvirt_longlongUnwrap(PyObject *obj, long long *val)
> {
> - long long llong_val;
> + long long llong_val = -1;
>
> if (!obj) {
> PyErr_SetString(PyExc_TypeError, "unexpected type");
> @@ -230,7 +230,11 @@ libvirt_longlongUnwrap(PyObject *obj, long long *val)
> /* If obj is of PyInt_Type, PyLong_AsLongLong
> * will call PyInt_AsLong() to handle it automatically.
> */
> - llong_val = PyLong_AsLongLong(obj);
> + if (PyInt_Check(obj) || PyLong_Check(obj))
> + llong_val = PyLong_AsLongLong(obj);
> + else
> + PyErr_SetString(PyExc_TypeError, "an integer is required");
> +
> if ((llong_val == -1) && PyErr_Occurred())
> return -1;
>
>
I wonder if we are guaranteed that if Py{Int|Long}_Check() returns true,
PyLong_AsLongLong cannot fail. If this is the case, than this patch can
be shortened as the check in the bottom context is no longer needed.
However, if it's not the case, then ACK.
I tried to read this out of python DOC, but man, my brain is too small
for that.
Michal
Thanks for the review.
I tried to see the source code of PyObject_SetItem where it uses
PyLong_AsLong() as the follows:
So I think it should be right for PyLong_AsLongLong too.
I am going to push this patch after a while.
...
else if (PyLong_Check(key)) {
long key_value = PyLong_AsLong(key);
if (key_value == -1 && PyErr_Occurred())
return -1;
return PySequence_SetItem(o, key_value, value);
}
...
Guannan