Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Python C API and references

Reply
Thread Tools

Python C API and references

 
 
lallous
Guest
Posts: n/a
 
      11-12-2009
Hello,

Everytime I use PyObject_SetAttrString(obj, attr_name, py_val) and I don't
need the reference to py_val I should decrement the reference after this
call?

So for example:

PyObject *py_val = PyInt_FromLong(5)
PyObject_SetAttrString(py_obj, "val", py_val);
Py_DECREF(py_val)

Right?

If so, take sysmodule.c:

if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)
return NULL;

Shouldn't they also call Py_DECREF(Py_None) ?

Same logic applies to PyDict_SetItemString() and the reference should be
decrement after setting the item (ofcourse if the value is not needed).

--
Elias

 
Reply With Quote
 
 
 
 
lallous
Guest
Posts: n/a
 
      11-12-2009
Hello Daniel,

Thanks for the reply.

>>
>> Everytime I use PyObject_SetAttrString(obj, attr_name, py_val) and I
>> don't
>> need the reference to py_val I should decrement the reference after this
>> call?

>
> It really depends on /how/ the object is created. If the
> method used to create *py_val* increases the reference count
> on the object and another function any other function is
> used to increase the reference count, you should use Py_DECREF
> or Py_XDECREF.
>
>>
>> So for example:
>>
>> PyObject *py_val = PyInt_FromLong(5)
>> PyObject_SetAttrString(py_obj, "val", py_val);
>> Py_DECREF(py_val)
>>
>> Right?

>
> In this case is right. *PyInt_FromLong()* returns a new
> reference: 'Return value: New reference.', which is increasing
> the reference count and PyObject_SetAttrString does it twice,
> then you have a reference count of two and you need to decrement
> the initial reference counting of the object, or you will have
> a memory leak.
>


Quote:
int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)
Set the value of the attribute named attr_name, for object o, to the value
v. Returns -1 on failure. This is the equivalent of the Python statement
o.attr_name = v.
int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
Set the value of the attribute named attr_name, for object o, to the value
v. Returns -1 on failure. This is the equivalent of the Python statement
o.attr_name = v.
Looking at the documentation, should I have understood that the passed value
reference will be incremented and that I should decrement it if I don't need
it?

Or I should have understood just because of the fact that whenever we have x
= b (be it from the C api in a form of SetAttr()) then we should know that
b's reference will be incremented. ?

Because, before this discussion I did not know I should decrease the
reference after SetAttr()

>>
>> If so, take sysmodule.c:
>>
>> if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)
>> return NULL;
>>
>> Shouldn't they also call Py_DECREF(Py_None) ?

>
> No, I think that Py_None do not needs to decrease the
> reference count...
>


None is an object like other objects. I think its reference must be taken
into consideration too, for instance why there is the convenience macro:
Py_RETURN_NONE ?

--
Elias

 
Reply With Quote
 
 
 
 
Mark Dickinson
Guest
Posts: n/a
 
      11-12-2009
On Nov 12, 9:23*am, "lallous" <(E-Mail Removed)> wrote:
> Hello,
>
> Everytime I use PyObject_SetAttrString(obj, attr_name, py_val) and I don't
> need the reference to py_val I should decrement the reference after this
> call?


Not necessarily: it depends where py_val came from. I find the
'ownership' model described in the docs quite helpful:

http://docs.python.org/c-api/intro.h...-count-details

It's probably better to read the docs, but here's a short version:

If you create a reference to some Python object in a function in your
code, you then 'own' that reference, and you're responsible for
getting rid of it by the time the function exits. There are various
ways this can happen: you can return the reference, thereby
transferring ownership to the calling function; you can explicitly
discard the reference by calling Py_DECREF; or you can transfer
ownership by calling a function that 'steals' the reference (most
functions in the C-API don't steal references, but rather borrow them
for the duration of the function call).

>
> So for example:
>
> PyObject *py_val = PyInt_FromLong(5)
> PyObject_SetAttrString(py_obj, "val", py_val);
> Py_DECREF(py_val)
>
> Right?


Yes. Here you've created the reference in the first place, so you
should Py_DECREF it before you exit. Right after the
PyObject_SetAttrString call is a good place to do this.

>
> If so, take sysmodule.c:
>
> * * * * if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)
> * * * * * * * * return NULL;
>
> Shouldn't they also call Py_DECREF(Py_None) ?


No, I don't think so. I assume you're looking at the sys_displayhook
function? This function doesn't create new references to Py_None
(well, except when it's about to return Py_None to the caller), so at
this point it doesn't own any reference to Py_None: it's not
responsible for decrementing the reference count.

> Same logic applies to PyDict_SetItemString()


Yes.


--
Mark
 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      11-13-2009
En Thu, 12 Nov 2009 06:23:54 -0300, lallous <(E-Mail Removed)> escribió:

> Everytime I use PyObject_SetAttrString(obj, attr_name, py_val) and I
> don't need the reference to py_val I should decrement the reference
> after this call?


If you own a reference to py_val, and you don't need it anymore, you must
decrement it. It doesn't matter if you call PyObject_SetAttrString or
whatever, except when the called function says it "steals" a reference.

> So for example:
>
> PyObject *py_val = PyInt_FromLong(5)
> PyObject_SetAttrString(py_obj, "val", py_val);
> Py_DECREF(py_val)
>
> Right?


Yes, because PyInt_FromLong returns a new reference, and you own it.

> If so, take sysmodule.c:
>
> if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)
> return NULL;
>
> Shouldn't they also call Py_DECREF(Py_None) ?


No, because the reference count of Py_None was not incremented previously;
the code doesn't own a reference to Py_None at that time. It's not the
same as the example above.

> Same logic applies to PyDict_SetItemString() and the reference should be
> decrement after setting the item (ofcourse if the value is not needed).


Yes, same as your first example.

--
Gabriel Genellina

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Snake references just as ok as Monty Python jokes/references in python community? :) seberino@spawar.navy.mil Python 8 12-12-2006 11:21 PM
Difference between bin and obj directories and difference between project references and dll references jakk ASP .Net 4 03-22-2005 09:23 PM
Calling the C API from Python and Python program from same C API -bidirectional Praveen, Tayal (IE10) Python 0 03-17-2005 06:33 AM
how to understand references to variables and references to constants are distinguished? baumann.Pan@gmail.com C++ 3 11-10-2004 04:16 AM
Pointers and References (and References to Pointers) Roger Leigh C++ 8 11-17-2003 10:14 AM



Advertisments