What is the meaning of Py_INCREF a static PyTypeObject?

Jason Swails jason.swails at gmail.com
Thu Nov 12 13:52:10 EST 2015


On Thu, Nov 12, 2015 at 3:05 AM, Xiang Zhang <18518281186 at 126.com> wrote:

> Recently I am learning Python C API.
>
> When I read the tutorial <
> https://docs.python.org/3/extending/newtypes.html#the-basics>, defining
> new types, I feel confused. After PyType_Ready(&noddy_NoddyType) comes
> Py_INCREF(&noddy_NoddyType). Actually noddy_NoddyType is a static struct so
> I don't understand why I need to Py_INCREF it. Since it's Py_INCREFed, does
> it mean sometimes we also need to Py_DECREF it? But then it seems that
> type_dealloc will be invoked and it will fail assert(type->tp_flags &
> Py_TPFLAGS_HEAPTYPE);
>

​It is a module attribute, so when the module is imported it has to have a
single reference (the reference *in* the module).  If you don't INCREF it,
then it will have a refcount of 0, and immediately be ready for garbage
collection.  So if you try to use the type from the module, you could get a
segfault because it's trying to use an object (type definition) that was
already destroyed.

Note that you don't *always* have to INCREF objects after you create them
in C.  Some macros and function do that for you.  And in some cases, all
you want or need is a borrowed reference.  In those cases, Py_INCREF is
unnecessary.

The DECREF will be done when it's normally done in Python.  If you do
something like

import noddy
del noddy.NoddyType

​All that's really doing is removing NoddyType from the noddy namespace and
Py_DECREFing it.  Alternatively, doing

import noddy
noddy.NoddyType = 10 # rebind the name

Then the original object NoddyType was pointing to will be DECREFed and
NoddyType will point to an object taking the value of 10.

HTH,
Jason



More information about the Python-list mailing list