A Python Boolean is described as follows in the documentation:
Booleans in Python are implemented as a subclass of integers. There are only two booleans, Py_False and Py_True.
The Py_False
and Py_True
are, as I understand it, singletons corresponding to False
and True
respectively.
Indeed, the following returns True
in my Jupyter notebook:
a = True
b = True
a is b
False
works the same way.
The PyBool_FromLong
method (code here) creates a new Boolean object from a long
. However, it creates an entirely new pointer to it and increments the reference count before returning it:
PyObject *PyBool_FromLong(long ok)
{
PyObject *result;
if (ok)
result = Py_True;
else
result = Py_False;
return Py_NewRef(result);
}
The Py_True
and Py_False
are defined as follows:
/* Py_False and Py_True are the only two bools in existence.
Don't forget to apply Py_INCREF() when returning either!!! */
/* Don't use these directly */
PyAPI_DATA(PyLongObject) _Py_FalseStruct;
PyAPI_DATA(PyLongObject) _Py_TrueStruct;
/* Use these macros */
#define Py_False _PyObject_CAST(&_Py_FalseStruct)
#define Py_True _PyObject_CAST(&_Py_TrueStruct)
The comments above are quite insistent that you increment the reference count when returning either, and that's exactly what the method I showed above does. I'm somewhat confused as to why this is necessary, though, since (as I understand it) these are just singletons that will never be garbage collected.
I was able to find this Q&A about whether incrementing the ref count is always necessary, but I'm still confused about why it's needed in the first place, given that the True
and False
objects are singletons that would never be garbage collected.
I'm not sure if I'm missing something obvious, but can someone explain why it's necessary to increment the reference count when returning a reference to Py_False
or Py_True
? Or is this to prevent the object from ever being garbage collected?