summaryrefslogtreecommitdiffstats
path: root/Modules/_testcapimodule.c
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-06-01 23:06:38 (GMT)
committerGitHub <noreply@github.com>2023-06-01 23:06:38 (GMT)
commitd57ee813ebd496a3fd8118d7dc057d54c4af847e (patch)
tree0ca49a125b77d250c937925e7405f72fc1cad978 /Modules/_testcapimodule.c
parentd2be5c73ed520fb9d82a395f001eb9001711ed8f (diff)
downloadcpython-d57ee813ebd496a3fd8118d7dc057d54c4af847e.zip
cpython-d57ee813ebd496a3fd8118d7dc057d54c4af847e.tar.gz
cpython-d57ee813ebd496a3fd8118d7dc057d54c4af847e.tar.bz2
[3.12] gh-104614: Make Sure ob_type is Always Set Correctly by PyType_Ready() (gh-105122) (gh-105211)
When I added the relevant condition to type_ready_set_bases() in gh-103912, I had missed that the function also sets tp_base and ob_type (if necessary). That led to problems for third-party static types. We fix that here, by making those extra operations distinct and by adjusting the condition to be more specific. (cherry picked from commit 1469393) Co-authored-by: Eric Snow ericsnowcurrently@gmail.com
Diffstat (limited to 'Modules/_testcapimodule.c')
-rw-r--r--Modules/_testcapimodule.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 66c1cba..3caaca3 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2627,6 +2627,50 @@ type_get_tp_mro(PyObject *self, PyObject *type)
}
+/* We only use 2 in test_capi/test_misc.py. */
+#define NUM_BASIC_STATIC_TYPES 2
+static PyTypeObject BasicStaticTypes[NUM_BASIC_STATIC_TYPES] = {
+#define INIT_BASIC_STATIC_TYPE \
+ { \
+ PyVarObject_HEAD_INIT(NULL, 0) \
+ .tp_name = "BasicStaticType", \
+ .tp_basicsize = sizeof(PyObject), \
+ }
+ INIT_BASIC_STATIC_TYPE,
+ INIT_BASIC_STATIC_TYPE,
+#undef INIT_BASIC_STATIC_TYPE
+};
+static int num_basic_static_types_used = 0;
+
+static PyObject *
+get_basic_static_type(PyObject *self, PyObject *args)
+{
+ PyObject *base = NULL;
+ if (!PyArg_ParseTuple(args, "|O", &base)) {
+ return NULL;
+ }
+ assert(base == NULL || PyType_Check(base));
+
+ if(num_basic_static_types_used >= NUM_BASIC_STATIC_TYPES) {
+ PyErr_SetString(PyExc_RuntimeError, "no more available basic static types");
+ return NULL;
+ }
+ PyTypeObject *cls = &BasicStaticTypes[num_basic_static_types_used++];
+
+ if (base != NULL) {
+ cls->tp_base = (PyTypeObject *)Py_NewRef(base);
+ cls->tp_bases = Py_BuildValue("(O)", base);
+ if (cls->tp_bases == NULL) {
+ return NULL;
+ }
+ }
+ if (PyType_Ready(cls) < 0) {
+ return NULL;
+ }
+ return (PyObject *)cls;
+}
+
+
// Test PyThreadState C API
static PyObject *
test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args))
@@ -3384,6 +3428,7 @@ static PyMethodDef TestMethods[] = {
{"type_assign_version", type_assign_version, METH_O, PyDoc_STR("PyUnstable_Type_AssignVersionTag")},
{"type_get_tp_bases", type_get_tp_bases, METH_O},
{"type_get_tp_mro", type_get_tp_mro, METH_O},
+ {"get_basic_static_type", get_basic_static_type, METH_VARARGS, NULL},
{"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL},
{"frame_getlocals", frame_getlocals, METH_O, NULL},
{"frame_getglobals", frame_getglobals, METH_O, NULL},