473,385 Members | 1,400 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

problem with Py_BuildValue

Hi,

currently I have a problem understanding Py_BuildValue. I have this code:

static PyObject *function(PyObject *self, PyObject *args) {
PyObject * python_return_value = NULL;
PyObject * dummy = NULL;
double * internal_list;
<snip and forget the rest>

/* converting to python representation */
for (i=0; i < limit; i++) {
dummy = Py_BuildValue("d", internal_list[i]);
if (!dummy) return NULL;
PyList_Append(python_return_value, dummy);
Py_DECREF(dummy); dummy = NULL;
}
return python_return_value
}

This doesn't work. What I see, when invoking the function "function()" in
Python is a list of refcounts, like: [<refcnt 0 at 0x94a29d4>, <refcnt 0 at
0x94a29e4>, ...]. However, if I change the Py_BuildValue-line to be
dummy = Py_BuildValue("i", (int)internal_list[i]);
I do get the 'right' integer return values. Point is that I really would
like to work with Python-floats afterwards.

Any idea where a pitfall might be here?

TIA
Christian

PS Oh, and I tried casting to float and explicitly to double, too. Same
result as without the casts.

Jun 27 '08 #1
3 2676
Hi,
Hi,

currently I have a problem understanding Py_BuildValue. I have this code:

static PyObject *function(PyObject *self, PyObject *args) {
PyObject * python_return_value = NULL;
PyObject * dummy = NULL;
double * internal_list;
<snip and forget the rest>

/* converting to python representation */
for (i=0; i < limit; i++) {
dummy = Py_BuildValue("d", internal_list[i]);
if (!dummy) return NULL;
PyList_Append(python_return_value, dummy);
Py_DECREF(dummy); dummy = NULL;
}
return python_return_value
}

This doesn't work. What I see, when invoking the function "function()" in
Python is a list of refcounts, like: [<refcnt 0 at 0x94a29d4>, <refcnt 0 at
0x94a29e4>, ...]. However, if I change the Py_BuildValue-line to be
dummy = Py_BuildValue("i", (int)internal_list[i]);
I do get the 'right' integer return values. Point is that I really would
like to work with Python-floats afterwards.

Any idea where a pitfall might be here?
I see nothing wrong with your code so I'd say it is somewhere else (did you
snip any code between the end of the loop and the return?). I've never seen
those 'refcnt' objects but a refcount of 0 sounds like you unrefed your
objects one extra time by mistake. This would produce a segfault on unix, but
maybe not on all platforms ? You should check the return value of
PyList_Append() and if it doesn't help trace the content of your list after
each iteration to see when the bad things happen (you can check the reference
count of an object with obj->ob_refcnt).

Finally note that in your case it would be much simpler and more efficient to
use the float constructor directly:

dummy = PyFloat_FromDouble(internal_list([i]))

PS: always use Py_CLEAR(dummy) instead of Py_DECREF(dummy); dummy=NULL;
(though it doesn't really matter in this simple case - see
http://docs.python.org/api/countingRefs.html)

--
Cédric Lucantis
Jun 27 '08 #2
Thank you. At least I can exclude another few error sources, now.

CĂ©dric Lucantis wrote:
I see nothing wrong with your code so I'd say it is somewhere else (did
you snip any code between the end of the loop and the return?).
No. (Apart from freeing allocated memory.)
I've never
seen those 'refcnt' objects but a refcount of 0 sounds like you unrefed
your objects one extra time by mistake. This would produce a segfault on
unix, but maybe not on all platforms ?
Well, I am working on Linux. Python 2.5.1, gcc 4.1.3 . And I do not see
segfaults until I start working in Python with the return value of that
function, of course.
You should check the return value
of PyList_Append()
It is always 0, regardless of what I do.
and if it doesn't help trace the content of your list
after each iteration to see when the bad things happen (you can check the
reference count of an object with obj->ob_refcnt).
Seems ok. What I did to check this was placing this after building the list:

for (i=0; i < limit; i++) {
dummy = PyList_GetItem(python_return_value, i);
printf("%f\n", PyFloat_AsDouble(dummy));
Py_CLEAR(dummy);
}

Which gives reasonable numbers.
>
Finally note that in your case it would be much simpler and more efficient
to use the float constructor directly:

dummy = PyFloat_FromDouble(internal_list([i]))
I tried that (actually PyFloat_FromDouble(internal_list[i]) ): Same thing,
but now more like [<refcnt -1 at 0x94a474c>, <refcnt -1 at 0x94a475c>, etc.
(Note the -1.)
>
PS: always use Py_CLEAR(dummy) instead of Py_DECREF(dummy); dummy=NULL;
(though it doesn't really matter in this simple case - see
http://docs.python.org/api/countingRefs.html)
Good idea! Since I require 2.4 for users anyway, there is no harm in
reducing the code.

Christian

Jun 27 '08 #3
Thank you so much - I was such an idiot (see below).
>>I see nothing wrong with your code so I'd say it is somewhere else (did
you snip any code between the end of the loop and the return?).
>>No. (Apart from freeing allocated memory.)

I'm pretty sure we'll find something interesting here :)
Still not. I was about to prove it and already uploaded the file, when I
saw, what was really going wrong ...
>
PyList_GetItem returns a borrowed reference so you shoud _not_ unref it
(this explains the refcnt -1 I think)
This is THE crucial point. If I just delete the Py_CLEAR-line, everything is
working smoothly and calling PyFloat_FromDouble-is working too.

Again: Thanks a lot. 'Reference counting' won't become one of my
hobbies ;-).

Best,
Christian
Jun 27 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: ashtonn | last post by:
Hello, How do i print values returned by Py_BuildValue in Linux? PyObject *obj = Py_BuildValue("{s:i}", "Status", status); I need to print the Status value here -Thanks, Ashton
6
by: ajikoe | last post by:
Hello I tried to combine c++ and python together. So I follow from this website: http://kortis.to/radix/python_ext/ I have this code: # prmodule.c static PyObject *pr_isprime(PyObject *self,...
5
by: Christian Meesters | last post by:
Hi I'm having trouble with Py_BuildValue. I was able to pinpoint the following statement as the one causing a seg. fault with my script: static PyObject * funcname(PyObject *self, PyObject...
4
by: spectrumdt | last post by:
Hello. I am trying to extend Python with some C code. I made a trivial "Hello World" program in C that I am trying to wrap in "boilerplate" for inclusion in a Python program. But I can't compile...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.