What is the meaning of Py_INCREF a static PyTypeObject?
Xiang Zhang
18518281186 at 126.com
Thu Nov 12 22:08:27 EST 2015
Thanks for your reply jason. Your reply does give me hints and then I
read more code and find maybe you are wrong in some points.
I think the meaning of Py_INCREF a static type object is to prevent it
from being deallocated when it is Py_DECREFed somehow later. Just as you
said, it may be somehow deallocated when using.
NoddyType is a static struct so I don't think it lives on Python's heap
and deallocating it is a wrong action. Just as I mentioned, type_dealloc
seems to only deallocated HEAPTYPE. And by the way, when NoddyType is
created, it has a reference count 1 with PyVarObject_HEAD_INIT. So if I
don't Py_INCREF it, when it is somehow Py_DECREDed later, it will reach
reference count 0 and fail the assert in type_dealloc. If it is
Py_INCREFed, just like the module holds a reference to it, it will at
least have a reference count 1 and never reach 0.
On 11/13/2015 02:52 AM, Jason Swails wrote:
>
>
> On Thu, Nov 12, 2015 at 3:05 AM, Xiang Zhang <18518281186 at 126.com
> <mailto: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