[Python-checkins] bpo-26868: Fix example usage of PyModule_AddObject. (GH-15725)

Miss Islington (bot) webhook-mailer at python.org
Thu Sep 12 08:29:13 EDT 2019


https://github.com/python/cpython/commit/c8d1338441114fbc504625bc66607e7996018a5d
commit: c8d1338441114fbc504625bc66607e7996018a5d
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2019-09-12T05:29:09-07:00
summary:

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 at gmail.com>

files:
A Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd.rst
M Doc/c-api/module.rst
M Doc/extending/extending.rst
M Doc/extending/newtypes_tutorial.rst
M Doc/includes/custom.c
M Doc/includes/custom2.c
M Doc/includes/custom3.c
M Doc/includes/custom4.c
M Doc/includes/sublist.c

diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 017b656854a8..7168dc7363ca 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 afed3aabb79a..73a77c781bc2 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 07c2ef718aed..e6448e46411b 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 13d16f5424ae..bda32e2ad81d 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 6477a19dafed..5bacab7a2a97 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 213d0864ce1c..2b7a99ecf96c 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 b0b2906dbdc8..584992fc5f1a 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 76ff93948cfd..b2c26e73ebaf 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 000000000000..c668092b41a6
--- /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



More information about the Python-checkins mailing list