bpo-26868: Fix example usage of PyModule_AddObject. (GH-15725) · python/cpython@535863e (original) (raw)
File tree
9 files changed
lines changed
- Misc/NEWS.d/next/Documentation
9 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -417,7 +417,22 @@ state: | ||
417 | 417 | |
418 | 418 | Add an object to *module* as *name*. This is a convenience function which can |
419 | 419 | 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 | + } | |
421 | 436 | |
422 | 437 | .. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) |
423 | 438 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -209,7 +209,7 @@ usually declare a static object variable at the beginning of your file:: | ||
209 | 209 | static PyObject *SpamError; |
210 | 210 | |
211 | 211 | 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:: | |
213 | 213 | |
214 | 214 | PyMODINIT_FUNC |
215 | 215 | PyInit_spam(void) |
@@ -221,8 +221,14 @@ with an exception object (leaving out the error checking for now):: | ||
221 | 221 | return NULL; |
222 | 222 | |
223 | 223 | 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 | + | |
226 | 232 | return m; |
227 | 233 | } |
228 | 234 | |
@@ -1261,8 +1267,12 @@ function must take care of initializing the C API pointer array:: | ||
1261 | 1267 | /* Create a Capsule containing the API pointer array's address */ |
1262 | 1268 | c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL); |
1263 | 1269 | |
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 | + | |
1266 | 1276 | return m; |
1267 | 1277 | } |
1268 | 1278 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -179,7 +179,12 @@ This initializes the :class:`Custom` type, filling in a number of members | ||
179 | 179 | to the appropriate default values, including :attr:`ob_type` that we initially |
180 | 180 | set to *NULL*. :: |
181 | 181 | |
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 | + } | |
183 | 188 | |
184 | 189 | This adds the type to the module dictionary. This allows us to create |
185 | 190 | :class:`Custom` instances by calling the :class:`Custom` class: |
@@ -864,7 +869,12 @@ function:: | ||
864 | 869 | return NULL; |
865 | 870 | |
866 | 871 | 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 | + | |
868 | 878 | return m; |
869 | 879 | } |
870 | 880 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -35,6 +35,11 @@ PyInit_custom(void) | ||
35 | 35 | return NULL; |
36 | 36 | |
37 | 37 | 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 | + | |
39 | 44 | return m; |
40 | 45 | } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -128,6 +128,11 @@ PyInit_custom2(void) | ||
128 | 128 | return NULL; |
129 | 129 | |
130 | 130 | 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 | + | |
132 | 137 | return m; |
133 | 138 | } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -179,6 +179,11 @@ PyInit_custom3(void) | ||
179 | 179 | return NULL; |
180 | 180 | |
181 | 181 | 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 | + | |
183 | 188 | return m; |
184 | 189 | } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -193,6 +193,11 @@ PyInit_custom4(void) | ||
193 | 193 | return NULL; |
194 | 194 | |
195 | 195 | 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 | + | |
197 | 202 | return m; |
198 | 203 | } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -59,6 +59,11 @@ PyInit_sublist(void) | ||
59 | 59 | return NULL; |
60 | 60 | |
61 | 61 | 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 | + | |
63 | 68 | return m; |
64 | 69 | } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1 | +Fix example usage of :c:func:`PyModule_AddObject` to properly handle errors. |