Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commiteaff3c1

Browse files
committed
Add PyDict_GetItemRef()
1 parentc7dac97 commiteaff3c1

File tree

5 files changed

+166
-7
lines changed

5 files changed

+166
-7
lines changed

‎docs/api.rst

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,17 @@ Latest version of the header file:
2727
Python 3.13
2828
-----------
2929

30-
..c:function:: PyObject*PyImport_AddModuleRef(const char *name)
30+
..c:function::intPyDict_GetItemRef(PyObject *p, PyObject *key, PyObject **result)
3131
32-
See `PyImport_AddModuleRef() documentation<https://docs.python.org/dev/c-api/import.html#c.PyImport_AddModuleRef>`__.
32+
See `PyDict_GetItemRef() documentation<https://docs.python.org/dev/c-api/dict.html#c.PyDict_GetItemRef>`__.
3333
34-
..c:function::intPyWeakref_GetRef(PyObject *ref,PyObject **pobj)
34+
..c:function::intPyDict_GetItemStringRef(PyObject *p, const char *key,PyObject **result)
3535
36-
See `PyWeakref_GetRef() documentation<https://docs.python.org/dev/c-api/weakref.html#c.PyWeakref_GetRef>`__.
36+
See `PyDict_GetItemStringRef() documentation<https://docs.python.org/dev/c-api/dict.html#c.PyDict_GetItemStringRef>`__.
37+
38+
..c:function:: PyObject*PyImport_AddModuleRef(const char *name)
39+
40+
See `PyImport_AddModuleRef() documentation<https://docs.python.org/dev/c-api/import.html#c.PyImport_AddModuleRef>`__.
3741
3842
..c:function::intPyObject_GetOptionalAttr(PyObject *obj, PyObject *attr_name, PyObject **result)
3943
@@ -55,6 +59,10 @@ Python 3.13
5559
5660
See `PyModule_Add() documentation<https://docs.python.org/dev/c-api/module.html#c.PyModule_Add>`__.
5761
62+
..c:function::intPyWeakref_GetRef(PyObject *ref, PyObject **pobj)
63+
64+
See `PyWeakref_GetRef() documentation<https://docs.python.org/dev/c-api/weakref.html#c.PyWeakref_GetRef>`__.
65+
5866
5967
Python 3.12
6068
-----------

‎docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Changelog
22
=========
33

4+
* 2023-07-21: Add ``PyDict_GetItemRef()`` function.
45
* 2023-07-18: Add ``PyModule_Add()`` function.
56
* 2023-07-12: Add ``PyObject_GetOptionalAttr()``,
67
``PyObject_GetOptionalAttrString()``,

‎docs/users.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,10 @@ Examples of projects using pythoncapi_compat.h
3838
(`commit<https://github.com/sergey-dryabzhinsky/python-zstd/commit/8aa6d7a4b250e1f0a4e27b4107c39dc516c87f96>`__)
3939
* `hollerith<https://github.com/pyansys/hollerith/>`_
4040
``src/writer.c`` uses ``PyObject_CallOneArg() and other Python 3.9 apis``
41-
(`pythoncapi_compat.h copy
41+
(`pythoncapi_compat.h copy
4242
<https://github.com/pyansys/hollerith/blob/main/src/pythoncapi_compat.h>`__)
4343

4444

45-
4645
Projects not using pythoncapi_compat.h
4746
======================================
4847

‎pythoncapi_compat.h

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ PyFrame_GetVar(PyFrameObject *frame, PyObject *name)
258258
#if PY_VERSION_HEX >= 0x03000000
259259
value =PyDict_GetItemWithError(locals, name);
260260
#else
261-
value =PyDict_GetItem(locals, name);
261+
value =_PyDict_GetItemWithError(locals, name);
262262
#endif
263263
Py_DECREF(locals);
264264

@@ -791,6 +791,49 @@ PyMapping_GetOptionalItemString(PyObject *obj, const char *key, PyObject **resul
791791
#endif
792792

793793

794+
// gh-106004 added PyDict_GetItemRef() and PyDict_GetItemStringRef()
795+
// to Python 3.13.0a1
796+
#if PY_VERSION_HEX < 0x030D00A1
797+
PYCAPI_COMPAT_STATIC_INLINE(int)
798+
PyDict_GetItemRef(PyObject *mp, PyObject *key, PyObject **result)
799+
{
800+
#if PY_VERSION_HEX >= 0x03000000
801+
PyObject *item =PyDict_GetItemWithError(mp, key);
802+
#else
803+
PyObject *item =_PyDict_GetItemWithError(mp, key);
804+
#endif
805+
if (item !=NULL) {
806+
*result =Py_NewRef(item);
807+
return1;// found
808+
}
809+
if (!PyErr_Occurred()) {
810+
*result =NULL;
811+
return0;// not found
812+
}
813+
*result =NULL;
814+
return -1;
815+
}
816+
817+
PYCAPI_COMPAT_STATIC_INLINE(int)
818+
PyDict_GetItemStringRef(PyObject *mp,constchar *key, PyObject **result)
819+
{
820+
int res;
821+
#if PY_VERSION_HEX >= 0x03000000
822+
PyObject *key_obj =PyUnicode_FromString(key);
823+
#else
824+
PyObject *key_obj =PyString_FromString(key);
825+
#endif
826+
if (key_obj ==NULL) {
827+
*result =NULL;
828+
return -1;
829+
}
830+
res =PyDict_GetItemRef(mp, key_obj, result);
831+
Py_DECREF(key_obj);
832+
return res;
833+
}
834+
#endif
835+
836+
794837
// gh-106307 added PyModule_Add() to Python 3.13.0a1
795838
#if PY_VERSION_HEX < 0x030D00A1
796839
PYCAPI_COMPAT_STATIC_INLINE(int)

‎tests/test_pythoncapi_compat_cext.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,113 @@ test_getitem(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
10861086
}
10871087

10881088

1089+
staticPyObject*
1090+
test_dict_getitemref(PyObject*Py_UNUSED(module),PyObject*Py_UNUSED(args))
1091+
{
1092+
assert(!PyErr_Occurred());
1093+
1094+
PyObject*dict=NULL,*key=NULL,*missing_key=NULL,*value=NULL;
1095+
PyObject*invalid_key=NULL;
1096+
PyObject*invalid_dict=NULL;
1097+
PyObject*get_value=NULL;
1098+
intres;
1099+
1100+
// test PyDict_New()
1101+
dict=PyDict_New();
1102+
if (dict==NULL) {
1103+
gotoerror;
1104+
}
1105+
1106+
key=PyUnicode_FromString("key");
1107+
if (key==NULL) {
1108+
gotoerror;
1109+
}
1110+
1111+
missing_key=PyUnicode_FromString("missing_key");
1112+
if (missing_key==NULL) {
1113+
gotoerror;
1114+
}
1115+
1116+
value=PyUnicode_FromString("value");
1117+
if (value==NULL) {
1118+
gotoerror;
1119+
}
1120+
1121+
res=PyDict_SetItemString(dict,"key",value);
1122+
if (res<0) {
1123+
gotoerror;
1124+
}
1125+
assert(res==0);
1126+
1127+
// test PyDict_GetItemRef(), key is present
1128+
get_value=Py_Ellipsis;// marker value
1129+
assert(PyDict_GetItemRef(dict,key,&get_value)==1);
1130+
assert(get_value==value);
1131+
Py_DECREF(get_value);
1132+
1133+
// test PyDict_GetItemStringRef(), key is present
1134+
get_value=Py_Ellipsis;// marker value
1135+
assert(PyDict_GetItemStringRef(dict,"key",&get_value)==1);
1136+
assert(get_value==value);
1137+
Py_DECREF(get_value);
1138+
1139+
// test PyDict_GetItemRef(), missing key
1140+
get_value=Py_Ellipsis;// marker value
1141+
assert(PyDict_GetItemRef(dict,missing_key,&get_value)==0);
1142+
assert(!PyErr_Occurred());
1143+
assert(get_value==NULL);
1144+
1145+
// test PyDict_GetItemStringRef(), missing key
1146+
get_value=Py_Ellipsis;// marker value
1147+
assert(PyDict_GetItemStringRef(dict,"missing_key",&get_value)==0);
1148+
assert(!PyErr_Occurred());
1149+
assert(get_value==NULL);
1150+
1151+
// test PyDict_GetItemRef(), invalid dict
1152+
invalid_dict=key;// borrowed reference
1153+
get_value=Py_Ellipsis;// marker value
1154+
assert(PyDict_GetItemRef(invalid_dict,key,&get_value)==-1);
1155+
assert(PyErr_ExceptionMatches(PyExc_SystemError));
1156+
PyErr_Clear();
1157+
assert(get_value==NULL);
1158+
1159+
// test PyDict_GetItemStringRef(), invalid dict
1160+
get_value=Py_Ellipsis;// marker value
1161+
assert(PyDict_GetItemStringRef(invalid_dict,"key",&get_value)==-1);
1162+
assert(PyErr_ExceptionMatches(PyExc_SystemError));
1163+
PyErr_Clear();
1164+
assert(get_value==NULL);
1165+
1166+
invalid_key=PyList_New(0);// not hashable key
1167+
if (invalid_key==NULL) {
1168+
gotoerror;
1169+
}
1170+
1171+
// test PyDict_GetItemRef(), invalid key
1172+
get_value=Py_Ellipsis;// marker value
1173+
assert(PyDict_GetItemRef(dict,invalid_key,&get_value)==-1);
1174+
assert(PyErr_ExceptionMatches(PyExc_TypeError));
1175+
PyErr_Clear();
1176+
assert(get_value==NULL);
1177+
1178+
Py_DECREF(dict);
1179+
Py_DECREF(key);
1180+
Py_DECREF(missing_key);
1181+
Py_DECREF(value);
1182+
Py_DECREF(invalid_key);
1183+
1184+
Py_RETURN_NONE;
1185+
1186+
error:
1187+
Py_XDECREF(dict);
1188+
Py_XDECREF(key);
1189+
Py_XDECREF(missing_key);
1190+
Py_XDECREF(value);
1191+
Py_XDECREF(invalid_key);
1192+
returnNULL;
1193+
}
1194+
1195+
10891196
staticstructPyMethodDefmethods[]= {
10901197
{"test_object",test_object,METH_NOARGS,_Py_NULL},
10911198
{"test_py_is",test_py_is,METH_NOARGS,_Py_NULL},
@@ -1110,6 +1217,7 @@ static struct PyMethodDef methods[] = {
11101217
{"test_vectorcall",test_vectorcall,METH_NOARGS,_Py_NULL},
11111218
{"test_getattr",test_getattr,METH_NOARGS,_Py_NULL},
11121219
{"test_getitem",test_getitem,METH_NOARGS,_Py_NULL},
1220+
{"test_dict_getitemref",test_dict_getitemref,METH_NOARGS,_Py_NULL},
11131221
{_Py_NULL,_Py_NULL,0,_Py_NULL}
11141222
};
11151223

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp