summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2022-07-25 18:47:31 (GMT)
committerGitHub <noreply@github.com>2022-07-25 18:47:31 (GMT)
commit4a1dd734311891662a6fc3394f93db98c93e7219 (patch)
tree2f85a419478553aeedd1622cb53dd5b302f77785 /Objects
parentc5140945c723ae6c4b7ee81ff720ac8ea4b52cfd (diff)
downloadcpython-4a1dd734311891662a6fc3394f93db98c93e7219.zip
cpython-4a1dd734311891662a6fc3394f93db98c93e7219.tar.gz
cpython-4a1dd734311891662a6fc3394f93db98c93e7219.tar.bz2
gh-94673: Add _PyStaticType_InitBuiltin() (#95152)
This is the first of several precursors to storing tp_subclasses (and tp_weaklist) on the interpreter state for static builtin types. We do the following: * add `_PyStaticType_InitBuiltin()` * add `_Py_TPFLAGS_STATIC_BUILTIN` * set it on all static builtin types in `_PyStaticType_InitBuiltin()` * shuffle some code around to be able to use _PyStaticType_InitBuiltin() * rename `_PyStructSequence_InitType()` to `_PyStructSequence_InitBuiltinWithFlags()` * add `_PyStructSequence_InitBuiltin()`.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/exceptions.c3
-rw-r--r--Objects/floatobject.c3
-rw-r--r--Objects/longobject.c2
-rw-r--r--Objects/object.c4
-rw-r--r--Objects/structseq.c122
-rw-r--r--Objects/typeobject.c8
-rw-r--r--Objects/unicodeobject.c6
7 files changed, 99 insertions, 49 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 9aab683..e06a8f4 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -3556,8 +3556,7 @@ _PyExc_InitTypes(PyInterpreterState *interp)
for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
PyTypeObject *exc = static_exceptions[i].exc;
-
- if (PyType_Ready(exc) < 0) {
+ if (_PyStaticType_InitBuiltin(exc) < 0) {
return -1;
}
}
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 47d308b..4b1b24f 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -1992,7 +1992,8 @@ _PyFloat_InitTypes(PyInterpreterState *interp)
/* Init float info */
if (FloatInfoType.tp_name == NULL) {
- if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) {
+ if (_PyStructSequence_InitBuiltin(&FloatInfoType,
+ &floatinfo_desc) < 0) {
return _PyStatus_ERR("can't init float info type");
}
}
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 4a1e5ca..90ed02b 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -6135,7 +6135,7 @@ _PyLong_InitTypes(PyInterpreterState *interp)
/* initialize int_info */
if (Int_InfoType.tp_name == NULL) {
- if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) {
+ if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) {
return _PyStatus_ERR("can't init int info type");
}
}
diff --git a/Objects/object.c b/Objects/object.c
index 75aee90..758b79e 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1975,8 +1975,8 @@ _PyTypes_InitTypes(PyInterpreterState *interp)
// All other static types (unless initialized elsewhere)
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
PyTypeObject *type = static_types[i];
- if (PyType_Ready(type) < 0) {
- return _PyStatus_ERR("Can't initialize types");
+ if (_PyStaticType_InitBuiltin(type) < 0) {
+ return _PyStatus_ERR("Can't initialize builtin type");
}
if (type == &PyType_Type) {
// Sanitify checks of the two most important types
diff --git a/Objects/structseq.c b/Objects/structseq.c
index 229e3d8..24cd0e7 100644
--- a/Objects/structseq.c
+++ b/Objects/structseq.c
@@ -432,11 +432,21 @@ error:
return -1;
}
-static void
-initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members,
- Py_ssize_t n_members) {
- Py_ssize_t i, k;
+static PyMemberDef *
+initialize_members(PyStructSequence_Desc *desc,
+ Py_ssize_t *pn_members, Py_ssize_t *pn_unnamed_members)
+{
+ PyMemberDef *members;
+ Py_ssize_t n_members, n_unnamed_members;
+
+ n_members = count_members(desc, &n_unnamed_members);
+ members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1);
+ if (members == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ Py_ssize_t i, k;
for (i = k = 0; i < n_members; ++i) {
if (desc->fields[i].name == PyStructSequence_UnnamedField) {
continue;
@@ -453,30 +463,17 @@ initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members,
k++;
}
members[k].name = NULL;
+
+ *pn_members = n_members;
+ *pn_unnamed_members = n_unnamed_members;
+ return members;
}
-int
-_PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc,
- unsigned long tp_flags)
+static void
+initialize_static_fields(PyTypeObject *type, PyStructSequence_Desc *desc,
+ PyMemberDef *tp_members, unsigned long tp_flags)
{
- PyMemberDef *members;
- Py_ssize_t n_members, n_unnamed_members;
-
-#ifdef Py_TRACE_REFS
- /* if the type object was chained, unchain it first
- before overwriting its storage */
- if (type->ob_base.ob_base._ob_next) {
- _Py_ForgetReference((PyObject *)type);
- }
-#endif
-
- /* PyTypeObject has already been initialized */
- if (Py_REFCNT(type) != 0) {
- PyErr_BadInternalCall();
- return -1;
- }
-
type->tp_name = desc->name;
type->tp_basicsize = sizeof(PyStructSequence) - sizeof(PyObject *);
type->tp_itemsize = sizeof(PyObject *);
@@ -488,25 +485,20 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc,
type->tp_new = structseq_new;
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags;
type->tp_traverse = (traverseproc) structseq_traverse;
+ type->tp_members = tp_members;
+}
- n_members = count_members(desc, &n_unnamed_members);
- members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1);
- if (members == NULL) {
- PyErr_NoMemory();
- return -1;
- }
- initialize_members(desc, members, n_members);
- type->tp_members = members;
-
+static int
+initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc,
+ Py_ssize_t n_members, Py_ssize_t n_unnamed_members) {
+ /* initialize_static_fields() should have been called already. */
if (PyType_Ready(type) < 0) {
- PyMem_Free(members);
return -1;
}
Py_INCREF(type);
if (initialize_structseq_dict(
desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
- PyMem_Free(members);
Py_DECREF(type);
return -1;
}
@@ -515,9 +507,62 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc,
}
int
+_PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
+ PyStructSequence_Desc *desc,
+ unsigned long tp_flags)
+{
+ PyMemberDef *members;
+ Py_ssize_t n_members, n_unnamed_members;
+
+ members = initialize_members(desc, &n_members, &n_unnamed_members);
+ if (members == NULL) {
+ return -1;
+ }
+ initialize_static_fields(type, desc, members, tp_flags);
+ if (_PyStaticType_InitBuiltin(type) < 0) {
+ PyMem_Free(members);
+ PyErr_Format(PyExc_RuntimeError,
+ "Can't initialize builtin type %s",
+ desc->name);
+ return -1;
+ }
+ if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) {
+ PyMem_Free(members);
+ return -1;
+ }
+ return 0;
+}
+
+int
PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc)
{
- return _PyStructSequence_InitType(type, desc, 0);
+ PyMemberDef *members;
+ Py_ssize_t n_members, n_unnamed_members;
+
+#ifdef Py_TRACE_REFS
+ /* if the type object was chained, unchain it first
+ before overwriting its storage */
+ if (type->ob_base.ob_base._ob_next) {
+ _Py_ForgetReference((PyObject *)type);
+ }
+#endif
+
+ /* PyTypeObject has already been initialized */
+ if (Py_REFCNT(type) != 0) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ members = initialize_members(desc, &n_members, &n_unnamed_members);
+ if (members == NULL) {
+ return -1;
+ }
+ initialize_static_fields(type, desc, members, 0);
+ if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) {
+ PyMem_Free(members);
+ return -1;
+ }
+ return 0;
}
void
@@ -569,13 +614,10 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
Py_ssize_t n_members, n_unnamed_members;
/* Initialize MemberDefs */
- n_members = count_members(desc, &n_unnamed_members);
- members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1);
+ members = initialize_members(desc, &n_members, &n_unnamed_members);
if (members == NULL) {
- PyErr_NoMemory();
return NULL;
}
- initialize_members(desc, members, n_members);
/* Initialize Slots */
slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc};
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 5ebff60..8510196 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -6650,6 +6650,14 @@ PyType_Ready(PyTypeObject *type)
return 0;
}
+int
+_PyStaticType_InitBuiltin(PyTypeObject *self)
+{
+ self->tp_flags = self->tp_flags | _Py_TPFLAGS_STATIC_BUILTIN;
+
+ return PyType_Ready(self);
+}
+
static int
add_subclass(PyTypeObject *base, PyTypeObject *type)
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 669ffe7..7e3caf1 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -14604,13 +14604,13 @@ _PyUnicode_InitTypes(PyInterpreterState *interp)
return _PyStatus_OK();
}
- if (PyType_Ready(&EncodingMapType) < 0) {
+ if (_PyStaticType_InitBuiltin(&EncodingMapType) < 0) {
goto error;
}
- if (PyType_Ready(&PyFieldNameIter_Type) < 0) {
+ if (_PyStaticType_InitBuiltin(&PyFieldNameIter_Type) < 0) {
goto error;
}
- if (PyType_Ready(&PyFormatterIter_Type) < 0) {
+ if (_PyStaticType_InitBuiltin(&PyFormatterIter_Type) < 0) {
goto error;
}
return _PyStatus_OK();