Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.10.rst
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@ New Features
* Added :c:func:`PyUnicode_AsUTF8AndSize` to the limited C API.
(Contributed by Alex Gaynor in :issue:`41784`.)

* The :c:func:`PyType_FromModuleAndSpec` function now accepts NULL ``tp_doc``
slot.
(Contributed by Hai Shi in :issue:`41832`.)


Porting to Python 3.10
----------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:c:func:`PyType_FromModuleAndSpec` can accept tp_doc=NULL.
2 changes: 0 additions & 2 deletions Modules/_lsprof.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,14 +489,12 @@ static PyStructSequence_Field profiler_subentry_fields[] = {

static PyStructSequence_Desc profiler_entry_desc = {
.name = "_lsprof.profiler_entry",
.doc = "",
.fields = profiler_entry_fields,
.n_in_sequence = 6
};

static PyStructSequence_Desc profiler_subentry_desc = {
.name = "_lsprof.profiler_subentry",
.doc = "",
.fields = profiler_subentry_fields,
.n_in_sequence = 5
};
Expand Down
16 changes: 16 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3990,6 +3990,21 @@ test_structseq_newtype_doesnt_leak(PyObject *Py_UNUSED(self),
Py_RETURN_NONE;
}

static PyType_Spec HeapDocCType_spec;

static PyObject *
test_PyType_FromSpec(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
{
void *tp_doc = HeapDocCType_spec.slots[0].pfunc;
HeapDocCType_spec.slots[0].pfunc = NULL;
PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec);
assert(HeapDocCType != NULL);
HeapDocCType_spec.slots[0].pfunc = tp_doc;
Py_DECREF(HeapDocCType);

Py_RETURN_NONE;
}

static PyObject *
test_incref_decref_API(PyObject *ob, PyObject *Py_UNUSED(ignored))
{
Expand Down Expand Up @@ -5601,6 +5616,7 @@ static PyMethodDef TestMethods[] = {
{"test_decref_doesnt_leak", test_decref_doesnt_leak, METH_NOARGS},
{"test_structseq_newtype_doesnt_leak",
test_structseq_newtype_doesnt_leak, METH_NOARGS},
{"test_PyType_FromSpec", test_PyType_FromSpec, METH_NOARGS},
{"test_incref_decref_API", test_incref_decref_API, METH_NOARGS},
{"test_long_and_overflow", test_long_and_overflow, METH_NOARGS},
{"test_long_as_double", test_long_as_double, METH_NOARGS},
Expand Down
6 changes: 6 additions & 0 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3012,6 +3012,12 @@ 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 */

/* bpo-41832: PyType_FromModuleAndSpec() can accept tp_doc=NULL. */
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) {
Expand Down