From 686c203cd4355be5b7809a9d24b4aa3566d9371f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 22 Nov 2020 13:25:02 +0200 Subject: bpo-42423: Accept single base class in PyType_FromModuleAndSpec() (GH-23441) --- Doc/c-api/type.rst | 8 ++++---- Doc/whatsnew/3.10.rst | 4 ++++ Misc/NEWS.d/next/C API/2020-11-21-12-27-19.bpo-42423.ByJHhY.rst | 3 +++ Modules/_hashopenssl.c | 9 +-------- Modules/_ssl.c | 7 +------ Objects/structseq.c | 9 +-------- Objects/typeobject.c | 5 +++-- 7 files changed, 17 insertions(+), 28 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-11-21-12-27-19.bpo-42423.ByJHhY.rst diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index a822b67..a869859 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -154,9 +154,8 @@ The following functions and structs are used to create Creates and returns a heap type object from the *spec* (:const:`Py_TPFLAGS_HEAPTYPE`). - If *bases* is a tuple, the created heap type contains all types contained - in it as base types. - + The *bases* argument can be used to specify base classes; it can either + be only one class or a tuple of classes. If *bases* is ``NULL``, the *Py_tp_bases* slot is used instead. If that also is ``NULL``, the *Py_tp_base* slot is used instead. If that also is ``NULL``, the new type derives from :class:`object`. @@ -174,7 +173,8 @@ The following functions and structs are used to create .. versionchanged:: 3.10 - The function now accepts NULL ``tp_doc`` slot. + The function now accepts a single class as the *bases* argument and + ``NULL`` as the ``tp_doc`` slot. .. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 16cb7ef..ce66b1d 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -512,6 +512,10 @@ New Features reference count of an object and return the object. (Contributed by Victor Stinner in :issue:`42262`.) +* The :c:func:`PyType_FromSpecWithBases` and :c:func:`PyType_FromModuleAndSpec` + functions now accept a single class as the *bases* argument. + (Contributed by Serhiy Storchaka in :issue:`42423`.) + * The :c:func:`PyType_FromModuleAndSpec` function now accepts NULL ``tp_doc`` slot. (Contributed by Hai Shi in :issue:`41832`.) diff --git a/Misc/NEWS.d/next/C API/2020-11-21-12-27-19.bpo-42423.ByJHhY.rst b/Misc/NEWS.d/next/C API/2020-11-21-12-27-19.bpo-42423.ByJHhY.rst new file mode 100644 index 0000000..046a89d --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-11-21-12-27-19.bpo-42423.ByJHhY.rst @@ -0,0 +1,3 @@ +The :c:func:`PyType_FromSpecWithBases` and +:c:func:`PyType_FromModuleAndSpec` functions now accept a single class as +the *bases* argument. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 56d2a77..7e176cf 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -2038,21 +2038,14 @@ hashlib_init_evpxoftype(PyObject *module) { #ifdef PY_OPENSSL_HAS_SHAKE _hashlibstate *state = get_hashlib_state(module); - PyObject *bases; if (state->EVPtype == NULL) { return -1; } - bases = PyTuple_Pack(1, state->EVPtype); - if (bases == NULL) { - return -1; - } - state->EVPXOFtype = (PyTypeObject *)PyType_FromSpecWithBases( - &EVPXOFtype_spec, bases + &EVPXOFtype_spec, (PyObject *)state->EVPtype ); - Py_DECREF(bases); if (state->EVPXOFtype == NULL) { return -1; } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 130dce4..6f799ee 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5955,12 +5955,7 @@ do { \ if (PyModule_AddObjectRef(module, name, exc) < 0) goto error; \ } while(0) - bases = PyTuple_Pack(1, PyExc_OSError); - if (bases == NULL) { - goto error; - } - PySSLErrorObject = PyType_FromSpecWithBases(&sslerror_type_spec, bases); - Py_CLEAR(bases); + PySSLErrorObject = PyType_FromSpecWithBases(&sslerror_type_spec, PyExc_OSError); if (PySSLErrorObject == NULL) { goto error; } diff --git a/Objects/structseq.c b/Objects/structseq.c index 5caa3bd..bb28e11 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -492,7 +492,6 @@ PyTypeObject * PyStructSequence_NewType(PyStructSequence_Desc *desc) { PyMemberDef *members; - PyObject *bases; PyTypeObject *type; PyType_Slot slots[8]; PyType_Spec spec; @@ -526,13 +525,7 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC; spec.slots = slots; - bases = PyTuple_Pack(1, &PyTuple_Type); - if (bases == NULL) { - PyMem_FREE(members); - return NULL; - } - type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, bases); - Py_DECREF(bases); + type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, (PyObject *)&PyTuple_Type); PyMem_FREE(members); if (type == NULL) { return NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 9ebeeeb..3a6143a 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2993,8 +2993,9 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) } } else if (!PyTuple_Check(bases)) { - PyErr_SetString(PyExc_SystemError, "bases is not a tuple"); - goto fail; + bases = PyTuple_Pack(1, bases); + if (!bases) + goto fail; } else { Py_INCREF(bases); -- cgit v0.12