Here's a useful explanation of INCREF()
and DECREF()
(after an original by Sjoerd Mullender).
Use XINCREF()
or XDECREF()
instead of INCREF()
or
DECREF()
when the argument may be NULL
- the versions
without `X' are faster but wull dump core when they encounter a
NULL
pointer.
The basic idea is, if you create an extra reference to an object, you
must INCREF()
it, if you throw away a reference to an object,
you must DECREF()
it. Functions such as
newstringobject()
, newsizedstringobject()
,
newintobject()
, etc. create a reference to an object. If you
want to throw away the object thus created, you must use
DECREF()
.
If you put an object into a tuple or list using settupleitem()
or setlistitem()
, the idea is that you usually don't want to
keep a reference of your own around, so Python does not
INCREF()
the elements. It does DECREF()
the old value.
This means that if you put something into such an object using the
functions Python provides for this, you must INCREF()
the
object if you also want to keep a separate reference to the object around.
Also, if you replace an element, you should INCREF()
the old
element first if you want to keep it. If you didn't INCREF()
it before you replaced it, you are not allowed to look at it anymore,
since it may have been freed.
Returning an object to Python (i.e. when your C function returns)
creates a reference to an object, but it does not change the reference
count. When your code does not keep another reference to the object,
you should not INCREF()
or DECREF()
it (assuming it is a
newly created object). When you do keep a reference around, you
should INCREF()
the object. Also, when you return a global
object such as None
, you should INCREF()
it.
If you want to return a tuple, you should consider using
mkvalue()
. This function creates a new tuple with a reference
count of 1 which you can return. If any of the elements you put into
the tuple are objects (format codes `O' or `S'), they
are INCREF()
'ed by mkvalue()
. If you don't want to keep
references to those elements around, you should DECREF()
them
after having called mkvalue()
.
Usually you don't have to worry about arguments. They are
INCREF()
'ed before your function is called and
DECREF()
'ed after your function returns. When you keep a
reference to an argument, you should INCREF()
it and
DECREF()
when you throw it away. Also, when you return an
argument, you should INCREF()
it, because returning the
argument creates an extra reference to it.
If you use getargs()
to parse the arguments, you can get a
reference to an object (by using `O' in the format string). This
object was not INCREF()
'ed, so you should not DECREF()
it. If you want to keep the object, you must INCREF()
it
yourself.
If you create your own type of objects, you should use NEWOBJ()
to create the object. This sets the reference count to 1. If you
want to throw away the object, you should use DECREF()
. When
the reference count reaches zero, your type's dealloc()
function is called. In it, you should DECREF()
all object to
which you keep references in your object, but you should not use
DECREF()
on your object. You should use DEL()
instead.