Skip to content

Commit 88c2cfd

Browse files
authored
bpo-41832: PyType_FromModuleAndSpec() now accepts NULL tp_doc (GH-23123)
1 parent 8031877 commit 88c2cfd

File tree

7 files changed

+44
-4
lines changed

7 files changed

+44
-4
lines changed

Doc/c-api/type.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ The following functions and structs are used to create
169169
170170
.. versionadded:: 3.9
171171
172+
.. versionchanged:: 3.10
173+
174+
The function now accepts NULL ``tp_doc`` slot.
175+
172176
.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
173177
174178
Equivalent to ``PyType_FromModuleAndSpec(NULL, spec, bases)``.
@@ -259,5 +263,3 @@ The following functions and structs are used to create
259263
260264
The desired value of the slot. In most cases, this is a pointer
261265
to a function.
262-
263-
May not be ``NULL``.

Doc/whatsnew/3.10.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,10 @@ New Features
401401
reference count of an object and return the object.
402402
(Contributed by Victor Stinner in :issue:`42262`.)
403403

404+
* The :c:func:`PyType_FromModuleAndSpec` function now accepts NULL ``tp_doc``
405+
slot.
406+
(Contributed by Hai Shi in :issue:`41832`.)
407+
404408

405409
Porting to Python 3.10
406410
----------------------

Lib/test/test_capi.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,9 @@ def test_heap_ctype_doc_and_text_signature(self):
405405
self.assertEqual(_testcapi.HeapDocCType.__doc__, "somedoc")
406406
self.assertEqual(_testcapi.HeapDocCType.__text_signature__, "(arg1, arg2)")
407407

408+
def test_null_type_doc(self):
409+
self.assertEqual(_testcapi.NullTpDocType.__doc__, None)
410+
408411
def test_subclass_of_heap_gc_ctype_with_tpdealloc_decrefs_once(self):
409412
class HeapGcCTypeSubclass(_testcapi.HeapGcCType):
410413
def __init__(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The :c:func:`PyType_FromModuleAndSpec` function now accepts NULL ``tp_doc``
2+
slot.

Modules/_lsprof.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,15 +489,15 @@ static PyStructSequence_Field profiler_subentry_fields[] = {
489489

490490
static PyStructSequence_Desc profiler_entry_desc = {
491491
.name = "_lsprof.profiler_entry",
492-
.doc = "",
493492
.fields = profiler_entry_fields,
493+
.doc = NULL,
494494
.n_in_sequence = 6
495495
};
496496

497497
static PyStructSequence_Desc profiler_subentry_desc = {
498498
.name = "_lsprof.profiler_subentry",
499-
.doc = "",
500499
.fields = profiler_subentry_fields,
500+
.doc = NULL,
501501
.n_in_sequence = 5
502502
};
503503

Modules/_testcapimodule.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6508,6 +6508,23 @@ static PyType_Spec HeapDocCType_spec = {
65086508
HeapDocCType_slots
65096509
};
65106510

6511+
typedef struct {
6512+
PyObject_HEAD
6513+
} NullTpDocTypeObject;
6514+
6515+
static PyType_Slot NullTpDocType_slots[] = {
6516+
{Py_tp_doc, NULL},
6517+
{0, 0},
6518+
};
6519+
6520+
static PyType_Spec NullTpDocType_spec = {
6521+
"_testcapi.NullTpDocType",
6522+
sizeof(NullTpDocTypeObject),
6523+
0,
6524+
Py_TPFLAGS_DEFAULT,
6525+
NullTpDocType_slots
6526+
};
6527+
65116528

65126529
PyDoc_STRVAR(heapgctype__doc__,
65136530
"A heap type with GC, and with overridden dealloc.\n\n"
@@ -7183,6 +7200,14 @@ PyInit__testcapi(void)
71837200
}
71847201
PyModule_AddObject(m, "HeapDocCType", HeapDocCType);
71857202

7203+
/* bpo-41832: Add a new type to test PyType_FromSpec()
7204+
now can accept a NULL tp_doc slot. */
7205+
PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec);
7206+
if (NullTpDocType == NULL) {
7207+
return NULL;
7208+
}
7209+
PyModule_AddObject(m, "NullTpDocType", NullTpDocType);
7210+
71867211
PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec);
71877212
if (HeapGcCType == NULL) {
71887213
return NULL;

Objects/typeobject.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3012,6 +3012,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
30123012
else if (slot->slot == Py_tp_doc) {
30133013
/* For the docstring slot, which usually points to a static string
30143014
literal, we need to make a copy */
3015+
if (slot->pfunc == NULL) {
3016+
type->tp_doc = NULL;
3017+
continue;
3018+
}
30153019
size_t len = strlen(slot->pfunc)+1;
30163020
char *tp_doc = PyObject_MALLOC(len);
30173021
if (tp_doc == NULL) {

0 commit comments

Comments
 (0)