Is Py_None part of the limited API?

I’m one of the developers of the Python interface of igraph, a C library for the analysis of large graphs. We are currently in the process of migrating the Python interface to the limited API so we can provide a single Python wheel per platform for all supported Python versions instead of publishing separate ones.

It has been brought to my attention that the current version of the Python interface does not build with PyPy 3.8 and above because it defines Py_LIMITED_API to 0x03060100 but keeps on using Py_None, which is apparently not part of the limited API. Indeed, it is not listed there; on the other hand, the code compiles just fine with all supported versions of CPython from 3.7 up to 3.10.

My questions are:

  • Is Py_None part of the limited API or not?
  • Similarly, are Py_True and Py_False part of the limited API or not? They do not seem to be listed either, but our code compiles fine.
  • If Py_None is not part of the limited API, how is one supposed to get hold of a reference to Py_None with the limited API? I know that Py_BuildValue("") is supposed to return Py_None, but it seems overkill to call Py_BuildValue() every time I need a reference to Py_None (which happens frequently because Py_None is the default value for many optional arguments that we parse with Py_ParseTupleAndKeywords).
1 Like

Somewhat late to the topic, but…

I’ve just been wondering this myself, and I hadn’t realised that you could get it via Py_BuildValue.

That being the case, Py_BuildValue should be returning the same pointer as Py_None because None is a singleton, but INCREFed. You could just store that in a static variable and DECREF it either when the module terminates or, probably safely, when you get it from Py_BuildValue (and I say “probably safely” because I’d expect the refcount to already be >1).