aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHai Shi <shihai1992@gmail.com>2020-11-07 00:04:47 +0800
committerGitHub <noreply@github.com>2020-11-06 17:04:47 +0100
commit88c2cfd9ffbcfc43fd1364f2984852a819547d43 (patch)
tree85571ab2d826b5eed1e084c9b973e3f9016fecd9
parentMinor grammar edits for the descriptor howto guide (GH-#23175) (diff)
downloadcpython-88c2cfd9ffbcfc43fd1364f2984852a819547d43.tar.gz
cpython-88c2cfd9ffbcfc43fd1364f2984852a819547d43.tar.bz2
cpython-88c2cfd9ffbcfc43fd1364f2984852a819547d43.zip
bpo-41832: PyType_FromModuleAndSpec() now accepts NULL tp_doc (GH-23123)
-rw-r--r--Doc/c-api/type.rst6
-rw-r--r--Doc/whatsnew/3.10.rst4
-rw-r--r--Lib/test/test_capi.py3
-rw-r--r--Misc/NEWS.d/next/C API/2020-11-03-19-47-06.bpo-41832.dL1VJJ.rst2
-rw-r--r--Modules/_lsprof.c4
-rw-r--r--Modules/_testcapimodule.c25
-rw-r--r--Objects/typeobject.c4
7 files changed, 44 insertions, 4 deletions
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index 73f26875d81..fcd92e38e24 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -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``.
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 0ed7084ccd2..1e6c7c4067f 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -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
----------------------
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index db62b47100a..a4ebe4a0a1b 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -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
index 00000000000..e0bce54eb93
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2020-11-03-19-47-06.bpo-41832.dL1VJJ.rst
@@ -0,0 +1,2 @@
+The :c:func:`PyType_FromModuleAndSpec` function now accepts NULL ``tp_doc``
+slot.
diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c
index 78d464d1481..c32699cb8ad 100644
--- a/Modules/_lsprof.c
+++ b/Modules/_lsprof.c
@@ -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
};
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 28d2c124d51..22d20d220d4 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -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;
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 2daf374f170..3822b8cf813 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -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) {