Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c6464c6

Browse files
committed
Add PyModule_AddObjectRef()
1 parent c11d367 commit c6464c6

3 files changed

Lines changed: 72 additions & 14 deletions

File tree

README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ GC protocol::
213213

214214
Module helper::
215215

216+
int PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value);
216217
int PyModule_AddType(PyObject *module, PyTypeObject *type);
217218

218219

pythoncapi_compat.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern "C" {
3232

3333

3434
// bpo-42262 added Py_NewRef() to Python 3.10.0a3
35-
#if PY_VERSION_HEX < 0x030a00A3 && !defined(Py_NewRef)
35+
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
3636
static inline PyObject* _Py_NewRef(PyObject *obj)
3737
{
3838
Py_INCREF(obj);
@@ -43,7 +43,7 @@ static inline PyObject* _Py_NewRef(PyObject *obj)
4343

4444

4545
// bpo-42262 added Py_XNewRef() to Python 3.10.0a3
46-
#if PY_VERSION_HEX < 0x030a00A3 && !defined(Py_XNewRef)
46+
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef)
4747
static inline PyObject* _Py_XNewRef(PyObject *obj)
4848
{
4949
Py_XINCREF(obj);
@@ -246,6 +246,21 @@ PyModule_AddType(PyObject *module, PyTypeObject *type)
246246
#endif
247247

248248

249+
// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
250+
#if PY_VERSION_HEX < 0x030A00A3
251+
static inline int
252+
PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
253+
{
254+
Py_XINCREF(value);
255+
int res = PyModule_AddObject(module, name, value);
256+
if (res < 0) {
257+
Py_XDECREF(value);
258+
}
259+
return res;
260+
}
261+
#endif
262+
263+
249264
// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
250265
// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
251266
#if PY_VERSION_HEX < 0x030900A6

tests/test_pythoncapi_compat_cext.c

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -197,16 +197,10 @@ test_gc(PyObject *self, PyObject *ignored)
197197
}
198198

199199

200-
static PyObject *
201-
test_module(PyObject *self, PyObject *ignored)
200+
// test PyModule_AddType()
201+
static int
202+
test_module_add_type(PyObject *module)
202203
{
203-
PyObject *module = PyImport_ImportModule("sys");
204-
if (module == NULL) {
205-
return NULL;
206-
}
207-
assert(PyModule_Check(module));
208-
209-
// test PyModule_AddType()
210204
PyTypeObject *type = &PyUnicode_Type;
211205
#ifdef PYTHON3
212206
const char *type_name = "str";
@@ -216,21 +210,69 @@ test_module(PyObject *self, PyObject *ignored)
216210
Py_ssize_t refcnt = Py_REFCNT(type);
217211

218212
if (PyModule_AddType(module, type) < 0) {
219-
goto error;
213+
return -1;
220214
}
221215
assert(Py_REFCNT(type) == refcnt + 1);
222216

223217
PyObject *attr = PyObject_GetAttrString(module, type_name);
224218
if (attr == NULL) {
225-
goto error;
219+
return -1;
226220
}
227221
assert(attr == (PyObject *)type);
228222
Py_DECREF(attr);
229223

230224
if (PyObject_DelAttrString(module, type_name) < 0) {
231-
goto error;
225+
return -1;
232226
}
233227
assert(Py_REFCNT(type) == refcnt);
228+
return 0;
229+
}
230+
231+
232+
// test PyModule_AddObjectRef()
233+
static int
234+
test_module_addobjectref(PyObject *module)
235+
{
236+
PyObject *obj = Py_True;
237+
Py_ssize_t refcnt = Py_REFCNT(obj);
238+
const char *name = "test_module_addobjectref";
239+
240+
if (PyModule_AddObjectRef(module, name, obj) < 0) {
241+
assert(Py_REFCNT(obj) == refcnt);
242+
return -1;
243+
}
244+
assert(Py_REFCNT(obj) == refcnt + 1);
245+
246+
if (PyObject_DelAttrString(module, name) < 0) {
247+
return -1;
248+
}
249+
assert(Py_REFCNT(obj) == refcnt);
250+
251+
// PyModule_AddObjectRef() with value=NULL must not crash
252+
int res = PyModule_AddObjectRef(module, name, NULL);
253+
assert(res < 0);
254+
PyErr_Clear();
255+
256+
return 0;
257+
}
258+
259+
260+
static PyObject *
261+
test_module(PyObject *self, PyObject *ignored)
262+
{
263+
PyObject *module = PyImport_ImportModule("sys");
264+
if (module == NULL) {
265+
return NULL;
266+
}
267+
assert(PyModule_Check(module));
268+
269+
if (test_module_add_type(module) < 0) {
270+
goto error;
271+
}
272+
273+
if (test_module_addobjectref(module) < 0) {
274+
goto error;
275+
}
234276

235277
Py_DECREF(module);
236278
Py_RETURN_NONE;

0 commit comments

Comments
 (0)