Skip to content

Commit 224b8aa

Browse files
brandtbuchermatrixise
authored andcommitted
bpo-26868: Fix example usage of PyModule_AddObject. (#15725)
* Add a note to the PyModule_AddObject docs. * Correct example usages of PyModule_AddObject. * Whitespace. * Clean up wording. * πŸ“œπŸ€– Added by blurb_it. * First code review. * Add < 0 in the tests with PyModule_AddObject
1 parent 967b84c commit 224b8aa

File tree

9 files changed

+74
-13
lines changed

9 files changed

+74
-13
lines changed

β€ŽDoc/c-api/module.rst

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,22 @@ state:
417417
418418
Add an object to *module* as *name*. This is a convenience function which can
419419
be used from the module's initialization function. This steals a reference to
420-
*value*. Return ``-1`` on error, ``0`` on success.
420+
*value* on success. Return ``-1`` on error, ``0`` on success.
421+
422+
.. note::
423+
424+
Unlike other functions that steal references, ``PyModule_AddObject()`` only
425+
decrements the reference count of *value* **on success**.
426+
427+
This means that its return value must be checked, and calling code must
428+
:c:func:`Py_DECREF` *value* manually on error. Example usage::
429+
430+
Py_INCREF(spam);
431+
if (PyModule_AddObject(module, "spam", spam) < 0) {
432+
Py_DECREF(module);
433+
Py_DECREF(spam);
434+
return NULL;
435+
}
421436
422437
.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
423438

β€ŽDoc/extending/extending.rst

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ usually declare a static object variable at the beginning of your file::
209209
static PyObject *SpamError;
210210

211211
and initialize it in your module's initialization function (:c:func:`PyInit_spam`)
212-
with an exception object (leaving out the error checking for now)::
212+
with an exception object::
213213

214214
PyMODINIT_FUNC
215215
PyInit_spam(void)
@@ -221,8 +221,14 @@ with an exception object (leaving out the error checking for now)::
221221
return NULL;
222222

223223
SpamError = PyErr_NewException("spam.error", NULL, NULL);
224-
Py_INCREF(SpamError);
225-
PyModule_AddObject(m, "error", SpamError);
224+
Py_XINCREF(SpamError);
225+
if (PyModule_AddObject(m, "error", SpamError) < 0) {
226+
Py_XDECREF(SpamError);
227+
Py_CLEAR(SpamError);
228+
Py_DECREF(m);
229+
return NULL;
230+
}
231+
226232
return m;
227233
}
228234

@@ -1261,8 +1267,12 @@ function must take care of initializing the C API pointer array::
12611267
/* Create a Capsule containing the API pointer array's address */
12621268
c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL);
12631269

1264-
if (c_api_object != NULL)
1265-
PyModule_AddObject(m, "_C_API", c_api_object);
1270+
if (PyModule_AddObject(m, "_C_API", c_api_object) < 0) {
1271+
Py_XDECREF(c_api_object);
1272+
Py_DECREF(m);
1273+
return NULL;
1274+
}
1275+
12661276
return m;
12671277
}
12681278

β€ŽDoc/extending/newtypes_tutorial.rst

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,12 @@ This initializes the :class:`Custom` type, filling in a number of members
179179
to the appropriate default values, including :attr:`ob_type` that we initially
180180
set to *NULL*. ::
181181

182-
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
182+
Py_INCREF(&CustomType);
183+
if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
184+
Py_DECREF(&CustomType);
185+
PY_DECREF(m);
186+
return NULL;
187+
}
183188

184189
This adds the type to the module dictionary. This allows us to create
185190
:class:`Custom` instances by calling the :class:`Custom` class:
@@ -864,7 +869,12 @@ function::
864869
return NULL;
865870

866871
Py_INCREF(&SubListType);
867-
PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
872+
if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) {
873+
Py_DECREF(&SubListType);
874+
Py_DECREF(m);
875+
return NULL;
876+
}
877+
868878
return m;
869879
}
870880

β€ŽDoc/includes/custom.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ PyInit_custom(void)
3535
return NULL;
3636

3737
Py_INCREF(&CustomType);
38-
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
38+
if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
39+
Py_DECREF(&CustomType);
40+
PY_DECREF(m);
41+
return NULL;
42+
}
43+
3944
return m;
4045
}

β€ŽDoc/includes/custom2.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ PyInit_custom2(void)
128128
return NULL;
129129

130130
Py_INCREF(&CustomType);
131-
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
131+
if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
132+
Py_DECREF(&CustomType);
133+
Py_DECREF(m);
134+
return NULL;
135+
}
136+
132137
return m;
133138
}

β€ŽDoc/includes/custom3.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ PyInit_custom3(void)
179179
return NULL;
180180

181181
Py_INCREF(&CustomType);
182-
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
182+
if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
183+
Py_DECREF(&CustomType);
184+
Py_DECREF(m);
185+
return NULL;
186+
}
187+
183188
return m;
184189
}

β€ŽDoc/includes/custom4.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ PyInit_custom4(void)
193193
return NULL;
194194

195195
Py_INCREF(&CustomType);
196-
PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
196+
if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
197+
Py_DECREF(&CustomType);
198+
Py_DECREF(m);
199+
return NULL;
200+
}
201+
197202
return m;
198203
}

β€ŽDoc/includes/sublist.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ PyInit_sublist(void)
5959
return NULL;
6060

6161
Py_INCREF(&SubListType);
62-
PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
62+
if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) {
63+
Py_DECREF(&SubListType);
64+
Py_DECREF(m);
65+
return NULL;
66+
}
67+
6368
return m;
6469
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix example usage of :c:func:`PyModule_AddObject` to properly handle errors.

0 commit comments

Comments
Β (0)