diff --git a/pythoncapi_compat.h b/pythoncapi_compat.h index 7586485..ae0a1a4 100644 --- a/pythoncapi_compat.h +++ b/pythoncapi_compat.h @@ -819,6 +819,21 @@ static inline int Py_IsFinalizing(void) #endif +// gh-108323 added PyDict_ContainsString() to Python 3.13.0a1 +#if PY_VERSION_HEX < 0x030D00A1 +static inline int PyDict_ContainsString(PyObject *op, const char *key) +{ + PyObject *key_obj = PyUnicode_FromString(key); + if (key_obj == NULL) { + return -1; + } + int res = PyDict_Contains(op, key_obj); + Py_DECREF(key_obj); + return res; +} +#endif + + #ifdef __cplusplus } #endif diff --git a/tests/test_pythoncapi_compat_cext.c b/tests/test_pythoncapi_compat_cext.c index 0213556..0f6dae6 100644 --- a/tests/test_pythoncapi_compat_cext.c +++ b/tests/test_pythoncapi_compat_cext.c @@ -1092,7 +1092,7 @@ test_getitem(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) static PyObject * -test_dict_getitemref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) +test_dict_api(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) { assert(!PyErr_Occurred()); @@ -1112,12 +1112,18 @@ test_dict_getitemref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) if (key == NULL) { goto error; } + invalid_dict = key; // borrowed reference missing_key = PyUnicode_FromString("missing_key"); if (missing_key == NULL) { goto error; } + invalid_key = PyList_New(0); // not hashable key + if (invalid_key == NULL) { + goto error; + } + value = PyUnicode_FromString("value"); if (value == NULL) { goto error; @@ -1129,6 +1135,17 @@ test_dict_getitemref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) } assert(res == 0); + // test PyDict_Contains() + assert(PyDict_Contains(dict, key) == 1); + assert(PyDict_Contains(dict, missing_key) == 0); + + // test PyDict_ContainsString() + assert(PyDict_ContainsString(dict, "key") == 1); + assert(PyDict_ContainsString(dict, "missing_key") == 0); + assert(PyDict_ContainsString(dict, "\xff") == -1); + assert(PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)); + PyErr_Clear(); + // test PyDict_GetItemRef(), key is present get_value = Py_Ellipsis; // marker value assert(PyDict_GetItemRef(dict, key, &get_value) == 1); @@ -1154,7 +1171,6 @@ test_dict_getitemref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) assert(get_value == NULL); // test PyDict_GetItemRef(), invalid dict - invalid_dict = key; // borrowed reference get_value = Py_Ellipsis; // marker value assert(PyDict_GetItemRef(invalid_dict, key, &get_value) == -1); assert(PyErr_ExceptionMatches(PyExc_SystemError)); @@ -1168,11 +1184,6 @@ test_dict_getitemref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) PyErr_Clear(); assert(get_value == NULL); - invalid_key = PyList_New(0); // not hashable key - if (invalid_key == NULL) { - goto error; - } - // test PyDict_GetItemRef(), invalid key get_value = Py_Ellipsis; // marker value assert(PyDict_GetItemRef(dict, invalid_key, &get_value) == -1); @@ -1222,7 +1233,7 @@ static struct PyMethodDef methods[] = { {"test_vectorcall", test_vectorcall, METH_NOARGS, _Py_NULL}, {"test_getattr", test_getattr, METH_NOARGS, _Py_NULL}, {"test_getitem", test_getitem, METH_NOARGS, _Py_NULL}, - {"test_dict_getitemref", test_dict_getitemref, METH_NOARGS, _Py_NULL}, + {"test_dict_api", test_dict_api, METH_NOARGS, _Py_NULL}, {_Py_NULL, _Py_NULL, 0, _Py_NULL} }; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy