]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-41832: PyType_FromModuleAndSpec() now accepts NULL tp_doc (GH-23123)
authorHai Shi <shihai1992@gmail.com>
Fri, 6 Nov 2020 16:04:47 +0000 (00:04 +0800)
committerGitHub <noreply@github.com>
Fri, 6 Nov 2020 16:04:47 +0000 (17:04 +0100)
Doc/c-api/type.rst
Doc/whatsnew/3.10.rst
Lib/test/test_capi.py
Misc/NEWS.d/next/C API/2020-11-03-19-47-06.bpo-41832.dL1VJJ.rst [new file with mode: 0644]
Modules/_lsprof.c
Modules/_testcapimodule.c
Objects/typeobject.c

index 73f26875d8194a844022ec3ea3b445570133d335..fcd92e38e2428e2834743cc145d7c84cf3eb751f 100644 (file)
@@ -169,6 +169,10 @@ The following functions and structs are used to create
 
    .. versionadded:: 3.9
 
+   .. versionchanged:: 3.10
+
+      The function now accepts NULL ``tp_doc`` slot.
+
 .. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
 
    Equivalent to ``PyType_FromModuleAndSpec(NULL, spec, bases)``.
@@ -259,5 +263,3 @@ The following functions and structs are used to create
 
       The desired value of the slot. In most cases, this is a pointer
       to a function.
-
-      May not be ``NULL``.
index 0ed7084ccd2ff0054353b99272b8fadf5a34de73..1e6c7c4067f3fac819151c5df25edcf08988a94e 100644 (file)
@@ -401,6 +401,10 @@ New Features
   reference count of an object and return the object.
   (Contributed by Victor Stinner in :issue:`42262`.)
 
+* The :c:func:`PyType_FromModuleAndSpec` function now accepts NULL ``tp_doc``
+  slot.
+  (Contributed by Hai Shi in :issue:`41832`.)
+
 
 Porting to Python 3.10
 ----------------------
index db62b47100ad3a20f73a5d35bf08077fb32a2d8f..a4ebe4a0a1b5cb32017311c0f94b7dc2a26111b2 100644 (file)
@@ -405,6 +405,9 @@ class CAPITest(unittest.TestCase):
         self.assertEqual(_testcapi.HeapDocCType.__doc__, "somedoc")
         self.assertEqual(_testcapi.HeapDocCType.__text_signature__, "(arg1, arg2)")
 
+    def test_null_type_doc(self):
+        self.assertEqual(_testcapi.NullTpDocType.__doc__, None)
+
     def test_subclass_of_heap_gc_ctype_with_tpdealloc_decrefs_once(self):
         class HeapGcCTypeSubclass(_testcapi.HeapGcCType):
             def __init__(self):
diff --git a/Misc/NEWS.d/next/C API/2020-11-03-19-47-06.bpo-41832.dL1VJJ.rst b/Misc/NEWS.d/next/C API/2020-11-03-19-47-06.bpo-41832.dL1VJJ.rst
new file mode 100644 (file)
index 0000000..e0bce54
--- /dev/null
@@ -0,0 +1,2 @@
+The :c:func:`PyType_FromModuleAndSpec` function now accepts NULL ``tp_doc``
+slot.
index 78d464d1481d75e63497be71fbf62adc2bf59924..c32699cb8ad5805ea1651bff03d9f87a439f7d62 100644 (file)
@@ -489,15 +489,15 @@ static PyStructSequence_Field profiler_subentry_fields[] = {
 
 static PyStructSequence_Desc profiler_entry_desc = {
     .name = "_lsprof.profiler_entry",
-    .doc = "",
     .fields = profiler_entry_fields,
+    .doc = NULL,
     .n_in_sequence = 6
 };
 
 static PyStructSequence_Desc profiler_subentry_desc = {
     .name = "_lsprof.profiler_subentry",
-    .doc = "",
     .fields = profiler_subentry_fields,
+    .doc = NULL,
     .n_in_sequence = 5
 };
 
index 28d2c124d517758048db7f784e380c2be49e3b83..22d20d220d408920274ce40d9d178ccb19c41cd8 100644 (file)
@@ -6508,6 +6508,23 @@ static PyType_Spec HeapDocCType_spec = {
     HeapDocCType_slots
 };
 
+typedef struct {
+    PyObject_HEAD
+} NullTpDocTypeObject;
+
+static PyType_Slot NullTpDocType_slots[] = {
+    {Py_tp_doc, NULL},
+    {0, 0},
+};
+
+static PyType_Spec NullTpDocType_spec = {
+    "_testcapi.NullTpDocType",
+    sizeof(NullTpDocTypeObject),
+    0,
+    Py_TPFLAGS_DEFAULT,
+    NullTpDocType_slots
+};
+
 
 PyDoc_STRVAR(heapgctype__doc__,
 "A heap type with GC, and with overridden dealloc.\n\n"
@@ -7183,6 +7200,14 @@ PyInit__testcapi(void)
     }
     PyModule_AddObject(m, "HeapDocCType", HeapDocCType);
 
+    /* bpo-41832: Add a new type to test PyType_FromSpec()
+       now can accept a NULL tp_doc slot. */
+    PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec);
+    if (NullTpDocType == NULL) {
+        return NULL;
+    }
+    PyModule_AddObject(m, "NullTpDocType", NullTpDocType);
+
     PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec);
     if (HeapGcCType == NULL) {
         return NULL;
index 2daf374f170b02b7c88d63dd6cf18e51f2ecea0e..3822b8cf813cfbfcbd553111da54b29865353346 100644 (file)
@@ -3012,6 +3012,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
         else if (slot->slot == Py_tp_doc) {
             /* For the docstring slot, which usually points to a static string
                literal, we need to make a copy */
+            if (slot->pfunc == NULL) {
+                type->tp_doc = NULL;
+                continue;
+            }
             size_t len = strlen(slot->pfunc)+1;
             char *tp_doc = PyObject_MALLOC(len);
             if (tp_doc == NULL) {