summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-09-12 05:26:46 -0700
committerGitHub <noreply@github.com>2019-09-12 05:26:46 -0700
commit535863e3f599a6ad829204d83f144c91e44de443 (patch)
tree183f007542a5f3ceaa229c0bc418f1168940baaa
parent14afe203d6937069c66b7e9c4a9fc0db49b32c19 (diff)
downloadcpython-git-535863e3f599a6ad829204d83f144c91e44de443.tar.gz
bpo-26868: Fix example usage of PyModule_AddObject. (GH-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 (cherry picked from commit 224b8aaa7e8f67f748e8b7b6a4a77a25f6554651) Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
-rw-r--r--Doc/c-api/module.rst17
-rw-r--r--Doc/extending/extending.rst20
-rw-r--r--Doc/extending/newtypes_tutorial.rst14
-rw-r--r--Doc/includes/custom.c7
-rw-r--r--Doc/includes/custom2.c7
-rw-r--r--Doc/includes/custom3.c7
-rw-r--r--Doc/includes/custom4.c7
-rw-r--r--Doc/includes/sublist.c7
-rw-r--r--Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd.rst1
9 files changed, 74 insertions, 13 deletions
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 68cbda2938..feca1ec2a0 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -417,7 +417,22 @@ state:
Add an object to *module* as *name*. This is a convenience function which can
be used from the module's initialization function. This steals a reference to
- *value*. Return ``-1`` on error, ``0`` on success.
+ *value* on success. Return ``-1`` on error, ``0`` on success.
+
+ .. note::
+
+ Unlike other functions that steal references, ``PyModule_AddObject()`` only
+ decrements the reference count of *value* **on success**.
+
+ This means that its return value must be checked, and calling code must
+ :c:func:`Py_DECREF` *value* manually on error. Example usage::
+
+ Py_INCREF(spam);
+ if (PyModule_AddObject(module, "spam", spam) < 0) {
+ Py_DECREF(module);
+ Py_DECREF(spam);
+ return NULL;
+ }
.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index e459514b2b..5b4ea8220e 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -209,7 +209,7 @@ usually declare a static object variable at the beginning of your file::
static PyObject *SpamError;
and initialize it in your module's initialization function (:c:func:`PyInit_spam`)
-with an exception object (leaving out the error checking for now)::
+with an exception object::
PyMODINIT_FUNC
PyInit_spam(void)
@@ -221,8 +221,14 @@ with an exception object (leaving out the error checking for now)::
return NULL;
SpamError = PyErr_NewException("spam.error", NULL, NULL);
- Py_INCREF(SpamError);
- PyModule_AddObject(m, "error", SpamError);
+ Py_XINCREF(SpamError);
+ if (PyModule_AddObject(m, "error", SpamError) < 0) {
+ Py_XDECREF(SpamError);
+ Py_CLEAR(SpamError);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
@@ -1261,8 +1267,12 @@ function must take care of initializing the C API pointer array::
/* Create a Capsule containing the API pointer array's address */
c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL);
- if (c_api_object != NULL)
- PyModule_AddObject(m, "_C_API", c_api_object);
+ if (PyModule_AddObject(m, "_C_API", c_api_object) < 0) {
+ Py_XDECREF(c_api_object);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst
index 59c8cc0122..94ca747c7a 100644
--- a/Doc/extending/newtypes_tutorial.rst
+++ b/Doc/extending/newtypes_tutorial.rst
@@ -179,7 +179,12 @@ This initializes the :class:`Custom` type, filling in a number of members
to the appropriate default values, including :attr:`ob_type` that we initially
set to *NULL*. ::
- PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ Py_INCREF(&CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ PY_DECREF(m);
+ return NULL;
+ }
This adds the type to the module dictionary. This allows us to create
:class:`Custom` instances by calling the :class:`Custom` class:
@@ -864,7 +869,12 @@ function::
return NULL;
Py_INCREF(&SubListType);
- PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
+ if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) {
+ Py_DECREF(&SubListType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c
index 13d16f5424..bda32e2ad8 100644
--- a/Doc/includes/custom.c
+++ b/Doc/includes/custom.c
@@ -35,6 +35,11 @@ PyInit_custom(void)
return NULL;
Py_INCREF(&CustomType);
- PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ PY_DECREF(m);
+ return NULL;
+ }
+
return m;
}
diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c
index 6477a19daf..5bacab7a2a 100644
--- a/Doc/includes/custom2.c
+++ b/Doc/includes/custom2.c
@@ -128,6 +128,11 @@ PyInit_custom2(void)
return NULL;
Py_INCREF(&CustomType);
- PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c
index 213d0864ce..2b7a99ecf9 100644
--- a/Doc/includes/custom3.c
+++ b/Doc/includes/custom3.c
@@ -179,6 +179,11 @@ PyInit_custom3(void)
return NULL;
Py_INCREF(&CustomType);
- PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c
index b0b2906dbd..584992fc5f 100644
--- a/Doc/includes/custom4.c
+++ b/Doc/includes/custom4.c
@@ -193,6 +193,11 @@ PyInit_custom4(void)
return NULL;
Py_INCREF(&CustomType);
- PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+ Py_DECREF(&CustomType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
diff --git a/Doc/includes/sublist.c b/Doc/includes/sublist.c
index 76ff93948c..b2c26e73eb 100644
--- a/Doc/includes/sublist.c
+++ b/Doc/includes/sublist.c
@@ -59,6 +59,11 @@ PyInit_sublist(void)
return NULL;
Py_INCREF(&SubListType);
- PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
+ if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) {
+ Py_DECREF(&SubListType);
+ Py_DECREF(m);
+ return NULL;
+ }
+
return m;
}
diff --git a/Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd.rst b/Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd.rst
new file mode 100644
index 0000000000..c668092b41
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd.rst
@@ -0,0 +1 @@
+Fix example usage of :c:func:`PyModule_AddObject` to properly handle errors. \ No newline at end of file