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