From 5e73355b9bd4495097cdcc218b696dd009bfb785 Mon Sep 17 00:00:00 2001 From: WildCard65 Date: Tue, 30 Jun 2020 12:24:26 -0400 Subject: [PATCH 1/7] bpo-41171: Added companion "FromSpec" methods prefixed with "PyMetaType" to go with the "PyType" variants. --- Doc/c-api/type.rst | 26 ++++++++++++++++++++++---- Include/object.h | 9 ++++++--- Objects/typeobject.c | 17 +++++++++++------ PC/python3dll.c | 4 ++-- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index f387279d143eec..df793971435799 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -142,7 +142,13 @@ The following functions and structs are used to create .. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) - Creates and returns a heap type object from the *spec* + Equivalent to ``PyMetaType_FromModuleAndSpec(module, &PyType_Type, spec, bases)``. + + .. versionadded:: 3.9 + +.. c:function:: PyObject* PyMetaType_FromModuleAndSpec(PyObject *module, PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) + + Creates and returns a heap type object from the *spec* whose's metaclass is *meta_type* (:const:`Py_TPFLAGS_HEAPTYPE`). If *bases* is a tuple, the created heap type contains all types contained @@ -157,17 +163,29 @@ The following functions and structs are used to create This function calls :c:func:`PyType_Ready` on the new type. - .. versionadded:: 3.9 + .. versionadded:: 3.10 .. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) - Equivalent to ``PyType_FromModuleAndSpec(NULL, spec, bases)``. + Equivalent to ``PyMetaType_FromSpecWithBases(&PyType_Type, spec, bases)``. .. versionadded:: 3.3 +.. c:function:: PyObject* PyMetaType_FromSpecWithBases(PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) + + Equivalent to ``PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, bases)``. + + .. versionadded:: 3.10 + .. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec) - Equivalent to ``PyType_FromSpecWithBases(spec, NULL)``. + Equivalent to ``PyMetaType_FromSpec(&PyType_Type, spec)``. + +.. c:function:: PyObject* PyMetaType_FromSpec(PyTypeObject *meta_type, PyType_Spec *spec) + + Equivalent to ``PyMetaType_FromSpecWithBases(meta_type, spec, NULL)`` + + .. versionadded:: 3.10 .. c:type:: PyType_Spec diff --git a/Include/object.h b/Include/object.h index 537567040f9871..66dce0f8e84ae3 100644 --- a/Include/object.h +++ b/Include/object.h @@ -225,15 +225,18 @@ typedef struct{ PyType_Slot *slots; /* terminated by slot==0. */ } PyType_Spec; -PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*); +#define PyType_FromSpec(spec) PyMetaType_FromSpec(&PyType_Type, spec) +PyAPI_FUNC(PyObject*) PyMetaType_FromSpec(PyTypeObject*, PyType_Spec*); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject*) PyType_FromSpecWithBases(PyType_Spec*, PyObject*); +#define PyType_FromSpecWithBases(spec, bases) PyMetaType_FromSpecWithBases(&PyType_Type, spec, bases) +PyAPI_FUNC(PyObject*) PyMetaType_FromSpecWithBases(PyTypeObject*, PyType_Spec*, PyObject*); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -PyAPI_FUNC(PyObject*) PyType_FromModuleAndSpec(PyObject *, PyType_Spec *, PyObject *); +#define PyType_FromModuleAndSpec(module, spec, bases) PyMetaType_FromModuleAndSpec(module, &PyType_Type, spec, bases) +PyAPI_FUNC(PyObject*) PyMetaType_FromModuleAndSpec(PyObject*, PyTypeObject*, PyType_Spec*, PyObject*); PyAPI_FUNC(PyObject *) PyType_GetModule(struct _typeobject *); PyAPI_FUNC(void *) PyType_GetModuleState(struct _typeobject *); #endif diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f0e349ecd2bb92..e62f1e46111de6 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2880,14 +2880,19 @@ static const short slotoffsets[] = { }; PyObject * -PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) +PyMetaType_FromSpecWithBases(PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) { - return PyType_FromModuleAndSpec(NULL, spec, bases); + return PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, bases); } PyObject * -PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +PyMetaType_FromModuleAndSpec(PyObject *module, PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) { + if (meta_type == NULL) { + PyErr_BadArgument(); + return NULL; + } + PyHeapTypeObject *res; PyObject *modname; PyTypeObject *type, *base; @@ -2924,7 +2929,7 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) } } - res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, nmembers); + res = (PyHeapTypeObject*)PyType_GenericAlloc(meta_type, nmembers); if (res == NULL) return NULL; res_start = (char*)res; @@ -3099,9 +3104,9 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) } PyObject * -PyType_FromSpec(PyType_Spec *spec) +PyMetaType_FromSpec(PyTypeObject *meta_type, PyType_Spec *spec) { - return PyType_FromSpecWithBases(spec, NULL); + return PyMetaType_FromSpecWithBases(meta_type, spec, NULL); } void * diff --git a/PC/python3dll.c b/PC/python3dll.c index f72f2c8af19d2b..65cf06abb28187 100644 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -541,8 +541,8 @@ EXPORT_FUNC(PyTuple_Pack) EXPORT_FUNC(PyTuple_SetItem) EXPORT_FUNC(PyTuple_Size) EXPORT_FUNC(PyType_ClearCache) -EXPORT_FUNC(PyType_FromSpec) -EXPORT_FUNC(PyType_FromSpecWithBases) +EXPORT_FUNC(PyMetaType_FromSpec) +EXPORT_FUNC(PyMetaType_FromSpecWithBases) EXPORT_FUNC(PyType_GenericAlloc) EXPORT_FUNC(PyType_GenericNew) EXPORT_FUNC(PyType_GetFlags) From 745387c30bcad3e208ff37eec0636f9992690004 Mon Sep 17 00:00:00 2001 From: WildCard65 Date: Tue, 30 Jun 2020 16:58:20 -0400 Subject: [PATCH 2/7] Removed 'PyMetaType_FromSpecAndBases'. Added a note about 'PyMetaType_FromModuleAndSpec' in regards to 'tp_new'. --- Doc/c-api/type.rst | 16 +++++++--------- Include/object.h | 3 +-- Objects/typeobject.c | 8 +------- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index df793971435799..5033b0ed1181bf 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -161,21 +161,19 @@ The following functions and structs are used to create If not ``NULL``, the module is associated with the new type and can later be retreived with :c:func:`PyType_GetModule`. - This function calls :c:func:`PyType_Ready` on the new type. + This function calls :c:func:`PyType_Ready` on the new type.' - .. versionadded:: 3.10 - -.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) + .. note:: - Equivalent to ``PyMetaType_FromSpecWithBases(&PyType_Type, spec, bases)``. + This method DOES NOT invoke ``PyTypeObject.tp_new`` on 'meta_type'. - .. versionadded:: 3.3 + .. versionadded:: 3.10 -.. c:function:: PyObject* PyMetaType_FromSpecWithBases(PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) +.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) Equivalent to ``PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, bases)``. - .. versionadded:: 3.10 + .. versionadded:: 3.3 .. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec) @@ -183,7 +181,7 @@ The following functions and structs are used to create .. c:function:: PyObject* PyMetaType_FromSpec(PyTypeObject *meta_type, PyType_Spec *spec) - Equivalent to ``PyMetaType_FromSpecWithBases(meta_type, spec, NULL)`` + Equivalent to ``PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, NULL)`` .. versionadded:: 3.10 diff --git a/Include/object.h b/Include/object.h index 66dce0f8e84ae3..bbcf32e15970e4 100644 --- a/Include/object.h +++ b/Include/object.h @@ -228,8 +228,7 @@ typedef struct{ #define PyType_FromSpec(spec) PyMetaType_FromSpec(&PyType_Type, spec) PyAPI_FUNC(PyObject*) PyMetaType_FromSpec(PyTypeObject*, PyType_Spec*); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -#define PyType_FromSpecWithBases(spec, bases) PyMetaType_FromSpecWithBases(&PyType_Type, spec, bases) -PyAPI_FUNC(PyObject*) PyMetaType_FromSpecWithBases(PyTypeObject*, PyType_Spec*, PyObject*); +#define PyType_FromSpecWithBases(spec, bases) PyMetaType_FromModuleAndSpec(NULL, &PyType_Type, spec, bases) #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e62f1e46111de6..c506c8c5806bb7 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2879,12 +2879,6 @@ static const short slotoffsets[] = { #include "typeslots.inc" }; -PyObject * -PyMetaType_FromSpecWithBases(PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) -{ - return PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, bases); -} - PyObject * PyMetaType_FromModuleAndSpec(PyObject *module, PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) { @@ -3106,7 +3100,7 @@ PyMetaType_FromModuleAndSpec(PyObject *module, PyTypeObject *meta_type, PyType_S PyObject * PyMetaType_FromSpec(PyTypeObject *meta_type, PyType_Spec *spec) { - return PyMetaType_FromSpecWithBases(meta_type, spec, NULL); + return PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, NULL); } void * From e2cde2cf4ac91eeb20e8c0f5d2962e106b2f76dc Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2020 16:31:16 +0000 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst diff --git a/Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst b/Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst new file mode 100644 index 00000000000000..42c2e956c92cb7 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst @@ -0,0 +1 @@ +Added new "FromSpec" methods prefixed with "PyMetaType" to specify the metaclass for the created heap type at type creation. \ No newline at end of file From faa247a747f604f49fdc226e0e9f7f7ff7cb9bc0 Mon Sep 17 00:00:00 2001 From: WildCard65 Date: Tue, 30 Jun 2020 17:02:50 -0400 Subject: [PATCH 4/7] Fixed documentation error of 'PyType_FromSpecWithBases' --- Doc/c-api/type.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 5033b0ed1181bf..06771881a12bd4 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -171,7 +171,7 @@ The following functions and structs are used to create .. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) - Equivalent to ``PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, bases)``. + Equivalent to ``PyMetaType_FromModuleAndSpec(NULL, &PyType_Type, spec, bases)``. .. versionadded:: 3.3 From 90899113340f9fd0a4f0b50c2853515dfdeb25e8 Mon Sep 17 00:00:00 2001 From: WildCard65 Date: Tue, 30 Jun 2020 17:04:25 -0400 Subject: [PATCH 5/7] Fixed dangling function export. --- PC/python3dll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PC/python3dll.c b/PC/python3dll.c index 65cf06abb28187..a224f75557738c 100644 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -542,7 +542,7 @@ EXPORT_FUNC(PyTuple_SetItem) EXPORT_FUNC(PyTuple_Size) EXPORT_FUNC(PyType_ClearCache) EXPORT_FUNC(PyMetaType_FromSpec) -EXPORT_FUNC(PyMetaType_FromSpecWithBases) +EXPORT_FUNC(PyMetaType_FromModuleAndSpec) EXPORT_FUNC(PyType_GenericAlloc) EXPORT_FUNC(PyType_GenericNew) EXPORT_FUNC(PyType_GetFlags) From 1ea9a54a798080c7793e33b2595a435654a0b8e2 Mon Sep 17 00:00:00 2001 From: WildCard65 Date: Tue, 30 Jun 2020 17:17:07 -0400 Subject: [PATCH 6/7] Renamed "PyMetaType_FromModuleAndSpec" to "PyMetaType_FromSpec". Removed other "PyMetaType" variants. --- Doc/c-api/type.rst | 14 ++++---------- Include/object.h | 9 ++++----- Objects/typeobject.c | 8 +------- PC/python3dll.c | 1 - 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 06771881a12bd4..75b81396c6ebba 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -142,11 +142,11 @@ The following functions and structs are used to create .. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) - Equivalent to ``PyMetaType_FromModuleAndSpec(module, &PyType_Type, spec, bases)``. + Equivalent to ``PyMetaType_FromSpec(module, &PyType_Type, spec, bases)``. .. versionadded:: 3.9 -.. c:function:: PyObject* PyMetaType_FromModuleAndSpec(PyObject *module, PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) +.. c:function:: PyObject* PyMetaType_FromSpec(PyObject *module, PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) Creates and returns a heap type object from the *spec* whose's metaclass is *meta_type* (:const:`Py_TPFLAGS_HEAPTYPE`). @@ -171,19 +171,13 @@ The following functions and structs are used to create .. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) - Equivalent to ``PyMetaType_FromModuleAndSpec(NULL, &PyType_Type, spec, bases)``. + Equivalent to ``PyMetaType_FromSpec(NULL, &PyType_Type, spec, bases)``. .. versionadded:: 3.3 .. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec) - Equivalent to ``PyMetaType_FromSpec(&PyType_Type, spec)``. - -.. c:function:: PyObject* PyMetaType_FromSpec(PyTypeObject *meta_type, PyType_Spec *spec) - - Equivalent to ``PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, NULL)`` - - .. versionadded:: 3.10 + Equivalent to ``PyMetaType_FromSpec(NULL, &PyType_Type, spec, NULL)``. .. c:type:: PyType_Spec diff --git a/Include/object.h b/Include/object.h index bbcf32e15970e4..f3eae2341bd433 100644 --- a/Include/object.h +++ b/Include/object.h @@ -225,17 +225,16 @@ typedef struct{ PyType_Slot *slots; /* terminated by slot==0. */ } PyType_Spec; -#define PyType_FromSpec(spec) PyMetaType_FromSpec(&PyType_Type, spec) -PyAPI_FUNC(PyObject*) PyMetaType_FromSpec(PyTypeObject*, PyType_Spec*); +#define PyType_FromSpec(spec) PyMetaType_FromSpec(NULL, &PyType_Type, spec, NULL) +PyAPI_FUNC(PyObject*) PyMetaType_FromSpec(PyObject*, PyTypeObject*, PyType_Spec*, PyObject*); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -#define PyType_FromSpecWithBases(spec, bases) PyMetaType_FromModuleAndSpec(NULL, &PyType_Type, spec, bases) +#define PyType_FromSpecWithBases(spec, bases) PyMetaType_FromSpec(NULL, &PyType_Type, spec, bases) #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -#define PyType_FromModuleAndSpec(module, spec, bases) PyMetaType_FromModuleAndSpec(module, &PyType_Type, spec, bases) -PyAPI_FUNC(PyObject*) PyMetaType_FromModuleAndSpec(PyObject*, PyTypeObject*, PyType_Spec*, PyObject*); +#define PyType_FromModuleAndSpec(module, spec, bases) PyMetaType_FromSpec(module, &PyType_Type, spec, bases) PyAPI_FUNC(PyObject *) PyType_GetModule(struct _typeobject *); PyAPI_FUNC(void *) PyType_GetModuleState(struct _typeobject *); #endif diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c506c8c5806bb7..80c408f9b413dd 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2880,7 +2880,7 @@ static const short slotoffsets[] = { }; PyObject * -PyMetaType_FromModuleAndSpec(PyObject *module, PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) +PyMetaType_FromSpec(PyObject *module, PyTypeObject *meta_type, PyType_Spec *spec, PyObject *bases) { if (meta_type == NULL) { PyErr_BadArgument(); @@ -3097,12 +3097,6 @@ PyMetaType_FromModuleAndSpec(PyObject *module, PyTypeObject *meta_type, PyType_S return NULL; } -PyObject * -PyMetaType_FromSpec(PyTypeObject *meta_type, PyType_Spec *spec) -{ - return PyMetaType_FromModuleAndSpec(NULL, meta_type, spec, NULL); -} - void * PyType_GetSlot(PyTypeObject *type, int slot) { diff --git a/PC/python3dll.c b/PC/python3dll.c index a224f75557738c..96bb6abd59d121 100644 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -542,7 +542,6 @@ EXPORT_FUNC(PyTuple_SetItem) EXPORT_FUNC(PyTuple_Size) EXPORT_FUNC(PyType_ClearCache) EXPORT_FUNC(PyMetaType_FromSpec) -EXPORT_FUNC(PyMetaType_FromModuleAndSpec) EXPORT_FUNC(PyType_GenericAlloc) EXPORT_FUNC(PyType_GenericNew) EXPORT_FUNC(PyType_GetFlags) From df908febfea8b73e11ee19598b8c04d68217b412 Mon Sep 17 00:00:00 2001 From: WildCard65 Date: Tue, 30 Jun 2020 17:26:35 -0400 Subject: [PATCH 7/7] Updated NEWS entry to reflect changes. --- Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst b/Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst index 42c2e956c92cb7..99e6b2dace47a9 100644 --- a/Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst +++ b/Misc/NEWS.d/next/C API/2020-06-30-16-31-15.bpo-41171.wFnoOM.rst @@ -1 +1 @@ -Added new "FromSpec" methods prefixed with "PyMetaType" to specify the metaclass for the created heap type at type creation. \ No newline at end of file +Added method "PyMetaType_FromSpec" to allow for specifying the metaclass for the type. \ No newline at end of file