Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of Py_DECREF and PY_INCREF?

I was going through the tutorial for defining 'new types' in python, https://docs.python.org/2/extending/newtypes.html, and I did not understand the purpose of using Py_DECREF in this piece of code.

static PyObject *
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    Noddy *self;

    self = (Noddy *)type->tp_alloc(type, 0);
    if (self != NULL) {
        self->first = PyString_FromString("");
        if (self->first == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->last = PyString_FromString("");
        if (self->last == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->number = 0;
    }

    return (PyObject *)self;
}

My understanding of reference counting is patchy and any help would be appreciated.

like image 357
Nihal Harish Avatar asked Jun 27 '14 05:06

Nihal Harish


People also ask

What is Py_DECREF?

void Py_DECREF(PyObject *o) Decrement the reference count for object o. If the reference count reaches zero, the object's type's deallocation function (which must not be NULL ) is invoked. This function is usually used to delete a strong reference before exiting its scope.

What is a PyObject?

PyObject is an object structure that you use to define object types for Python. All Python objects share a small number of fields that are defined using the PyObject structure. All other object types are extensions of this type. PyObject tells the Python interpreter to treat a pointer to an object as an object.

What is reference counting in Python?

Reference counting is one of the memory management technique in which the objects are deallocated when there is no reference to them in a program. Let's try to understand with examples. Variables in Python are just the references to the objects in the memory.


1 Answers

In this case, Py_DECREF would simply free the memory allocated with tp->alloc.

tp->alloc sets the ref count to 1. Py_DECREF decreases the ref count from 1 to 0; as it finds the ref count is 0, it calls the appropriate functions to free the memory (Noddy_dealloc in this case.)

If a python C api function returns NULL, something has gone wrong; usually an exception is set (saved in a global variable).

If the caller returns NULL again, the exception is chained, hence the 'return NULL'.

like image 131
Yu Feng Avatar answered Oct 07 '22 00:10

Yu Feng