]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40024: Add PyModule_AddType() helper function (GH-19088)
authorDong-hee Na <donghee.na92@gmail.com>
Sun, 22 Mar 2020 16:17:34 +0000 (01:17 +0900)
committerGitHub <noreply@github.com>
Sun, 22 Mar 2020 16:17:34 +0000 (17:17 +0100)
Doc/c-api/module.rst
Doc/whatsnew/3.9.rst
Include/modsupport.h
Misc/NEWS.d/next/C API/2020-03-20-18-41-33.bpo-40024.9zHpve.rst [new file with mode: 0644]
Modules/_collectionsmodule.c
Modules/_functoolsmodule.c
Modules/_lzmamodule.c
Modules/itertoolsmodule.c
Objects/typeobject.c
Python/modsupport.c

index 8d1a0fbeb76584b2ac65cc97920769a9606f611d..8cf26fbe9e4af5c4926403348c0b41eca367c1ba 100644 (file)
@@ -441,7 +441,7 @@ 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* on success.  Return ``-1`` on error, ``0`` on success.
+   *value* on success. Return ``-1`` on error, ``0`` on success.
 
    .. note::
 
@@ -484,6 +484,16 @@ state:
 
    Add a string constant to *module*.
 
+.. c:function:: int PyModule_AddType(PyObject *module, PyTypeObject *type)
+
+   Add a type object to *module*.
+   The type object is finalized by calling internally :c:func:`PyType_Ready`.
+   The name of the type object is taken from the last component of
+   :c:member:`~PyTypeObject.tp_name` after dot.
+   Return ``-1`` on error, ``0`` on success.
+
+   .. versionadded:: 3.9
+
 
 Module lookup
 ^^^^^^^^^^^^^
index 5c84ca10e20378975f012bebbddb23024827c761..9f9e8951f52d4fd1446c2a460d405208370e5cc7 100644 (file)
@@ -538,6 +538,9 @@ Build and C API Changes
   by the internal C API. Remove also ``PyThreadFrameGetter`` type.
   (Contributed by Victor Stinner in :issue:`39946`.)
 
+* The :c:func:`PyModule_AddType` function is added to help adding a type to a module.
+  (Contributed by Dong-hee Na in :issue:`40024`.)
+
 Deprecated
 ==========
 
index f2dc812df2ba8b78aff0adcf61e834dfb98d6ba5..4c4aab65bac10376e1f6b3e44df13ff6df8f73a9 100644 (file)
@@ -139,6 +139,10 @@ void _PyArg_Fini(void);
 PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *);
 PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long);
 PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *);
+#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
+/* New in 3.9 */
+PyAPI_FUNC(int) PyModule_AddType(PyObject *module, PyTypeObject *type);
+#endif /* Py_LIMITED_API */
 #define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c)
 #define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c)
 
diff --git a/Misc/NEWS.d/next/C API/2020-03-20-18-41-33.bpo-40024.9zHpve.rst b/Misc/NEWS.d/next/C API/2020-03-20-18-41-33.bpo-40024.9zHpve.rst
new file mode 100644 (file)
index 0000000..a0b33dd
--- /dev/null
@@ -0,0 +1 @@
+Add :c:func:`PyModule_AddType` helper function: add a type to a module. Patch by Dong-hee Na.
index a595e5b5ea341c2e2d30b5b6145f126d3eda5a78..11342a35179ef6652d64cc113f258e2c593c6bb4 100644 (file)
@@ -2565,21 +2565,13 @@ collections_exec(PyObject *module) {
         &PyODict_Type,
         &dequeiter_type,
         &dequereviter_type,
-        &tuplegetter_type,
-        NULL,
+        &tuplegetter_type
     };
 
     defdict_type.tp_base = &PyDict_Type;
 
-    for (int i = 0; typelist[i] != NULL; i++) {
-        PyTypeObject *type = typelist[i];
-        if (PyType_Ready(type) < 0) {
-            return -1;
-        }
-        const char *name = _PyType_Name(type);
-        Py_INCREF(type);
-        if (PyModule_AddObject(module, name, (PyObject *)type) < 0) {
-            Py_DECREF(type);
+    for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) {
+        if (PyModule_AddType(module, typelist[i]) < 0) {
             return -1;
         }
     }
index 0c0fae1a979a4fbacc52d1e20a8f7cbca42ee576..ff733b8d45a3086c1b32b75e07e83e4b0b97d055 100644 (file)
@@ -1431,13 +1431,10 @@ static struct PyModuleDef _functoolsmodule = {
 PyMODINIT_FUNC
 PyInit__functools(void)
 {
-    int i;
     PyObject *m;
-    const char *name;
     PyTypeObject *typelist[] = {
         &partial_type,
-        &lru_cache_type,
-        NULL
+        &lru_cache_type
     };
 
     m = PyModule_Create(&_functoolsmodule);
@@ -1450,14 +1447,11 @@ PyInit__functools(void)
         return NULL;
     }
 
-    for (i=0 ; typelist[i] != NULL ; i++) {
-        if (PyType_Ready(typelist[i]) < 0) {
+    for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) {
+        if (PyModule_AddType(m, typelist[i]) < 0) {
             Py_DECREF(m);
             return NULL;
         }
-        name = _PyType_Name(typelist[i]);
-        Py_INCREF(typelist[i]);
-        PyModule_AddObject(m, name, (PyObject *)typelist[i]);
     }
     return m;
 }
index 1ab67f306b73a0dcd2b6c46ccab67ba0ffc7472c..a2027be2e98fb901dcf3b3a6e934e99be4609d63 100644 (file)
@@ -1486,19 +1486,13 @@ PyInit__lzma(void)
     if (PyModule_AddObject(m, "LZMAError", Error) == -1)
         return NULL;
 
-    if (PyType_Ready(&Compressor_type) == -1)
-        return NULL;
-    Py_INCREF(&Compressor_type);
-    if (PyModule_AddObject(m, "LZMACompressor",
-                           (PyObject *)&Compressor_type) == -1)
+    if (PyModule_AddType(m, &Compressor_type) < 0) {
         return NULL;
+    }
 
-    if (PyType_Ready(&Decompressor_type) == -1)
-        return NULL;
-    Py_INCREF(&Decompressor_type);
-    if (PyModule_AddObject(m, "LZMADecompressor",
-                           (PyObject *)&Decompressor_type) == -1)
+    if (PyModule_AddType(m, &Decompressor_type) < 0) {
         return NULL;
+    }
 
     return m;
 }
index 72fd3d7c551caa687717d0babb867fe378f40b33..83d1bb127248005d7416c00783bc1df5b5a15b54 100644 (file)
@@ -4724,21 +4724,13 @@ itertoolsmodule_exec(PyObject *m)
         &groupby_type,
         &_grouper_type,
         &tee_type,
-        &teedataobject_type,
-        NULL
+        &teedataobject_type
     };
 
     Py_SET_TYPE(&teedataobject_type, &PyType_Type);
 
-    for (int i = 0; typelist[i] != NULL; i++) {
-        PyTypeObject *type = typelist[i];
-        if (PyType_Ready(type) < 0) {
-            return -1;
-        }
-        const char *name = _PyType_Name(type);
-        Py_INCREF(type);
-        if (PyModule_AddObject(m, name, (PyObject *)type) < 0) {
-            Py_DECREF(type);
+    for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) {
+        if (PyModule_AddType(m, typelist[i]) < 0) {
             return -1;
         }
     }
index e27c4b2c40a2c0e1a3b1e14d9bbcb9025f2d678e..bed50d1e7f2d3c6c721edc77ed08330fb218a9cc 100644 (file)
@@ -431,6 +431,7 @@ check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *nam
 const char *
 _PyType_Name(PyTypeObject *type)
 {
+    assert(type->tp_name != NULL);
     const char *s = strrchr(type->tp_name, '.');
     if (s == NULL) {
         s = type->tp_name;
index 7271af3ac5332f7b103ff39fca903e76ffadc479..a8e78c3cec88bb0b4da48064190946b3011e3ec8 100644 (file)
@@ -678,3 +678,22 @@ PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
     Py_DECREF(o);
     return -1;
 }
+
+int
+PyModule_AddType(PyObject *module, PyTypeObject *type)
+{
+    if (PyType_Ready(type) < 0) {
+        return -1;
+    }
+
+    const char *name = _PyType_Name(type);
+    assert(name != NULL);
+
+    Py_INCREF(type);
+    if (PyModule_AddObject(module, name, (PyObject *)type) < 0) {
+        Py_DECREF(type);
+        return -1;
+    }
+
+    return 0;
+}