-1

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?

Nima Mousavi
  • 1,601
  • 2
  • 21
  • 30

1 Answers1

1

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.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • Thanks for your answer, but maybe my question wasnt detailed enough. What I mean is: What is the purpose of Py_DECREF(Py_None)? I have a C extension where I call a Python method from C and that method returns None. I can decref it, but it doesnt do anything. As I said I'd literally have to decref it 30000 times for it to make a difference. I'd have expected that if I'd use Py_DECREF twice on it, then it would cause a crash, but apparently it doesnt matter. – Nima Mousavi Jan 02 '23 at 11:28
  • @NimaMousavi: It would be unusual to do `Py_DECREF(Py_None)`, as `Py_None` is a reference you do not own. It is, however, perfectly normal to do `Py_DECREF(some_var)` if `some_var` holds a reference that is about to be destroyed, even if that reference is to `None`. – user2357112 Jan 02 '23 at 11:33
  • That is exactly what happens. I use Py_DECREF on that variable, which happens to be Py_None. I am just confused by the fact that I can Py_DECREF it 10000 times at that particular point and my program would still finish without a problem. – Nima Mousavi Jan 02 '23 at 11:35
  • Python does not promise to crash if you do things wrong at C level. C programs generally cannot make such promises. There are plenty of things you can do wrong in C that might seem to work, until some trigger you likely have no idea about causes everything to fall apart in arbitrarily bad ways. – user2357112 Jan 02 '23 at 11:38