Re: Python C API and references

2009-11-13 Thread Gabriel Genellina

En Thu, 12 Nov 2009 06:23:54 -0300, lallous  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

--
http://mail.python.org/mailman/listinfo/python-list


Re: Python C API and references

2009-11-12 Thread Mark Dickinson
On Nov 12, 9:23 am, "lallous"  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.html#reference-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
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python C API and references

2009-11-12 Thread lallous

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.

[/quote]

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 


--
http://mail.python.org/mailman/listinfo/python-list


Python C API and references

2009-11-12 Thread lallous

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 


--
http://mail.python.org/mailman/listinfo/python-list