diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -403,17 +403,18 @@ The module initialization function (if u a function called from a module execution slot (if using multi-phase initialization), can use the following functions to help initialize the module state: .. c:function:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value) 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. On error, + *value* must be :c:func:`Py_DECREF`'ed manually. .. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) Add an integer constant to *module* as *name*. This convenience function can be used from the module's initialization function. Return ``-1`` on error, ``0`` on success. diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -210,17 +210,20 @@ with an exception object (leaving out th PyObject *m; m = PyModule_Create(&spammodule); if (m == NULL) return NULL; SpamError = PyErr_NewException("spam.error", NULL, NULL); Py_INCREF(SpamError); - PyModule_AddObject(m, "error", SpamError); + if (PyModule_AddObject(m, "error", SpamError) == -1) { + Py_DECREF(SpamError); + return NULL; + } return m; } Note that the Python name for the exception object is :exc:`spam.error`. The :c:func:`PyErr_NewException` function may create a class with the base class being :exc:`Exception` (unless another class is passed in instead of *NULL*), described in :ref:`bltin-exceptions`. @@ -1242,17 +1245,20 @@ function must take care of initializing /* Initialize the C API pointer array */ PySpam_API[PySpam_System_NUM] = (void *)PySpam_System; /* 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) == -1) { + Py_DECREF(c_api_object); + return NULL; + } return m; } Note that ``PySpam_API`` is declared ``static``; otherwise the pointer array would disappear when :func:`PyInit_spam` terminates! The bulk of the work is in the header file :file:`spammodule.h`, which looks like this:: diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -189,17 +189,20 @@ Everything else in the file should be fa :c:func:`PyInit_noddy`:: if (PyType_Ready(&noddy_NoddyType) < 0) return; This initializes the :class:`Noddy` type, filing in a number of members, including :attr:`ob_type` that we initially set to *NULL*. :: - PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType); + if (PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType) == -1) { + Py_DECREF(&noddy_NoddyType); + return NULL; + } This adds the type to the module dictionary. This allows us to create :class:`Noddy` instances by calling the :class:`Noddy` class:: >>> import noddy >>> mynoddy = noddy.Noddy() That's it! All that remains is to build it; put the above code in a file called @@ -849,17 +852,20 @@ the module's :c:func:`init` function. :: if (PyType_Ready(&ShoddyType) < 0) return NULL; m = PyModule_Create(&shoddymodule); if (m == NULL) return NULL; Py_INCREF(&ShoddyType); - PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType); + if (PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType)) { + Py_DECREF(&ShoddyType); + return NULL; + } return m; } Before calling :c:func:`PyType_Ready`, the type structure must have the :c:member:`~PyTypeObject.tp_base` slot filled in. When we are deriving a new type, it is not necessary to fill out the :c:member:`~PyTypeObject.tp_alloc` slot with :c:func:`PyType_GenericNew` -- the allocate function from the base type will be inherited.