GeezerVison is showing github.com — [C API] Deprecate _Py_Identifier API · Issue #142217 · python/cpython
[C API] Deprecate _Py_Identifier API #142217DescriptionI propose to deprecate the private _Py_Identifier API.
- Deprecate private
_PyObject_CallMethodId(), _PyObject_GetAttrId(), _PyUnicode_FromId().
- Remove immediately internal functions using
_Py_Identifier.
See also the discussions:
Since 2022, CPython has been modified to replace _Py_IDENTIFIER() with _Py_STR(). Python no longer uses the _Py_IDENTIFIER() API anymore.
See also issue #141049 "Deprecate private C API functions".
Linked PRs
Activitycdce8p commented on Dec 14, 2025 I just tested the latest cpython build against mypy. #142221 is causing a lot of errors with -Werror,-Wdeprecated-declarations. Yes it's possible to replace most _Py_IDENTIFIER calls with PyUnicode_FromString, see python/mypy@f287f7d, but I'm not sure this is the right call here. The discuss thread mentions the need / desire for an API to get/create immortal strings, has there been any progress for it?
cpython itself uses &_Py_ID in a lot of places. These could actually also be used by mypy in most cases though I don't think it's intended that way. python/mypy@dbbc992 encukou commented on Dec 15, 2025
The discuss thread mentions the need / desire for an API to get/create immortal strings, has there been any progress for it?
Not really.
Note that CPython's immortal strings (_Py_STR) are statically allocated, in a way that requires code generation with lots of knowledge about the internals, and taking advantage of the fact that there are no conflicts.
We unfortunately can't provide that exact API to extensions -- if two of those intern the same string, only one can “win”.
AFAIK, we can't really make _Py_IDENTIFIER substantially better than users calling if(!x) {x = PyUnicode_InternFromString("...");} on init, and Py_CLEAR(x) on teardown.
The advantage of _Py_Identifier is the ease of use -- in particular, the teardown is automatic. But it comes at the cost of an elaborate (and largely untested) mechanism to make everything work correctly.
cpython itself uses &_Py_ID in a lot of places. These could actually also be used by mypy in most cases though I don't think it's intended that way.
Don't do that, this uses internal ABI that will break in patch releases. As in: it does break in practice in patch releases, it's not a CYA theoretical possibility.
@vstinner: would PyUnicode_InternFromString be a better suggested replacement than PyUnicode_FromString? vstinner commented on Dec 15, 2025
@vstinner: would PyUnicode_InternFromString be a better suggested replacement than PyUnicode_FromString?
Oh, good idea: I wrote #142746 to update the documentation. added a commit that references this issue on Dec 15, 2025gh-142217: Recommend PyUnicode_InternFromString() to replace _PyUnico… vstinner commented on Dec 16, 2025
Yes it's possible to replace most _Py_IDENTIFIER calls with PyUnicode_FromString, see python/mypy@f287f7d, but I'm not sure this is the right call here.
Yes, it's a safe replacement. To avoid negative impact on performance, you might try to only decode bytes strings (char*) from UTF-8 once by storing the object (PyObject*) in a module state, if possible.
I close the issue since the APIs are now deprecated. cdce8p commented on Dec 22, 2025 This is what I got working for mypy: python/mypy#20460
It's heavily inspired by the numpy implementation. Reacted by Victor Stinner
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|