https://github.com/python/cpython/commit/21403afa9ba5baa63dc7dd7cf6e109c335d26bb4
commit: 21403afa9ba5baa63dc7dd7cf6e109c335d26bb4
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-09-17T13:45:31+02:00
summary:
gh-142217: Add tests on the deprecated _Py_Identifier C API (#157638)
Replace also PyDict_GetItemWithError() with PyDict_GetItemRef()
and remove outdated comment in Modules/_pickle.c.
files:
A Misc/NEWS.d/next/C_API/2026-09-16-21-24-36.gh-issue-142217.44sqt4.rst
M Modules/_pickle.c
M Modules/_testcapi/unicode.c
M Tools/c-analyzer/cpython/ignored.tsv
diff --git
a/Misc/NEWS.d/next/C_API/2026-09-16-21-24-36.gh-issue-142217.44sqt4.rst
b/Misc/NEWS.d/next/C_API/2026-09-16-21-24-36.gh-issue-142217.44sqt4.rst
new file mode 100644
index 000000000000000..7d48e27d8a83409
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2026-09-16-21-24-36.gh-issue-142217.44sqt4.rst
@@ -0,0 +1,2 @@
+Add tests on the undocumented and deprecated ``_Py_Identifier`` C API. Patch
+by Victor Stinner.
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 90200a4379319d9..5339337741d2f27 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -4745,17 +4745,9 @@ save(PickleState *st, PicklerObject *self, PyObject
*obj, int pers_save)
* __reduce_ex__ method, or the object's __reduce__ method.
*/
if (self->dispatch_table == NULL) {
- reduce_func = PyDict_GetItemWithError(st->dispatch_table,
- (PyObject *)type);
- if (reduce_func == NULL) {
- if (PyErr_Occurred()) {
- goto error;
- }
- } else {
- /* PyDict_GetItemWithError() returns a borrowed reference.
- Increase the reference count to be consistent with
- PyObject_GetItem and _PyObject_GetAttrId used below. */
- Py_INCREF(reduce_func);
+ if (PyDict_GetItemRef(st->dispatch_table, (PyObject *)type,
+ &reduce_func) < 0) {
+ goto error;
}
}
else if (PyMapping_GetOptionalItem(self->dispatch_table, (PyObject *)type,
diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c
index 915c9230f66b52e..e4017efd19237fd 100644
--- a/Modules/_testcapi/unicode.c
+++ b/Modules/_testcapi/unicode.c
@@ -227,6 +227,55 @@ unicode_GET_CACHED_HASH(PyObject *self, PyObject *arg)
}
+// Test the deprecated _Py_Identifier C API:
+// - _Py_IDENTIFIER()
+// - _Py_static_string()
+// - _Py_static_string_init()
+// - _PyObject_CallMethodId()
+// - _PyObject_GetAttrId()
+// - _PyUnicode_FromId()
+//
+// _testembed also has tests on _PyUnicode_FromId().
+static PyObject*
+test_py_identifier(PyObject *self, PyObject *Py_UNUSED(args))
+{
+// Ignore deprecation warnings
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+
+ _Py_IDENTIFIER(hello);
+ PyObject *str = _PyUnicode_FromId(&PyId_hello); // borrowed ref
+ if (str == NULL) {
+ return NULL;
+ }
+ assert(PyUnicode_EqualToUTF8(str, "hello") == 1);
+
+ // Calling twice return the same object
+ PyObject *str2 = _PyUnicode_FromId(&PyId_hello); // borrowed ref
+ assert(str2 == str);
+
+ PyObject *number = Py_GetConstant(Py_CONSTANT_ONE); // immortal
+ _Py_static_string(to_bytes_id, "to_bytes");
+ PyObject *res = _PyObject_CallMethodId(number, &to_bytes_id, NULL);
+ if (res == NULL) {
+ return NULL;
+ }
+ Py_DECREF(res);
+
+ static _Py_Identifier real_id = _Py_static_string_init("real");
+ res = _PyObject_GetAttrId(number, &real_id);
+ if (res == NULL) {
+ return NULL;
+ }
+ assert(res == number);
+ Py_DECREF(res);
+
+ Py_RETURN_NONE;
+
+_Py_COMP_DIAG_POP
+}
+
+
// --- PyUnicodeWriter type -------------------------------------------------
typedef struct {
@@ -572,6 +621,7 @@ static PyMethodDef TestMethods[] = {
{"unicode_asutf8", unicode_asutf8, METH_VARARGS},
{"unicode_copycharacters", unicode_copycharacters, METH_VARARGS},
{"unicode_GET_CACHED_HASH", unicode_GET_CACHED_HASH, METH_O},
+ {"test_py_identifier", test_py_identifier, METH_NOARGS},
{NULL},
};
diff --git a/Tools/c-analyzer/cpython/ignored.tsv
b/Tools/c-analyzer/cpython/ignored.tsv
index 4c143164650a2ba..cddfeb02c4b8597 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -787,7 +787,9 @@ Modules/clinic/grpmodule.c.h grp_getgrgid
_keywords -
Modules/clinic/grpmodule.c.h grp_getgrnam _keywords -
Objects/object.c - constants static PyObject*[]
Objects/dictobject.c - PyFrozenDict_Type -
-
+Modules/_testcapi/unicode.c test_py_identifier PyId_hello -
+Modules/_testcapi/unicode.c test_py_identifier to_bytes_id -
+Modules/_testcapi/unicode.c test_py_identifier real_id -
## False positives
Python/specialize.c - _Py_InitCleanup -
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]