summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Objects/structseq.c
diff options
context:
space:
mode:
authorAlexSm <[email protected]>2024-02-16 11:51:30 +0100
committerGitHub <[email protected]>2024-02-16 11:51:30 +0100
commit506ecaee93b52cc12c2e2f97c3d42e3ca2a7f59e (patch)
treed096fb9eb988fbb0ca1ba970041773207ce3aa70 /contrib/tools/python3/src/Objects/structseq.c
parent4749b9e5d260714490997e6f5ee1ee8c1c8fc46c (diff)
parentf200f72c9d7a89c1018e3dc6b46c49fe2ecf84fb (diff)
Merge pull request #1940 from dcherednik/importlib
Library import 14
Diffstat (limited to 'contrib/tools/python3/src/Objects/structseq.c')
-rw-r--r--contrib/tools/python3/src/Objects/structseq.c195
1 files changed, 131 insertions, 64 deletions
diff --git a/contrib/tools/python3/src/Objects/structseq.c b/contrib/tools/python3/src/Objects/structseq.c
index 229e3d893ff..8b189595710 100644
--- a/contrib/tools/python3/src/Objects/structseq.c
+++ b/contrib/tools/python3/src/Objects/structseq.c
@@ -26,11 +26,12 @@ const char * const PyStructSequence_UnnamedField = "unnamed field";
static Py_ssize_t
get_type_attr_as_size(PyTypeObject *tp, PyObject *name)
{
- PyObject *v = PyDict_GetItemWithError(tp->tp_dict, name);
+ PyObject *v = PyDict_GetItemWithError(_PyType_GetDict(tp), name);
if (v == NULL && !PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError,
"Missed attribute '%U' of type %s",
name, tp->tp_name);
+ return -1;
}
return PyLong_AsSsize_t(v);
}
@@ -200,8 +201,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict)
}
for (i = 0; i < len; ++i) {
PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
- Py_INCREF(v);
- res->ob_item[i] = v;
+ res->ob_item[i] = Py_NewRef(v);
}
Py_DECREF(arg);
for (; i < max_len; ++i) {
@@ -219,8 +219,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict)
ob = Py_None;
}
}
- Py_INCREF(ob);
- res->ob_item[i] = ob;
+ res->ob_item[i] = Py_NewRef(ob);
}
_PyObject_GC_TRACK(res);
@@ -432,11 +431,19 @@ 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 n_members, Py_ssize_t n_unnamed_members)
+{
+ PyMemberDef *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 +460,15 @@ initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members,
k++;
}
members[k].name = NULL;
+
+ 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 +480,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);
+ desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) {
Py_DECREF(type);
return -1;
}
@@ -515,9 +502,92 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc,
}
int
+_PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp,
+ PyTypeObject *type,
+ PyStructSequence_Desc *desc,
+ unsigned long tp_flags)
+{
+ Py_ssize_t n_unnamed_members;
+ Py_ssize_t n_members = count_members(desc, &n_unnamed_members);
+ PyMemberDef *members = NULL;
+
+ if ((type->tp_flags & Py_TPFLAGS_READY) == 0) {
+ assert(type->tp_name == NULL);
+ assert(type->tp_members == NULL);
+ assert(type->tp_base == NULL);
+
+ members = initialize_members(desc, n_members, n_unnamed_members);
+ if (members == NULL) {
+ goto error;
+ }
+ initialize_static_fields(type, desc, members, tp_flags);
+
+ _Py_SetImmortal(type);
+ }
+#ifndef NDEBUG
+ else {
+ // Ensure that the type was initialized.
+ assert(type->tp_name != NULL);
+ assert(type->tp_members != NULL);
+ assert(type->tp_base == &PyTuple_Type);
+ assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
+ assert(_Py_IsImmortal(type));
+ }
+#endif
+
+ if (_PyStaticType_InitBuiltin(interp, type) < 0) {
+ PyErr_Format(PyExc_RuntimeError,
+ "Can't initialize builtin type %s",
+ desc->name);
+ goto error;
+ }
+
+ if (initialize_structseq_dict(
+ desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0)
+ {
+ goto error;
+ }
+
+ return 0;
+
+error:
+ if (members != NULL) {
+ PyMem_Free(members);
+ }
+ return -1;
+}
+
+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;
+ }
+
+ n_members = count_members(desc, &n_unnamed_members);
+ 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
@@ -527,35 +597,34 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
}
+/* This is exposed in the internal API, not the public API.
+ It is only called on builtin static types, which are all
+ initialized via _PyStructSequence_InitBuiltinWithFlags(). */
+
void
-_PyStructSequence_FiniType(PyTypeObject *type)
+_PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type)
{
// Ensure that the type is initialized
assert(type->tp_name != NULL);
assert(type->tp_base == &PyTuple_Type);
+ assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
+ assert(_Py_IsImmortal(type));
// Cannot delete a type if it still has subclasses
- if (type->tp_subclasses != NULL) {
+ if (_PyType_HasSubclasses(type)) {
+ // XXX Shouldn't this be an error?
return;
}
- // Undo PyStructSequence_NewType()
- type->tp_name = NULL;
- PyMem_Free(type->tp_members);
-
- _PyStaticType_Dealloc(type);
- assert(Py_REFCNT(type) == 1);
- // Undo Py_INCREF(type) of _PyStructSequence_InitType().
- // Don't use Py_DECREF(): static type must not be deallocated
- Py_SET_REFCNT(type, 0);
-#ifdef Py_REF_DEBUG
- _Py_RefTotal--;
-#endif
+ _PyStaticType_Dealloc(interp, type);
- // Make sure that _PyStructSequence_InitType() will initialize
- // the type again
- assert(Py_REFCNT(type) == 0);
- assert(type->tp_name == NULL);
+ if (_Py_IsMainInterpreter(interp)) {
+ // Undo _PyStructSequence_InitBuiltinWithFlags().
+ type->tp_name = NULL;
+ PyMem_Free(type->tp_members);
+ type->tp_members = NULL;
+ type->tp_base = NULL;
+ }
}
@@ -570,12 +639,10 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
/* 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};
@@ -603,7 +670,7 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
}
if (initialize_structseq_dict(
- desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
+ desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) {
Py_DECREF(type);
return NULL;
}