Skip to content

[C API] Deprecate _Py_Identifier API #142217

Description

@vstinner

I 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

Activity

  1. added a commit that references this issue on Dec 3, 2025
  2. added
    type-featureA feature request or enhancement
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    on Dec 3, 2025
  3. added 2 commits that reference this issue on Dec 3, 2025
  4. added a commit that references this issue on Dec 6, 2025
  5. added a commit that references this issue on Dec 12, 2025
  6. cdce8p commented on Dec 14, 2025

    @cdce8p
    Contributor

    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

  7. encukou commented on Dec 15, 2025

    @encukou
    Member

    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?

  8. added a commit that references this issue on Dec 15, 2025
  9. vstinner commented on Dec 15, 2025

    @vstinner
    MemberAuthor

    @vstinner: would PyUnicode_InternFromString be a better suggested replacement than PyUnicode_FromString?

    Oh, good idea: I wrote #142746 to update the documentation.

  10. added a commit that references this issue on Dec 15, 2025
  11. added a commit that references this issue on Dec 16, 2025
  12. vstinner commented on Dec 16, 2025

    @vstinner
    MemberAuthor

    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.

  13. cdce8p commented on Dec 22, 2025

    @cdce8p
    Contributor

    This is what I got working for mypy: python/mypy#20460
    It's heavily inspired by the numpy implementation.

  14. added 3 commits that reference this issue on Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions