C API: How much private is the private _Py_IDENTIFIER() API?

I wrote gh-106320: Remove private _Py_Identifier API by vstinner · Pull Request #108593 · python/cpython · GitHub to remove the private _Py_identifier from the public C API (move it to the internal C API). This change is part of my larger plan on removing private API: C API: My plan to clarify private vs public functions in Python 3.13.

If the number of affected projects is low, the solution is to guide them towards static/global variables to cache strings (call PyUnicode_FromUnicode() only once), and then use this string. Or just use the bytes string functions, variants with the String suffix like PyDict_GetItemStringRef().

If there are many affected projects, another option is to expose the bare minimum to the public C API:

  • Py_IDENTIFIER(name) macro
  • PyUnicode_FromId(&PyId_name) function
  • Py_Identifier structure with its members (needed by Py_IDENTIFIER() macro)
  • and maybe also the Py_static_string(name, "...") macro for strings which are not valid C identifiers.

I dislike exposing the Py_Identifier structure :frowning: Its members already changed when I added support for sub-interpreters, so it’s not implementation-agnostic :frowning:

As I wrote before, if possible, I would prefer to not add this API to the public C API.

Maybe a brand new API should be design? Or PyUnicode_FromString() should be optimized? Would it be possible to design a LRU cache on PyUnicode_FromString() which would be more efficient… than not using a cache? Computing a cache key requires to hash the byte string which is not free in terms of performance.