While reading through the documentation and some SO questions, I learned that Py_INCREF() should be applied to Py_None and that applying Py_DECREF() to Py_None is a bad idea unless you hold a reference to it.
But when I look up the reference count of Py_None:
from sys import getrefcount
print(getrefcount(None))
It's at 34169. I'd have to Py_DECREF in a loop 30000 times to make my interpreter crash. A single INCREF or DECREF doesnt do anything. Can anybody explain?
CodePudding user response:
There are just a lot of references to None
, all over the place. Many of them are implicitly created, like __doc__
for functions and classes with no docstring, or the first element of every code object's co_consts
, but plenty are created explicitly. The refcount is a count of those references.
You should not treat None
specially when managing references. As with any other object, Py_INCREF
and Py_DECREF
should be used when you create or destroy a reference to the object in C code, if some other code isn't responsible for that.
I'd have to Py_DECREF in a loop 30000 times to make my interpreter crash.
Okay. So you write a function that mismanages its refcounting and incorrectly decrements None
's refcount by 1.
Then your function gets called 30000 times. That's a completely unremarkable number of times to call a function. Your program crashes, quite likely in a location completely unrelated to your broken function, when unrelated reference manipulation somewhere else causes the refcount of None
to hit 0 because the value was already too low due to your function.
Or maybe your function only gets called 10000 times. Then, later, when your program is shutting down, most of those None
references get cleaned up, and your program crashes messily during shutdown when the refcount of None
hits 0 anyway. Maybe that means your program fails to save important data. Maybe it just means your program produces a really unprofessional-looking error message every time it shuts down. Either way, customers are unhappy, and you've got a nasty bug to debug.