https://github.com/python/cpython/commit/2a28b21a517775120a7a720adc29cf85111e8bf4
commit: 2a28b21a517775120a7a720adc29cf85111e8bf4
branch: main
author: Eric Snow <ericsnowcurren...@gmail.com>
committer: ericsnowcurrently <ericsnowcurren...@gmail.com>
date: 2025-04-25T16:43:50Z
summary:

gh-132776: Revert Moving memoryview XIData Code to memoryobject.c (gh-132960)

This is a partial revert of gh-132821.  It resolves the refleak introduced by 
that PR.

files:
M Include/internal/pycore_interp_structs.h
M Include/internal/pycore_memoryobject.h
M Modules/_interpreters_common.h
M Modules/_interpretersmodule.c
M Objects/memoryobject.c
M Python/crossinterp.c
M Python/crossinterp_data_lookup.h
M Python/pylifecycle.c

diff --git a/Include/internal/pycore_interp_structs.h 
b/Include/internal/pycore_interp_structs.h
index 3c2b2d30028280..af6ee3ab48939f 100644
--- a/Include/internal/pycore_interp_structs.h
+++ b/Include/internal/pycore_interp_structs.h
@@ -9,7 +9,6 @@ extern "C" {
 
 #include "pycore_ast_state.h"     // struct ast_state
 #include "pycore_llist.h"         // struct llist_node
-#include "pycore_memoryobject.h"  // struct _memoryobject_state
 #include "pycore_opcode_utils.h"  // NUM_COMMON_CONSTANTS
 #include "pycore_pymath.h"        // _PY_SHORT_FLOAT_REPR
 #include "pycore_structs.h"       // PyHamtObject
@@ -913,10 +912,9 @@ struct _is {
     struct _dtoa_state dtoa;
     struct _py_func_state func_state;
     struct _py_code_state code_state;
+
     struct _Py_dict_state dict_state;
     struct _Py_exc_state exc_state;
-    struct _memoryobject_state memobj_state;
-
     struct _Py_mem_interp_free_queue mem_free_queue;
 
     struct ast_state ast;
diff --git a/Include/internal/pycore_memoryobject.h 
b/Include/internal/pycore_memoryobject.h
index 43e37330e1b07f..62e204fcbf6533 100644
--- a/Include/internal/pycore_memoryobject.h
+++ b/Include/internal/pycore_memoryobject.h
@@ -8,17 +8,6 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-struct _memoryobject_state {
-    PyTypeObject *XIBufferViewType;
-};
-
-extern PyStatus _PyMemoryView_InitTypes(PyInterpreterState *);
-extern void _PyMemoryView_FiniTypes(PyInterpreterState *);
-
-// exported for _interpreters module
-PyAPI_FUNC(PyTypeObject *) _PyMemoryView_GetXIBuffewViewType(void);
-
-
 extern PyTypeObject _PyManagedBuffer_Type;
 
 PyObject *
diff --git a/Modules/_interpreters_common.h b/Modules/_interpreters_common.h
index bc919485885294..a6c639feea5d14 100644
--- a/Modules/_interpreters_common.h
+++ b/Modules/_interpreters_common.h
@@ -5,7 +5,6 @@
     _RESOLVE_MODINIT_FUNC_NAME(NAME)
 
 
-#ifdef REGISTERS_HEAP_TYPES
 static int
 ensure_xid_class(PyTypeObject *cls, xidatafunc getdata)
 {
@@ -17,6 +16,7 @@ ensure_xid_class(PyTypeObject *cls, xidatafunc getdata)
     return _PyXIData_RegisterClass(&ctx, cls, getdata);
 }
 
+#ifdef REGISTERS_HEAP_TYPES
 static int
 clear_xid_class(PyTypeObject *cls)
 {
diff --git a/Modules/_interpretersmodule.c b/Modules/_interpretersmodule.c
index f636ce882c3023..e59a53feb09df8 100644
--- a/Modules/_interpretersmodule.c
+++ b/Modules/_interpretersmodule.c
@@ -9,7 +9,6 @@
 #include "pycore_code.h"          // _PyCode_HAS_EXECUTORS()
 #include "pycore_crossinterp.h"   // _PyXIData_t
 #include "pycore_interp.h"        // _PyInterpreterState_IDIncref()
-#include "pycore_memoryobject.h"  // _PyMemoryView_GetXIBuffewViewType()
 #include "pycore_modsupport.h"    // _PyArg_BadArgument()
 #include "pycore_namespace.h"     // _PyNamespace_New()
 #include "pycore_pybuffer.h"      // _PyBuffer_ReleaseInInterpreterAndRawFree()
@@ -37,6 +36,23 @@ _get_current_interp(void)
 #define look_up_interp _PyInterpreterState_LookUpIDObject
 
 
+static PyObject *
+_get_current_module(void)
+{
+    PyObject *name = PyUnicode_FromString(MODULE_NAME_STR);
+    if (name == NULL) {
+        return NULL;
+    }
+    PyObject *mod = PyImport_GetModule(name);
+    Py_DECREF(name);
+    if (mod == NULL) {
+        return NULL;
+    }
+    assert(mod != Py_None);
+    return mod;
+}
+
+
 static int
 is_running_main(PyInterpreterState *interp)
 {
@@ -55,10 +71,238 @@ is_running_main(PyInterpreterState *interp)
 }
 
 
+/* Cross-interpreter Buffer Views *******************************************/
+
+/* When a memoryview object is "shared" between interpreters,
+ * its underlying "buffer" memory is actually shared, rather than just
+ * copied.  This facilitates efficient use of that data where otherwise
+ * interpreters are strictly isolated.  However, this also means that
+ * the underlying data is subject to the complexities of thread-safety,
+ * which the user must manage carefully.
+ *
+ * When the memoryview is "shared", it is essentially copied in the same
+ * way as PyMemory_FromObject() does, but in another interpreter.
+ * The Py_buffer value is copied like normal, including the "buf" pointer,
+ * with one key exception.
+ *
+ * When a Py_buffer is released and it holds a reference to an object,
+ * that object gets a chance to call its bf_releasebuffer() (if any)
+ * before the object is decref'ed.  The same is true with the memoryview
+ * tp_dealloc, which essentially calls PyBuffer_Release().
+ *
+ * The problem for a Py_buffer shared between two interpreters is that
+ * the naive approach breaks interpreter isolation.  Operations on an
+ * object must only happen while that object's interpreter is active.
+ * If the copied mv->view.obj pointed to the original memoryview then
+ * the PyBuffer_Release() would happen under the wrong interpreter.
+ *
+ * To work around this, we set mv->view.obj on the copied memoryview
+ * to a wrapper object with the only job of releasing the original
+ * buffer in a cross-interpreter-safe way.
+ */
+
+// XXX Note that there is still an issue to sort out, where the original
+// interpreter is destroyed but code in another interpreter is still
+// using dependent buffers.  Using such buffers segfaults.  This will
+// require a careful fix.  In the meantime, users will have to be
+// diligent about avoiding the problematic situation.
+
+typedef struct {
+    PyObject base;
+    Py_buffer *view;
+    int64_t interpid;
+} xibufferview;
+
+static PyObject *
+xibufferview_from_buffer(PyTypeObject *cls, Py_buffer *view, int64_t interpid)
+{
+    assert(interpid >= 0);
+
+    Py_buffer *copied = PyMem_RawMalloc(sizeof(Py_buffer));
+    if (copied == NULL) {
+        return NULL;
+    }
+    /* This steals the view->obj reference  */
+    *copied = *view;
+
+    xibufferview *self = PyObject_Malloc(sizeof(xibufferview));
+    if (self == NULL) {
+        PyMem_RawFree(copied);
+        return NULL;
+    }
+    PyObject_Init(&self->base, cls);
+    *self = (xibufferview){
+        .base = self->base,
+        .view = copied,
+        .interpid = interpid,
+    };
+    return (PyObject *)self;
+}
+
+static void
+xibufferview_dealloc(PyObject *op)
+{
+    xibufferview *self = (xibufferview *)op;
+    if (self->view != NULL) {
+        PyInterpreterState *interp =
+                        _PyInterpreterState_LookUpID(self->interpid);
+        if (interp == NULL) {
+            /* The interpreter is no longer alive. */
+            PyErr_Clear();
+            PyMem_RawFree(self->view);
+        }
+        else {
+            if (_PyBuffer_ReleaseInInterpreterAndRawFree(interp,
+                                                         self->view) < 0)
+            {
+                // XXX Emit a warning?
+                PyErr_Clear();
+            }
+        }
+    }
+
+    PyTypeObject *tp = Py_TYPE(self);
+    tp->tp_free(self);
+    /* "Instances of heap-allocated types hold a reference to their type."
+     * See: 
https://docs.python.org/3.11/howto/isolating-extensions.html#garbage-collection-protocol
+     * See: 
https://docs.python.org/3.11/c-api/typeobj.html#c.PyTypeObject.tp_traverse
+    */
+    // XXX Why don't we implement Py_TPFLAGS_HAVE_GC, e.g. Py_tp_traverse,
+    // like we do for _abc._abc_data?
+    Py_DECREF(tp);
+}
+
+static int
+xibufferview_getbuf(PyObject *op, Py_buffer *view, int flags)
+{
+    /* Only PyMemoryView_FromObject() should ever call this,
+       via _memoryview_from_xid() below. */
+    xibufferview *self = (xibufferview *)op;
+    *view = *self->view;
+    /* This is the workaround mentioned earlier. */
+    view->obj = op;
+    // XXX Should we leave it alone?
+    view->internal = NULL;
+    return 0;
+}
+
+static PyType_Slot XIBufferViewType_slots[] = {
+    {Py_tp_dealloc, xibufferview_dealloc},
+    {Py_bf_getbuffer, xibufferview_getbuf},
+    // We don't bother with Py_bf_releasebuffer since we don't need it.
+    {0, NULL},
+};
+
+static PyType_Spec XIBufferViewType_spec = {
+    .name = MODULE_NAME_STR ".CrossInterpreterBufferView",
+    .basicsize = sizeof(xibufferview),
+    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+              Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE),
+    .slots = XIBufferViewType_slots,
+};
+
+
+static PyTypeObject * _get_current_xibufferview_type(void);
+
+
+struct xibuffer {
+    Py_buffer view;
+    int used;
+};
+
+static PyObject *
+_memoryview_from_xid(_PyXIData_t *data)
+{
+    assert(_PyXIData_DATA(data) != NULL);
+    assert(_PyXIData_OBJ(data) == NULL);
+    assert(_PyXIData_INTERPID(data) >= 0);
+    struct xibuffer *view = (struct xibuffer *)_PyXIData_DATA(data);
+    assert(!view->used);
+
+    PyTypeObject *cls = _get_current_xibufferview_type();
+    if (cls == NULL) {
+        return NULL;
+    }
+
+    PyObject *obj = xibufferview_from_buffer(
+                        cls, &view->view, _PyXIData_INTERPID(data));
+    if (obj == NULL) {
+        return NULL;
+    }
+    PyObject *res = PyMemoryView_FromObject(obj);
+    if (res == NULL) {
+        Py_DECREF(obj);
+        return NULL;
+    }
+    view->used = 1;
+    return res;
+}
+
+static void
+_pybuffer_shared_free(void* data)
+{
+    struct xibuffer *view = (struct xibuffer *)data;
+    if (!view->used) {
+        PyBuffer_Release(&view->view);
+    }
+    PyMem_RawFree(data);
+}
+
+static int
+_pybuffer_shared(PyThreadState *tstate, PyObject *obj, _PyXIData_t *data)
+{
+    struct xibuffer *view = PyMem_RawMalloc(sizeof(struct xibuffer));
+    if (view == NULL) {
+        return -1;
+    }
+    view->used = 0;
+    /* This will increment the memoryview's export count, which won't get
+     * decremented until the view sent to other interpreters is released. */
+    if (PyObject_GetBuffer(obj, &view->view, PyBUF_FULL_RO) < 0) {
+        PyMem_RawFree(view);
+        return -1;
+    }
+    /* The view holds a reference to the object, so we don't worry
+     * about also tracking it on the cross-interpreter data. */
+    _PyXIData_Init(data, tstate->interp, view, NULL, _memoryview_from_xid);
+    data->free = _pybuffer_shared_free;
+    return 0;
+}
+
+static int
+register_memoryview_xid(PyObject *mod, PyTypeObject **p_state)
+{
+    // XIBufferView
+    assert(*p_state == NULL);
+    PyTypeObject *cls = (PyTypeObject *)PyType_FromModuleAndSpec(
+                mod, &XIBufferViewType_spec, NULL);
+    if (cls == NULL) {
+        return -1;
+    }
+    if (PyModule_AddType(mod, cls) < 0) {
+        Py_DECREF(cls);
+        return -1;
+    }
+    *p_state = cls;
+
+    // Register XID for the builtin memoryview type.
+    if (ensure_xid_class(&PyMemoryView_Type, _pybuffer_shared) < 0) {
+        return -1;
+    }
+    // We don't ever bother un-registering memoryview.
+
+    return 0;
+}
+
+
+
 /* module state *************************************************************/
 
 typedef struct {
     int _notused;
+
+    /* heap types */
+    PyTypeObject *XIBufferViewType;
 } module_state;
 
 static inline module_state *
@@ -70,19 +314,51 @@ get_module_state(PyObject *mod)
     return state;
 }
 
+static module_state *
+_get_current_module_state(void)
+{
+    PyObject *mod = _get_current_module();
+    if (mod == NULL) {
+        // XXX import it?
+        PyErr_SetString(PyExc_RuntimeError,
+                        MODULE_NAME_STR " module not imported yet");
+        return NULL;
+    }
+    module_state *state = get_module_state(mod);
+    Py_DECREF(mod);
+    return state;
+}
+
 static int
 traverse_module_state(module_state *state, visitproc visit, void *arg)
 {
+    /* heap types */
+    Py_VISIT(state->XIBufferViewType);
+
     return 0;
 }
 
 static int
 clear_module_state(module_state *state)
 {
+    /* heap types */
+    Py_CLEAR(state->XIBufferViewType);
+
     return 0;
 }
 
 
+static PyTypeObject *
+_get_current_xibufferview_type(void)
+{
+    module_state *state = _get_current_module_state();
+    if (state == NULL) {
+        return NULL;
+    }
+    return state->XIBufferViewType;
+}
+
+
 /* Python code **************************************************************/
 
 static const char *
@@ -1303,7 +1579,6 @@ module_exec(PyObject *mod)
 {
     PyInterpreterState *interp = PyInterpreterState_Get();
     module_state *state = get_module_state(mod);
-    (void)state;
 
     _PyXIData_lookup_context_t ctx;
     if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
@@ -1335,14 +1610,9 @@ module_exec(PyObject *mod)
         goto error;
     }
 
-    PyTypeObject *XIBufferViewType = _PyMemoryView_GetXIBuffewViewType();
-    if (XIBufferViewType == NULL) {
+    if (register_memoryview_xid(mod, &state->XIBufferViewType) < 0) {
         goto error;
     }
-    if (PyModule_AddType(mod, XIBufferViewType) < 0) {
-        Py_DECREF(XIBufferViewType);
-        return -1;
-    }
 
     return 0;
 
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
index 9098c27c564d78..cf673fb379edcd 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -12,11 +12,8 @@
 
 #include "Python.h"
 #include "pycore_abstract.h"      // _PyIndex_Check()
-#include "pycore_initconfig.h"    // _PyStatus_OK()
-#include "pycore_interp.h"        // _PyInterpreterState_LookUpID()
 #include "pycore_memoryobject.h"  // _PyManagedBuffer_Type
 #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
-#include "pycore_pybuffer.h"      // _PyBuffer_ReleaseInInterpreterAndRawFree()
 #include "pycore_strhex.h"        // _Py_strhex_with_sep()
 #include <stddef.h>               // offsetof()
 
@@ -3559,252 +3556,6 @@ PyTypeObject _PyMemoryIter_Type = {
     .tp_iternext = memoryiter_next,
 };
 
-
-/**************************************************************************/
-/*                   Memoryview Cross-interpreter Data                    */
-/**************************************************************************/
-
-/* When a memoryview object is "shared" between interpreters,
- * its underlying "buffer" memory is actually shared, rather than just
- * copied.  This facilitates efficient use of that data where otherwise
- * interpreters are strictly isolated.  However, this also means that
- * the underlying data is subject to the complexities of thread-safety,
- * which the user must manage carefully.
- *
- * When the memoryview is "shared", it is essentially copied in the same
- * way as PyMemory_FromObject() does, but in another interpreter.
- * The Py_buffer value is copied like normal, including the "buf" pointer,
- * with one key exception.
- *
- * When a Py_buffer is released and it holds a reference to an object,
- * that object gets a chance to call its bf_releasebuffer() (if any)
- * before the object is decref'ed.  The same is true with the memoryview
- * tp_dealloc, which essentially calls PyBuffer_Release().
- *
- * The problem for a Py_buffer shared between two interpreters is that
- * the naive approach breaks interpreter isolation.  Operations on an
- * object must only happen while that object's interpreter is active.
- * If the copied mv->view.obj pointed to the original memoryview then
- * the PyBuffer_Release() would happen under the wrong interpreter.
- *
- * To work around this, we set mv->view.obj on the copied memoryview
- * to a wrapper object with the only job of releasing the original
- * buffer in a cross-interpreter-safe way.
- */
-
-// XXX Note that there is still an issue to sort out, where the original
-// interpreter is destroyed but code in another interpreter is still
-// using dependent buffers.  Using such buffers segfaults.  This will
-// require a careful fix.  In the meantime, users will have to be
-// diligent about avoiding the problematic situation.
-
-typedef struct {
-    PyObject base;
-    Py_buffer *view;
-    int64_t interpid;
-} xibufferview;
-
-static PyObject *
-xibufferview_from_buffer(PyTypeObject *cls, Py_buffer *view, int64_t interpid)
-{
-    assert(interpid >= 0);
-
-    Py_buffer *copied = PyMem_RawMalloc(sizeof(Py_buffer));
-    if (copied == NULL) {
-        return NULL;
-    }
-    /* This steals the view->obj reference  */
-    *copied = *view;
-
-    xibufferview *self = PyObject_Malloc(sizeof(xibufferview));
-    if (self == NULL) {
-        PyMem_RawFree(copied);
-        return NULL;
-    }
-    *self = (xibufferview){
-        .view = copied,
-        .interpid = interpid,
-    };
-    PyObject_Init(&self->base, cls);
-    return (PyObject *)self;
-}
-
-static void
-xibufferview_dealloc(PyObject *op)
-{
-    xibufferview *self = (xibufferview *)op;
-
-    if (self->view != NULL) {
-        PyInterpreterState *interp =
-                        _PyInterpreterState_LookUpID(self->interpid);
-        if (interp == NULL) {
-            /* The interpreter is no longer alive. */
-            PyErr_Clear();
-            PyMem_RawFree(self->view);
-        }
-        else {
-            if (_PyBuffer_ReleaseInInterpreterAndRawFree(interp,
-                                                         self->view) < 0)
-            {
-                // XXX Emit a warning?
-                PyErr_Clear();
-            }
-        }
-    }
-
-    PyTypeObject *tp = Py_TYPE(self);
-    tp->tp_free(self);
-    /* "Instances of heap-allocated types hold a reference to their type."
-     * See: 
https://docs.python.org/3.11/howto/isolating-extensions.html#garbage-collection-protocol
-     * See: 
https://docs.python.org/3.11/c-api/typeobj.html#c.PyTypeObject.tp_traverse
-    */
-    // XXX Why don't we implement Py_TPFLAGS_HAVE_GC, e.g. Py_tp_traverse,
-    // like we do for _abc._abc_data?
-    Py_DECREF(tp);
-}
-
-static int
-xibufferview_getbuf(PyObject *op, Py_buffer *view, int flags)
-{
-    /* Only PyMemoryView_FromObject() should ever call this,
-       via _memoryview_from_xid() below. */
-    xibufferview *self = (xibufferview *)op;
-    *view = *self->view;
-    /* This is the workaround mentioned earlier. */
-    view->obj = op;
-    // XXX Should we leave it alone?
-    view->internal = NULL;
-    return 0;
-}
-
-static PyType_Slot XIBufferViewType_slots[] = {
-    {Py_tp_dealloc, xibufferview_dealloc},
-    {Py_bf_getbuffer, xibufferview_getbuf},
-    // We don't bother with Py_bf_releasebuffer since we don't need it.
-    {0, NULL},
-};
-
-static PyType_Spec XIBufferViewType_spec = {
-    .name = "_interpreters.CrossInterpreterBufferView",
-    .basicsize = sizeof(xibufferview),
-    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
-              Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE),
-    .slots = XIBufferViewType_slots,
-};
-
-PyTypeObject *
-_PyMemoryView_GetXIBuffewViewType(void)
-{
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    PyTypeObject *cls = interp->memobj_state.XIBufferViewType;
-    if (cls == NULL) {
-        cls = (PyTypeObject *)PyType_FromSpec(&XIBufferViewType_spec);
-        if (cls == NULL) {
-            return NULL;
-        }
-        /* It gets cleaned up during interpreter finalization
-         * in clear_xidata_state(). */
-        interp->memobj_state.XIBufferViewType = cls;
-    }
-    Py_INCREF(cls);
-    return cls;
-}
-
-
-struct xibuffer {
-    Py_buffer view;
-    int used;
-};
-
-static PyObject *
-_memoryview_from_xid(_PyXIData_t *data)
-{
-    assert(_PyXIData_DATA(data) != NULL);
-    assert(_PyXIData_OBJ(data) == NULL);
-    assert(_PyXIData_INTERPID(data) >= 0);
-    struct xibuffer *view = (struct xibuffer *)_PyXIData_DATA(data);
-    assert(!view->used);
-
-    PyTypeObject *cls = _PyMemoryView_GetXIBuffewViewType();
-    if (cls == NULL) {
-        return NULL;
-    }
-
-    PyObject *obj = xibufferview_from_buffer(
-                        cls, &view->view, _PyXIData_INTERPID(data));
-    if (obj == NULL) {
-        return NULL;
-    }
-    PyObject *res = PyMemoryView_FromObject(obj);
-    if (res == NULL) {
-        Py_DECREF(obj);
-        return NULL;
-    }
-    view->used = 1;
-    return res;
-}
-
-static void
-_pybuffer_shared_free(void* data)
-{
-    struct xibuffer *view = (struct xibuffer *)data;
-    if (!view->used) {
-        PyBuffer_Release(&view->view);
-    }
-    PyMem_RawFree(data);
-}
-
-static int
-_pybuffer_shared(PyThreadState *tstate, PyObject *obj, _PyXIData_t *data)
-{
-    struct xibuffer *view = PyMem_RawMalloc(sizeof(struct xibuffer));
-    if (view == NULL) {
-        return -1;
-    }
-    view->used = 0;
-    /* This will increment the memoryview's export count, which won't get
-     * decremented until the view sent to other interpreters is released. */
-    if (PyObject_GetBuffer(obj, &view->view, PyBUF_FULL_RO) < 0) {
-        PyMem_RawFree(view);
-        return -1;
-    }
-    /* The view holds a reference to the object, so we don't worry
-     * about also tracking it on the cross-interpreter data. */
-    _PyXIData_Init(data, tstate->interp, view, NULL, _memoryview_from_xid);
-    data->free = _pybuffer_shared_free;
-    return 0;
-}
-
-
-static int
-init_xidata_types(PyInterpreterState *interp)
-{
-    /* Register an XI data handler for memoryview. */
-    // This is necessary only as long as we don't have a tp_ slot for it.
-    _PyXIData_lookup_context_t ctx;
-    if (_PyXIData_GetLookupContext(interp, &ctx) < 0) {
-        return -1;
-    }
-    if (_PyXIData_RegisterClass(&ctx, &PyMemoryView_Type, _pybuffer_shared) < 
0) {
-        return -1;
-    }
-
-    return 0;
-}
-
-static void
-clear_xidata_types(PyInterpreterState *interp)
-{
-    if (interp->memobj_state.XIBufferViewType != NULL) {
-        Py_CLEAR(interp->memobj_state.XIBufferViewType);
-    }
-}
-
-
-/**************************************************************************/
-/*                            Memoryview Type                             */
-/**************************************************************************/
-
 PyTypeObject PyMemoryView_Type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "memoryview",                             /* tp_name */
@@ -3846,27 +3597,3 @@ PyTypeObject PyMemoryView_Type = {
     0,                                        /* tp_alloc */
     memoryview,                               /* tp_new */
 };
-
-
-/**************************************************************************/
-/*                           Runtime Lifecycle                            */
-/**************************************************************************/
-
-PyStatus
-_PyMemoryView_InitTypes(PyInterpreterState *interp)
-{
-    /* interp->memobj_state.XIBufferViewType is initialized lazily
-     * in _PyMemoryView_GetXIBuffewViewType(). */
-
-    if (init_xidata_types(interp) < 0) {
-        return _PyStatus_ERR("failed to initialize cross-interpreter data 
types");
-    }
-
-    return _PyStatus_OK();
-}
-
-void
-_PyMemoryView_FiniTypes(PyInterpreterState *interp)
-{
-    clear_xidata_types(interp);
-}
diff --git a/Python/crossinterp.c b/Python/crossinterp.c
index 7a19cc3da1f3f8..094bbbe54f2a75 100644
--- a/Python/crossinterp.c
+++ b/Python/crossinterp.c
@@ -1902,25 +1902,7 @@ _PyXI_Fini(PyInterpreterState *interp)
 PyStatus
 _PyXI_InitTypes(PyInterpreterState *interp)
 {
-    if (_Py_IsMainInterpreter(interp)) {
-        _PyXI_global_state_t *global_state = _PyXI_GET_GLOBAL_STATE(interp);
-        if (global_state == NULL) {
-            PyErr_PrintEx(0);
-            return _PyStatus_ERR(
-                    "failed to get global cross-interpreter state");
-        }
-        xid_lookup_init(&global_state->data_lookup);
-    }
-
-    _PyXI_state_t *state = _PyXI_GET_STATE(interp);
-    if (state == NULL) {
-        PyErr_PrintEx(0);
-        return _PyStatus_ERR(
-                "failed to get interpreter's cross-interpreter state");
-    }
-    xid_lookup_init(&state->data_lookup);
-
-    if (init_static_exctypes(&state->exceptions, interp) < 0) {
+    if (init_static_exctypes(&_PyXI_GET_STATE(interp)->exceptions, interp) < 
0) {
         PyErr_PrintEx(0);
         return _PyStatus_ERR(
                 "failed to initialize the cross-interpreter exception types");
@@ -1933,21 +1915,9 @@ _PyXI_InitTypes(PyInterpreterState *interp)
 void
 _PyXI_FiniTypes(PyInterpreterState *interp)
 {
-    _PyXI_state_t *state = _PyXI_GET_STATE(interp);
-    if (state != NULL) {
-        // We would finalize heap types here too but that leads to ref leaks.
-        // Instead, we finalize them in _PyXI_Fini().
-        fini_static_exctypes(&state->exceptions, interp);
-
-        xid_lookup_fini(&state->data_lookup);
-    }
-
-    if (_Py_IsMainInterpreter(interp)) {
-        _PyXI_global_state_t *global_state = _PyXI_GET_GLOBAL_STATE(interp);
-        if (global_state != NULL) {
-            xid_lookup_fini(&global_state->data_lookup);
-        }
-    }
+    // We would finalize heap types here too but that leads to ref leaks.
+    // Instead, we finalize them in _PyXI_Fini().
+    fini_static_exctypes(&_PyXI_GET_STATE(interp)->exceptions, interp);
 }
 
 
diff --git a/Python/crossinterp_data_lookup.h b/Python/crossinterp_data_lookup.h
index 6e75e2475280cf..48e5d9762cd697 100644
--- a/Python/crossinterp_data_lookup.h
+++ b/Python/crossinterp_data_lookup.h
@@ -174,7 +174,6 @@ _lookup_getdata_from_registry(dlcontext_t *ctx, PyObject 
*obj)
     PyTypeObject *cls = Py_TYPE(obj);
 
     dlregistry_t *xidregistry = _get_xidregistry_for_type(ctx, cls);
-    assert(xidregistry->initialized);
     _xidregistry_lock(xidregistry);
 
     dlregitem_t *matched = _xidregistry_find_type(xidregistry, cls);
@@ -191,7 +190,6 @@ static int
 _xidregistry_add_type(dlregistry_t *xidregistry,
                       PyTypeObject *cls, xidatafunc getdata)
 {
-    assert(xidregistry->initialized);
     dlregitem_t *newhead = PyMem_RawMalloc(sizeof(dlregitem_t));
     if (newhead == NULL) {
         return -1;
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 4c25198b702c57..1b9832bff17ba5 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -14,7 +14,6 @@
 #include "pycore_global_objects_fini_generated.h"  // 
_PyStaticObjects_CheckRefcnt()
 #include "pycore_initconfig.h"    // _PyStatus_OK()
 #include "pycore_long.h"          // _PyLong_InitTypes()
-#include "pycore_memoryobject.h"  // _PyMemoryView_InitTypes()
 #include "pycore_object.h"        // _PyDebug_PrintTotalRefs()
 #include "pycore_obmalloc.h"      // _PyMem_init_obmalloc()
 #include "pycore_optimizer.h"     // _Py_Executors_InvalidateAll
@@ -755,11 +754,6 @@ pycore_init_types(PyInterpreterState *interp)
         return status;
     }
 
-    status = _PyMemoryView_InitTypes(interp);
-    if (_PyStatus_EXCEPTION(status)) {
-        return status;
-    }
-
     return _PyStatus_OK();
 }
 
@@ -1851,7 +1845,6 @@ finalize_interp_types(PyInterpreterState *interp)
     _PyTypes_FiniExtTypes(interp);
     _PyUnicode_FiniTypes(interp);
     _PySys_FiniTypes(interp);
-    _PyMemoryView_FiniTypes(interp);
     _PyXI_FiniTypes(interp);
     _PyExc_Fini(interp);
     _PyFloat_FiniType(interp);

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to