Browse Source
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 224b8aaa7e )
Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
pull/16039/head
Miss Islington (bot)
7 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with
74 additions and
13 deletions
Doc/c-api/module.rst
Doc/extending/extending.rst
Doc/extending/newtypes_tutorial.rst
Doc/includes/custom.c
Doc/includes/custom2.c
Doc/includes/custom3.c
Doc/includes/custom4.c
Doc/includes/sublist.c
Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd.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)
@ -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;
}
@ -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;
}
@ -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 ;
}
@ -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 ;
}
@ -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 ;
}
@ -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 ;
}
@ -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 ;
}
@ -0,0 +1 @@
Fix example usage of :c:func: `PyModule_AddObject` to properly handle errors.