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

Commit309c56d

Browse files
authored
Add PyMapping_HasKeyWithError() function (#73)
Add PyMapping_HasKeyWithError() and PyMapping_HasKeyStringWithError()functions.Fix also undefined behavior in PyMapping_GetOptionalItemString() whenPyUnicode_FromString() fails: set '*result' to NULL.
1 parent8109811 commit309c56d

File tree

3 files changed

+79
-24
lines changed

3 files changed

+79
-24
lines changed

‎docs/api.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ Python 3.13
5858
5959
See `PyMapping_GetOptionalItemString() documentation<https://docs.python.org/dev/c-api/mapping.html#c.PyMapping_GetOptionalItemString>`__.
6060
61+
..c:function::intPyMapping_HasKeyWithError(PyObject *obj, PyObject *key)
62+
63+
See `PyMapping_HasKeyWithError() documentation<https://docs.python.org/dev/c-api/mapping.html#c.PyMapping_HasKeyWithError>`__.
64+
65+
..c:function::intPyMapping_HasKeyStringWithError(PyObject *obj, const char *key)
66+
67+
See `PyMapping_HasKeyStringWithError() documentation<https://docs.python.org/dev/c-api/mapping.html#c.PyMapping_HasKeyStringWithError>`__.
68+
6169
..c:function::intPyModule_Add(PyObject *module, const char *name, PyObject *value)
6270
6371
See `PyModule_Add() documentation<https://docs.python.org/dev/c-api/module.html#c.PyModule_Add>`__.

‎pythoncapi_compat.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,8 @@ PyObject_GetOptionalAttrString(PyObject *obj, const char *name, PyObject **resul
711711
#endif
712712

713713

714-
// gh-106307 added PyObject_GetOptionalAttr() to Python 3.13.0a1
714+
// gh-106307 added PyObject_GetOptionalAttr() and
715+
// PyMapping_GetOptionalItemString() to Python 3.13.0a1
715716
#if PY_VERSION_HEX < 0x030D00A1
716717
staticinlineint
717718
PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result)
@@ -738,6 +739,7 @@ PyMapping_GetOptionalItemString(PyObject *obj, const char *key, PyObject **resul
738739
key_obj =PyString_FromString(key);
739740
#endif
740741
if (key_obj ==NULL) {
742+
*result =NULL;
741743
return -1;
742744
}
743745
rc =PyMapping_GetOptionalItem(obj, key_obj, result);
@@ -746,6 +748,28 @@ PyMapping_GetOptionalItemString(PyObject *obj, const char *key, PyObject **resul
746748
}
747749
#endif
748750

751+
// gh-108511 added PyMapping_HasKeyWithError() and
752+
// PyMapping_HasKeyStringWithError() to Python 3.13.0a1
753+
#if PY_VERSION_HEX < 0x030D00A1
754+
staticinlineint
755+
PyMapping_HasKeyWithError(PyObject *obj, PyObject *key)
756+
{
757+
PyObject *res;
758+
int rc =PyMapping_GetOptionalItem(obj, key, &res);
759+
Py_XDECREF(res);
760+
return rc;
761+
}
762+
763+
staticinlineint
764+
PyMapping_HasKeyStringWithError(PyObject *obj,constchar *key)
765+
{
766+
PyObject *res;
767+
int rc =PyMapping_GetOptionalItemString(obj, key, &res);
768+
Py_XDECREF(res);
769+
return rc;
770+
}
771+
#endif
772+
749773

750774
// gh-106004 added PyDict_GetItemRef() and PyDict_GetItemStringRef()
751775
// to Python 3.13.0a1

‎tests/test_pythoncapi_compat_cext.c

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
# defineASSERT_REFCNT(expr)
5151
#endif
5252

53+
// Marker to check that pointer value was set
54+
staticconstcharuninitialized[]="uninitialized";
55+
#defineUNINITIALIZED_OBJ ((PyObject *)uninitialized)
56+
5357

5458
staticPyObject*
5559
create_string(constchar*str)
@@ -806,7 +810,7 @@ test_weakref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
806810
}
807811

808812
// test PyWeakref_GetRef(), reference is alive
809-
PyObject*ref=Py_True;// marker to check that value was set
813+
PyObject*ref=UNINITIALIZED_OBJ;
810814
assert(PyWeakref_GetRef(weakref,&ref)==1);
811815
assert(ref==obj);
812816
assert(Py_REFCNT(obj)== (refcnt+1));
@@ -1016,28 +1020,28 @@ test_getattr(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
10161020

10171021
// test PyObject_GetOptionalAttr(): attribute exists
10181022
attr_name=create_string("version");
1019-
value=Py_True;// marker value
1023+
value=UNINITIALIZED_OBJ;
10201024
assert(PyObject_GetOptionalAttr(obj,attr_name,&value)==1);
10211025
assert(value!=_Py_NULL);
10221026
Py_DECREF(value);
10231027
Py_DECREF(attr_name);
10241028

10251029
// test PyObject_GetOptionalAttrString(): attribute exists
1026-
value=Py_True;// marker value
1030+
value=UNINITIALIZED_OBJ;
10271031
assert(PyObject_GetOptionalAttrString(obj,"version",&value)==1);
10281032
assert(value!=_Py_NULL);
10291033
Py_DECREF(value);
10301034

10311035
// test PyObject_GetOptionalAttr(): attribute doesn't exist
10321036
attr_name=create_string("nonexistant_attr_name");
1033-
value=Py_True;// marker value
1037+
value=UNINITIALIZED_OBJ;
10341038
assert(PyObject_GetOptionalAttr(obj,attr_name,&value)==0);
10351039
assert(value==_Py_NULL);
10361040
Py_DECREF(attr_name);
10371041
assert(!PyErr_Occurred());
10381042

10391043
// test PyObject_GetOptionalAttrString(): attribute doesn't exist
1040-
value=Py_True;// marker value
1044+
value=UNINITIALIZED_OBJ;
10411045
assert(PyObject_GetOptionalAttrString(obj,"nonexistant_attr_name",&value)==0);
10421046
assert(value==_Py_NULL);
10431047
assert(!PyErr_Occurred());
@@ -1056,37 +1060,56 @@ test_getitem(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
10561060
assert(value!=_Py_NULL);
10571061
PyObject*obj=Py_BuildValue("{sO}","key",value);
10581062
assert(obj!=_Py_NULL);
1059-
PyObject*key;
1063+
PyObject*present_key,*missing_key;
10601064
PyObject*item;
10611065

1066+
present_key=create_string("key");
1067+
missing_key=create_string("dontexist");
1068+
10621069
// test PyMapping_GetOptionalItem(): key is present
1063-
key=create_string("key");
1064-
item=Py_True;// marker value
1065-
assert(PyMapping_GetOptionalItem(obj,key,&item)==1);
1070+
item=UNINITIALIZED_OBJ;
1071+
assert(PyMapping_GetOptionalItem(obj,present_key,&item)==1);
10661072
assert(item==value);
10671073
Py_DECREF(item);
1068-
Py_DECREF(key);
1074+
assert(!PyErr_Occurred());
1075+
1076+
// test PyMapping_HasKeyWithError(): key is present
1077+
assert(PyMapping_HasKeyWithError(obj,present_key)==1);
1078+
assert(!PyErr_Occurred());
10691079

10701080
// test PyMapping_GetOptionalItemString(): key is present
1071-
item=Py_True;// marker value
1081+
item=UNINITIALIZED_OBJ;
10721082
assert(PyMapping_GetOptionalItemString(obj,"key",&item)==1);
10731083
assert(item==value);
10741084
Py_DECREF(item);
10751085

1086+
// test PyMapping_HasKeyStringWithError(): key is present
1087+
assert(PyMapping_HasKeyStringWithError(obj,"key")==1);
1088+
assert(!PyErr_Occurred());
1089+
10761090
// test PyMapping_GetOptionalItem(): missing key
1077-
key=create_string("dontexist");
1078-
item=Py_True;// marker value
1079-
assert(PyMapping_GetOptionalItem(obj,key,&item)==0);
1091+
item=UNINITIALIZED_OBJ;
1092+
assert(PyMapping_GetOptionalItem(obj,missing_key,&item)==0);
10801093
assert(item==_Py_NULL);
1081-
Py_DECREF(key);
1094+
assert(!PyErr_Occurred());
1095+
1096+
// test PyMapping_HasKeyWithError(): missing key
1097+
assert(PyMapping_HasKeyWithError(obj,missing_key)==0);
1098+
assert(!PyErr_Occurred());
10821099

10831100
// test PyMapping_GetOptionalItemString(): missing key
1084-
item=Py_True;// marker value
1101+
item=UNINITIALIZED_OBJ;
10851102
assert(PyMapping_GetOptionalItemString(obj,"dontexist",&item)==0);
10861103
assert(item==_Py_NULL);
10871104

1105+
// test PyMapping_HasKeyStringWithError(): missing key
1106+
assert(PyMapping_HasKeyStringWithError(obj,"dontexist")==0);
1107+
assert(!PyErr_Occurred());
1108+
10881109
Py_DECREF(obj);
10891110
Py_DECREF(value);
1111+
Py_DECREF(present_key);
1112+
Py_DECREF(missing_key);
10901113
Py_RETURN_NONE;
10911114
}
10921115

@@ -1147,45 +1170,45 @@ test_dict_api(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
11471170
PyErr_Clear();
11481171

11491172
// test PyDict_GetItemRef(), key is present
1150-
get_value=Py_Ellipsis;// marker value
1173+
get_value=UNINITIALIZED_OBJ;
11511174
assert(PyDict_GetItemRef(dict,key,&get_value)==1);
11521175
assert(get_value==value);
11531176
Py_DECREF(get_value);
11541177

11551178
// test PyDict_GetItemStringRef(), key is present
1156-
get_value=Py_Ellipsis;// marker value
1179+
get_value=UNINITIALIZED_OBJ;
11571180
assert(PyDict_GetItemStringRef(dict,"key",&get_value)==1);
11581181
assert(get_value==value);
11591182
Py_DECREF(get_value);
11601183

11611184
// test PyDict_GetItemRef(), missing key
1162-
get_value=Py_Ellipsis;// marker value
1185+
get_value=UNINITIALIZED_OBJ;
11631186
assert(PyDict_GetItemRef(dict,missing_key,&get_value)==0);
11641187
assert(!PyErr_Occurred());
11651188
assert(get_value==NULL);
11661189

11671190
// test PyDict_GetItemStringRef(), missing key
1168-
get_value=Py_Ellipsis;// marker value
1191+
get_value=UNINITIALIZED_OBJ;
11691192
assert(PyDict_GetItemStringRef(dict,"missing_key",&get_value)==0);
11701193
assert(!PyErr_Occurred());
11711194
assert(get_value==NULL);
11721195

11731196
// test PyDict_GetItemRef(), invalid dict
1174-
get_value=Py_Ellipsis;// marker value
1197+
get_value=UNINITIALIZED_OBJ;
11751198
assert(PyDict_GetItemRef(invalid_dict,key,&get_value)==-1);
11761199
assert(PyErr_ExceptionMatches(PyExc_SystemError));
11771200
PyErr_Clear();
11781201
assert(get_value==NULL);
11791202

11801203
// test PyDict_GetItemStringRef(), invalid dict
1181-
get_value=Py_Ellipsis;// marker value
1204+
get_value=UNINITIALIZED_OBJ;
11821205
assert(PyDict_GetItemStringRef(invalid_dict,"key",&get_value)==-1);
11831206
assert(PyErr_ExceptionMatches(PyExc_SystemError));
11841207
PyErr_Clear();
11851208
assert(get_value==NULL);
11861209

11871210
// test PyDict_GetItemRef(), invalid key
1188-
get_value=Py_Ellipsis;// marker value
1211+
get_value=UNINITIALIZED_OBJ;
11891212
assert(PyDict_GetItemRef(dict,invalid_key,&get_value)==-1);
11901213
assert(PyErr_ExceptionMatches(PyExc_TypeError));
11911214
PyErr_Clear();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp