On Thu, Nov 12, 2015 at 3:05 AM, Xiang Zhang <18518281...@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
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to