]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46008: Make runtime-global object/type lifecycle functions and state consistent...
authorEric Snow <ericsnowcurrently@gmail.com>
Thu, 9 Dec 2021 19:59:26 +0000 (12:59 -0700)
committerGitHub <noreply@github.com>
Thu, 9 Dec 2021 19:59:26 +0000 (12:59 -0700)
This change is strictly renames and moving code around.  It helps in the following ways:

* ensures type-related init functions focus strictly on one of the three aspects (state, objects, types)
* passes in PyInterpreterState * to all those functions, simplifying work on moving types/objects/state to the interpreter
* consistent naming conventions help make what's going on more clear
* keeping API related to a type in the corresponding header file makes it more obvious where to look for it

https://bugs.python.org/issue46008

38 files changed:
Include/internal/pycore_bytesobject.h [new file with mode: 0644]
Include/internal/pycore_context.h
Include/internal/pycore_dict.h
Include/internal/pycore_exceptions.h [new file with mode: 0644]
Include/internal/pycore_floatobject.h
Include/internal/pycore_frame.h
Include/internal/pycore_genobject.h [new file with mode: 0644]
Include/internal/pycore_hamt.h
Include/internal/pycore_interp.h
Include/internal/pycore_list.h
Include/internal/pycore_long.h
Include/internal/pycore_long_state.h [new file with mode: 0644]
Include/internal/pycore_pyerrors.h
Include/internal/pycore_pylifecycle.h
Include/internal/pycore_runtime.h
Include/internal/pycore_sliceobject.h [new file with mode: 0644]
Include/internal/pycore_structseq.h
Include/internal/pycore_tuple.h
Include/internal/pycore_typeobject.h [new file with mode: 0644]
Include/internal/pycore_unicodeobject.h [new file with mode: 0644]
Makefile.pre.in
Objects/bytesobject.c
Objects/exceptions.c
Objects/floatobject.c
Objects/genobject.c
Objects/listobject.c
Objects/longobject.c
Objects/object.c
Objects/structseq.c
Objects/tupleobject.c
Objects/typeobject.c
Objects/unicodeobject.c
PCbuild/pythoncore.vcxproj
PCbuild/pythoncore.vcxproj.filters
Python/context.c
Python/errors.c
Python/hamt.c
Python/pylifecycle.c

diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h
new file mode 100644 (file)
index 0000000..b00ed97
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef Py_INTERNAL_BYTESOBJECT_H
+#define Py_INTERNAL_BYTESOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern PyStatus _PyBytes_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyBytes_InitTypes(PyInterpreterState *);
+extern void _PyBytes_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+struct _Py_bytes_state {
+    PyObject *empty_string;
+    PyBytesObject *characters[256];
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_BYTESOBJECT_H */
index a482dd42122872f2f0406d37b156d6ebcc80aa3b..31ca0a43fae29d631959ea54cbbdc35572990dc1 100644 (file)
@@ -7,6 +7,32 @@
 
 #include "pycore_hamt.h"   /* PyHamtObject */
 
+
+/* runtime lifecycle */
+
+PyStatus _PyContext_InitTypes(PyInterpreterState *);
+void _PyContext_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+#  define PyContext_MAXFREELIST 0
+#endif
+
+#ifndef PyContext_MAXFREELIST
+#  define PyContext_MAXFREELIST 255
+#endif
+
+struct _Py_context_state {
+#if PyContext_MAXFREELIST > 0
+    // List of free PyContext objects
+    PyContext *freelist;
+    int numfree;
+#endif
+};
+
 struct _pycontextobject {
     PyObject_HEAD
     PyContext *ctx_prev;
@@ -36,7 +62,4 @@ struct _pycontexttokenobject {
 };
 
 
-int _PyContext_Init(void);
-void _PyContext_Fini(PyInterpreterState *interp);
-
 #endif /* !Py_INTERNAL_CONTEXT_H */
index 2f0536801ec6e4d849f9d5578ae0963bbbb64acf..faa8bb49bb7a4d64eb64339591fba630fae1e904 100644 (file)
@@ -10,6 +10,32 @@ extern "C" {
 #endif
 
 
+/* runtime lifecycle */
+
+extern void _PyDict_Fini(PyInterpreterState *interp);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+#  define PyDict_MAXFREELIST 0
+#endif
+
+#ifndef PyDict_MAXFREELIST
+#  define PyDict_MAXFREELIST 80
+#endif
+
+struct _Py_dict_state {
+#if PyDict_MAXFREELIST > 0
+    /* Dictionary reuse scheme to save calls to malloc and free */
+    PyDictObject *free_list[PyDict_MAXFREELIST];
+    int numfree;
+    PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
+    int keys_numfree;
+#endif
+};
+
 typedef struct {
     /* Cached hash code of me_key. */
     Py_hash_t me_hash;
diff --git a/Include/internal/pycore_exceptions.h b/Include/internal/pycore_exceptions.h
new file mode 100644 (file)
index 0000000..1651966
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef Py_INTERNAL_EXCEPTIONS_H
+#define Py_INTERNAL_EXCEPTIONS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern PyStatus _PyExc_InitState(PyInterpreterState *);
+extern PyStatus _PyExc_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyExc_InitTypes(PyInterpreterState *);
+extern void _PyExc_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+struct _Py_exc_state {
+    // The dict mapping from errno codes to OSError subclasses
+    PyObject *errnomap;
+    PyBaseExceptionObject *memerrors_freelist;
+    int memerrors_numfree;
+    // The ExceptionGroup type
+    PyObject *PyExc_ExceptionGroup;
+};
+
+extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_EXCEPTIONS_H */
index 18227c9e36925d2d876d8941edf579dbd9a595a5..be6045587de1c94c2d1a59672faeb26f7f9e312b 100644 (file)
@@ -8,6 +8,35 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
+
+/* runtime lifecycle */
+
+extern void _PyFloat_InitState(PyInterpreterState *);
+extern PyStatus _PyFloat_InitTypes(PyInterpreterState *);
+extern void _PyFloat_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+#  define PyFloat_MAXFREELIST 0
+#endif
+
+#ifndef PyFloat_MAXFREELIST
+#  define PyFloat_MAXFREELIST   100
+#endif
+
+struct _Py_float_state {
+#if PyFloat_MAXFREELIST > 0
+    /* Special free list
+       free_list is a singly-linked list of available PyFloatObjects,
+       linked via abuse of their ob_type members. */
+    int numfree;
+    PyFloatObject *free_list;
+#endif
+};
+
 /* _PyFloat_{Pack,Unpack}{4,8}
  *
  * The struct and pickle (at least) modules need an efficient platform-
index f4f7ab942c1ac7b5ce522a4aece34364834cc992..a55877b55fb8a3e3669e6d5544995189885898ee 100644 (file)
@@ -4,6 +4,14 @@
 extern "C" {
 #endif
 
+
+/* runtime lifecycle */
+
+extern void _PyFrame_Fini(PyInterpreterState *interp);
+
+
+/* other API */
+
 /* These values are chosen so that the inline functions below all
  * compare f_state to zero.
  */
diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h
new file mode 100644 (file)
index 0000000..74a676d
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef Py_INTERNAL_GENOBJECT_H
+#define Py_INTERNAL_GENOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern void _PyAsyncGen_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+#  define _PyAsyncGen_MAXFREELIST 0
+#endif
+
+#ifndef _PyAsyncGen_MAXFREELIST
+#  define _PyAsyncGen_MAXFREELIST 80
+#endif
+
+struct _Py_async_gen_state {
+#if _PyAsyncGen_MAXFREELIST > 0
+    /* Freelists boost performance 6-10%; they also reduce memory
+       fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
+       are short-living objects that are instantiated for every
+       __anext__() call. */
+    struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
+    int value_numfree;
+
+    struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
+    int asend_numfree;
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_GENOBJECT_H */
index aaf655909551af4704c98a1c4a1dbd80b29aaf79..cf9c19e022d8a5c52558a17299cec0c11a06351d 100644 (file)
@@ -8,6 +8,14 @@
 #define _Py_HAMT_MAX_TREE_DEPTH 7
 
 
+/* runtime lifecycle */
+
+PyStatus _PyHamt_InitTypes(PyInterpreterState *);
+void _PyHamt_Fini(PyInterpreterState *);
+
+
+/* other API */
+
 #define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type)
 
 
@@ -110,7 +118,4 @@ PyObject * _PyHamt_NewIterValues(PyHamtObject *o);
 /* Return a Items iterator over "o". */
 PyObject * _PyHamt_NewIterItems(PyHamtObject *o);
 
-int _PyHamt_Init(void);
-void _PyHamt_Fini(void);
-
 #endif /* !Py_INTERNAL_HAMT_H */
index e421aa4bc4d7b30d051d4763c935586a70fc27b0..e4d7b1b8752eab1ead0f93ed15a306545a9a4fe8 100644 (file)
@@ -10,8 +10,18 @@ extern "C" {
 
 #include "pycore_atomic.h"        // _Py_atomic_address
 #include "pycore_ast_state.h"     // struct ast_state
+#include "pycore_bytesobject.h"   // struct _Py_bytes_state
+#include "pycore_context.h"       // struct _Py_context_state
+#include "pycore_dict.h"          // struct _Py_dict_state
+#include "pycore_exceptions.h"    // struct _Py_exc_state
+#include "pycore_floatobject.h"   // struct _Py_float_state
+#include "pycore_genobject.h"     // struct _Py_async_gen_state
 #include "pycore_gil.h"           // struct _gil_runtime_state
 #include "pycore_gc.h"            // struct _gc_runtime_state
+#include "pycore_list.h"          // struct _Py_list_state
+#include "pycore_tuple.h"         // struct _Py_tuple_state
+#include "pycore_typeobject.h"    // struct type_cache
+#include "pycore_unicodeobject.h" // struct _Py_unicode_state
 #include "pycore_warnings.h"      // struct _warnings_runtime_state
 
 struct _pending_calls {
@@ -44,158 +54,6 @@ struct _ceval_state {
 #endif
 };
 
-/* fs_codec.encoding is initialized to NULL.
-   Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
-struct _Py_unicode_fs_codec {
-    char *encoding;   // Filesystem encoding (encoded to UTF-8)
-    int utf8;         // encoding=="utf-8"?
-    char *errors;     // Filesystem errors (encoded to UTF-8)
-    _Py_error_handler error_handler;
-};
-
-struct _Py_bytes_state {
-    PyObject *empty_string;
-    PyBytesObject *characters[256];
-};
-
-struct _Py_unicode_ids {
-    Py_ssize_t size;
-    PyObject **array;
-};
-
-struct _Py_unicode_state {
-    // The empty Unicode object is a singleton to improve performance.
-    PyObject *empty_string;
-    /* Single character Unicode strings in the Latin-1 range are being
-       shared as well. */
-    PyObject *latin1[256];
-    struct _Py_unicode_fs_codec fs_codec;
-
-    /* This dictionary holds all interned unicode strings.  Note that references
-       to strings in this dictionary are *not* counted in the string's ob_refcnt.
-       When the interned string reaches a refcnt of 0 the string deallocation
-       function will delete the reference from this dictionary.
-
-       Another way to look at this is that to say that the actual reference
-       count of a string is:  s->ob_refcnt + (s->state ? 2 : 0)
-    */
-    PyObject *interned;
-
-    // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId()
-    struct _Py_unicode_ids ids;
-};
-
-#ifndef WITH_FREELISTS
-// without freelists
-#  define PyFloat_MAXFREELIST 0
-// for tuples only store empty tuple singleton
-#  define PyTuple_MAXSAVESIZE 1
-#  define PyTuple_MAXFREELIST 1
-#  define PyList_MAXFREELIST 0
-#  define PyDict_MAXFREELIST 0
-#  define _PyAsyncGen_MAXFREELIST 0
-#  define PyContext_MAXFREELIST 0
-#endif
-
-#ifndef PyFloat_MAXFREELIST
-#  define PyFloat_MAXFREELIST   100
-#endif
-
-struct _Py_float_state {
-#if PyFloat_MAXFREELIST > 0
-    /* Special free list
-       free_list is a singly-linked list of available PyFloatObjects,
-       linked via abuse of their ob_type members. */
-    int numfree;
-    PyFloatObject *free_list;
-#endif
-};
-
-/* Speed optimization to avoid frequent malloc/free of small tuples */
-#ifndef PyTuple_MAXSAVESIZE
-   // Largest tuple to save on free list
-#  define PyTuple_MAXSAVESIZE 20
-#endif
-#ifndef PyTuple_MAXFREELIST
-   // Maximum number of tuples of each size to save
-#  define PyTuple_MAXFREELIST 2000
-#endif
-
-struct _Py_tuple_state {
-#if PyTuple_MAXSAVESIZE > 0
-    /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists,
-       entry 0 is the empty tuple () of which at most one instance
-       will be allocated. */
-    PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
-    int numfree[PyTuple_MAXSAVESIZE];
-#endif
-};
-
-/* Empty list reuse scheme to save calls to malloc and free */
-#ifndef PyList_MAXFREELIST
-#  define PyList_MAXFREELIST 80
-#endif
-
-struct _Py_list_state {
-#if PyList_MAXFREELIST > 0
-    PyListObject *free_list[PyList_MAXFREELIST];
-    int numfree;
-#endif
-};
-
-#ifndef PyDict_MAXFREELIST
-#  define PyDict_MAXFREELIST 80
-#endif
-
-struct _Py_dict_state {
-#if PyDict_MAXFREELIST > 0
-    /* Dictionary reuse scheme to save calls to malloc and free */
-    PyDictObject *free_list[PyDict_MAXFREELIST];
-    int numfree;
-    PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
-    int keys_numfree;
-#endif
-};
-
-#ifndef _PyAsyncGen_MAXFREELIST
-#  define _PyAsyncGen_MAXFREELIST 80
-#endif
-
-struct _Py_async_gen_state {
-#if _PyAsyncGen_MAXFREELIST > 0
-    /* Freelists boost performance 6-10%; they also reduce memory
-       fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
-       are short-living objects that are instantiated for every
-       __anext__() call. */
-    struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
-    int value_numfree;
-
-    struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
-    int asend_numfree;
-#endif
-};
-
-#ifndef PyContext_MAXFREELIST
-#  define PyContext_MAXFREELIST 255
-#endif
-
-struct _Py_context_state {
-#if PyContext_MAXFREELIST > 0
-    // List of free PyContext objects
-    PyContext *freelist;
-    int numfree;
-#endif
-};
-
-struct _Py_exc_state {
-    // The dict mapping from errno codes to OSError subclasses
-    PyObject *errnomap;
-    PyBaseExceptionObject *memerrors_freelist;
-    int memerrors_numfree;
-    // The ExceptionGroup type
-    PyObject *PyExc_ExceptionGroup;
-};
-
 
 // atexit state
 typedef struct {
@@ -211,27 +69,6 @@ struct atexit_state {
 };
 
 
-// Type attribute lookup cache: speed up attribute and method lookups,
-// see _PyType_Lookup().
-struct type_cache_entry {
-    unsigned int version;  // initialized from type->tp_version_tag
-    PyObject *name;        // reference to exactly a str or None
-    PyObject *value;       // borrowed reference or NULL
-};
-
-#define MCACHE_SIZE_EXP 12
-#define MCACHE_STATS 0
-
-struct type_cache {
-    struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
-#if MCACHE_STATS
-    size_t hits;
-    size_t misses;
-    size_t collisions;
-#endif
-};
-
-
 /* interpreter state */
 
 // The PyInterpreterState typedef is in Include/pystate.h.
index f18fb052c49c7c3110e4812bed6a00e0ff4a4277..0717a1f9563a2ac9b6da9a4731e2cf858a0127b3 100644 (file)
@@ -11,6 +11,30 @@ extern "C" {
 #include "listobject.h"           // _PyList_CAST()
 
 
+/* runtime lifecycle */
+
+extern void _PyList_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+#  define PyList_MAXFREELIST 0
+#endif
+
+/* Empty list reuse scheme to save calls to malloc and free */
+#ifndef PyList_MAXFREELIST
+#  define PyList_MAXFREELIST 80
+#endif
+
+struct _Py_list_state {
+#if PyList_MAXFREELIST > 0
+    PyListObject *free_list[PyList_MAXFREELIST];
+    int numfree;
+#endif
+};
+
 #define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item)
 
 
index b9f926996d8107942466dc8aed8f2d733d4fde4a..a5639ceb6924a8022685f93602d52cbff066fb0d 100644 (file)
@@ -8,18 +8,28 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-#include "pycore_interp.h"        // PyInterpreterState.small_ints
+#include "pycore_long_state.h"    // _PyLong_SMALL_INTS
 #include "pycore_pystate.h"       // _PyThreadState_GET()
+#include "pycore_runtime.h"       // _PyRuntime
+
+
+/* runtime lifecycle */
+
+extern void _PyLong_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyLong_InitTypes(PyInterpreterState *);
+
+
+/* other API */
 
 // Return a borrowed reference to the zero singleton.
 // The function cannot return NULL.
 static inline PyObject* _PyLong_GetZero(void)
-{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS]; }
+{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; }
 
 // Return a borrowed reference to the one singleton.
 // The function cannot return NULL.
 static inline PyObject* _PyLong_GetOne(void)
-{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS+1]; }
+{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; }
 
 PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
 PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
diff --git a/Include/internal/pycore_long_state.h b/Include/internal/pycore_long_state.h
new file mode 100644 (file)
index 0000000..5fe8e62
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef Py_INTERNAL_LONG_STATE_H
+#define Py_INTERNAL_LONG_STATE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+#define _PY_NSMALLPOSINTS           257
+#define _PY_NSMALLNEGINTS           5
+
+// _PyLong_GetZero() and _PyLong_GetOne() must always be available
+#if _PY_NSMALLPOSINTS < 2
+#  error "_PY_NSMALLPOSINTS must be greater than 1"
+#endif
+
+struct _Py_long_state {
+    /* Small integers are preallocated in this array so that they
+     * can be shared.
+     * The integers that are preallocated are those in the range
+     *-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
+     */
+    PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
+};
+
+#define _PyLong_SMALL_INTS _PyRuntime.int_state.small_ints
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_LONG_STATE_H */
index 14ea182f4f47aa5620486231415eb2522a514f4e..3134afeb864904804468431808a7dbaa16771c68 100644 (file)
@@ -8,6 +8,14 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
+
+/* runtime lifecycle */
+
+extern PyStatus _PyErr_InitTypes(PyInterpreterState *);
+
+
+/* other API */
+
 static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
 {
     assert(tstate != NULL);
index 5e0f36ab2ae494a20bc12243762e0566fd8c7757..766e889f237b96bf550b62cc9a938ae05b1a02bc 100644 (file)
@@ -49,13 +49,6 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
 
 /* Various one-time initializers */
 
-extern PyStatus _PyUnicode_Init(PyInterpreterState *interp);
-extern PyStatus _PyUnicode_InitTypes(void);
-extern PyStatus _PyBytes_Init(PyInterpreterState *interp);
-extern int _PyStructSequence_Init(void);
-extern void _PyLong_Init(PyInterpreterState *interp);
-extern int _PyLong_InitTypes(void);
-extern PyStatus _PyTuple_Init(PyInterpreterState *interp);
 extern PyStatus _PyFaulthandler_Init(int enable);
 extern int _PyTraceMalloc_Init(int enable);
 extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp);
@@ -65,15 +58,9 @@ extern PyStatus _PySys_Create(
 extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
 extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
 extern int _PySys_UpdateConfig(PyThreadState *tstate);
-extern PyStatus _PyExc_Init(PyInterpreterState *interp);
-extern PyStatus _PyErr_InitTypes(void);
 extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod);
-extern void _PyFloat_Init(void);
-extern int _PyFloat_InitTypes(void);
 extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
 
-extern PyStatus _PyTypes_Init(void);
-extern PyStatus _PyTypes_InitSlotDefs(void);
 extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
 extern PyStatus _PyGC_Init(PyInterpreterState *interp);
 extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
@@ -81,28 +68,13 @@ extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
 
 /* Various internal finalizers */
 
-extern void _PyFrame_Fini(PyInterpreterState *interp);
-extern void _PyDict_Fini(PyInterpreterState *interp);
-extern void _PyTuple_Fini(PyInterpreterState *interp);
-extern void _PyList_Fini(PyInterpreterState *interp);
-extern void _PyBytes_Fini(PyInterpreterState *interp);
-extern void _PyFloat_Fini(PyInterpreterState *interp);
-extern void _PySlice_Fini(PyInterpreterState *interp);
-extern void _PyAsyncGen_Fini(PyInterpreterState *interp);
-
 extern int _PySignal_Init(int install_signal_handlers);
 extern void _PySignal_Fini(void);
 
-extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *interp);
-extern void _PyExc_Fini(PyInterpreterState *interp);
 extern void _PyImport_Fini(void);
 extern void _PyImport_Fini2(void);
 extern void _PyGC_Fini(PyInterpreterState *interp);
-extern void _PyType_Fini(PyInterpreterState *interp);
 extern void _Py_HashRandomization_Fini(void);
-extern void _PyUnicode_Fini(PyInterpreterState *interp);
-extern void _PyUnicode_ClearInterned(PyInterpreterState *interp);
-extern void _PyLong_Fini(PyInterpreterState *interp);
 extern void _PyFaulthandler_Fini(void);
 extern void _PyHash_Fini(void);
 extern void _PyTraceMalloc_Fini(void);
index 39e30b785a3cd0b7fa66749e408025f128ec26a8..bd88510d1f056243173a5391205d1a43388be081 100644 (file)
@@ -10,14 +10,8 @@ extern "C" {
 
 #include "pycore_atomic.h"    /* _Py_atomic_address */
 #include "pycore_gil.h"       // struct _gil_runtime_state
-
-#define _PY_NSMALLPOSINTS           257
-#define _PY_NSMALLNEGINTS           5
-
-// _PyLong_GetZero() and _PyLong_GetOne() must always be available
-#if _PY_NSMALLPOSINTS < 2
-#  error "_PY_NSMALLPOSINTS must be greater than 1"
-#endif
+#include "pycore_long_state.h"  // struct _Py_long_state
+#include "pycore_unicodeobject.h"  // struct _Py_unicode_runtime_ids
 
 /* ceval state */
 
@@ -57,13 +51,6 @@ typedef struct _Py_AuditHookEntry {
     void *userData;
 } _Py_AuditHookEntry;
 
-struct _Py_unicode_runtime_ids {
-    PyThread_type_lock lock;
-    // next_index value must be preserved when Py_Initialize()/Py_Finalize()
-    // is called multiple times: see _PyUnicode_FromId() implementation.
-    Py_ssize_t next_index;
-};
-
 /* Full Python runtime state */
 
 typedef struct pyruntimestate {
@@ -114,12 +101,7 @@ typedef struct pyruntimestate {
 
     unsigned long main_thread;
 
-    /* Small integers are preallocated in this array so that they
-     * can be shared.
-     * The integers that are preallocated are those in the range
-     *-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
-     */
-    PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
+    struct _Py_long_state int_state;
 
 #define NEXITFUNCS 32
     void (*exitfuncs[NEXITFUNCS])(void);
diff --git a/Include/internal/pycore_sliceobject.h b/Include/internal/pycore_sliceobject.h
new file mode 100644 (file)
index 0000000..e81834c
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef Py_INTERNAL_SLICEOBJECT_H
+#define Py_INTERNAL_SLICEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern void _PySlice_Fini(PyInterpreterState *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_SLICEOBJECT_H */
index 84c8d477e0dac8e94f6e7436404a016f9256f8a8..3a61cb9a12608b652d7fda1ae8313cbdbd442939 100644 (file)
@@ -9,6 +9,13 @@ extern "C" {
 #endif
 
 
+/* runtime lifecycle */
+
+extern PyStatus _PyStructSequence_InitState(PyInterpreterState *);
+
+
+/* other API */
+
 PyAPI_FUNC(int) _PyStructSequence_InitType(
     PyTypeObject *type,
     PyStructSequence_Desc *desc,
index 79c827fe8800a7324c261a683ebf3597eba5c418..624c21caec1cc7539501f42ae8ddcd334166b61a 100644 (file)
@@ -10,6 +10,43 @@ extern "C" {
 
 #include "tupleobject.h"   /* _PyTuple_CAST() */
 
+
+/* runtime lifecycle */
+
+extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyTuple_InitTypes(PyInterpreterState *);
+extern void _PyTuple_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+// for tuples only store empty tuple singleton
+#  define PyTuple_MAXSAVESIZE 1
+#  define PyTuple_MAXFREELIST 1
+#endif
+
+/* Speed optimization to avoid frequent malloc/free of small tuples */
+#ifndef PyTuple_MAXSAVESIZE
+   // Largest tuple to save on free list
+#  define PyTuple_MAXSAVESIZE 20
+#endif
+#ifndef PyTuple_MAXFREELIST
+   // Maximum number of tuples of each size to save
+#  define PyTuple_MAXFREELIST 2000
+#endif
+
+struct _Py_tuple_state {
+#if PyTuple_MAXSAVESIZE > 0
+    /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists,
+       entry 0 is the empty tuple () of which at most one instance
+       will be allocated. */
+    PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
+    int numfree[PyTuple_MAXSAVESIZE];
+#endif
+};
+
 #define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item)
 
 extern PyObject *_PyTuple_FromArray(PyObject *const *, Py_ssize_t);
diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h
new file mode 100644 (file)
index 0000000..7fd8a1f
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef Py_INTERNAL_TYPEOBJECT_H
+#define Py_INTERNAL_TYPEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern PyStatus _PyTypes_InitState(PyInterpreterState *);
+extern PyStatus _PyTypes_InitTypes(PyInterpreterState *);
+extern void _PyTypes_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+// Type attribute lookup cache: speed up attribute and method lookups,
+// see _PyType_Lookup().
+struct type_cache_entry {
+    unsigned int version;  // initialized from type->tp_version_tag
+    PyObject *name;        // reference to exactly a str or None
+    PyObject *value;       // borrowed reference or NULL
+};
+
+#define MCACHE_SIZE_EXP 12
+#define MCACHE_STATS 0
+
+struct type_cache {
+    struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
+#if MCACHE_STATS
+    size_t hits;
+    size_t misses;
+    size_t collisions;
+#endif
+};
+
+extern PyStatus _PyTypes_InitSlotDefs(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_TYPEOBJECT_H */
diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h
new file mode 100644 (file)
index 0000000..c50c420
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef Py_INTERNAL_UNICODEOBJECT_H
+#define Py_INTERNAL_UNICODEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern void _PyUnicode_InitState(PyInterpreterState *);
+extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *);
+extern void _PyUnicode_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+struct _Py_unicode_runtime_ids {
+    PyThread_type_lock lock;
+    // next_index value must be preserved when Py_Initialize()/Py_Finalize()
+    // is called multiple times: see _PyUnicode_FromId() implementation.
+    Py_ssize_t next_index;
+};
+
+/* fs_codec.encoding is initialized to NULL.
+   Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
+struct _Py_unicode_fs_codec {
+    char *encoding;   // Filesystem encoding (encoded to UTF-8)
+    int utf8;         // encoding=="utf-8"?
+    char *errors;     // Filesystem errors (encoded to UTF-8)
+    _Py_error_handler error_handler;
+};
+
+struct _Py_unicode_ids {
+    Py_ssize_t size;
+    PyObject **array;
+};
+
+struct _Py_unicode_state {
+    // The empty Unicode object is a singleton to improve performance.
+    PyObject *empty_string;
+    /* Single character Unicode strings in the Latin-1 range are being
+       shared as well. */
+    PyObject *latin1[256];
+    struct _Py_unicode_fs_codec fs_codec;
+
+    /* This dictionary holds all interned unicode strings.  Note that references
+       to strings in this dictionary are *not* counted in the string's ob_refcnt.
+       When the interned string reaches a refcnt of 0 the string deallocation
+       function will delete the reference from this dictionary.
+
+       Another way to look at this is that to say that the actual reference
+       count of a string is:  s->ob_refcnt + (s->state ? 2 : 0)
+    */
+    PyObject *interned;
+
+    // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId()
+    struct _Py_unicode_ids ids;
+};
+
+extern void _PyUnicode_ClearInterned(PyInterpreterState *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_UNICODEOBJECT_H */
index f6801353cfeb464e4bfaa8ff3515ba8b0a7d6551..57928eead4384b7a0a91624f0aa3258dbf37b460 100644 (file)
@@ -1576,6 +1576,7 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/internal/pycore_atomic_funcs.h \
                $(srcdir)/Include/internal/pycore_bitutils.h \
                $(srcdir)/Include/internal/pycore_bytes_methods.h \
+               $(srcdir)/Include/internal/pycore_bytesobject.h \
                $(srcdir)/Include/internal/pycore_call.h \
                $(srcdir)/Include/internal/pycore_ceval.h \
                $(srcdir)/Include/internal/pycore_code.h \
@@ -1584,10 +1585,12 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/internal/pycore_context.h \
                $(srcdir)/Include/internal/pycore_dict.h \
                $(srcdir)/Include/internal/pycore_dtoa.h \
+               $(srcdir)/Include/internal/pycore_exceptions.h \
                $(srcdir)/Include/internal/pycore_fileutils.h \
                $(srcdir)/Include/internal/pycore_floatobject.h \
                $(srcdir)/Include/internal/pycore_format.h \
                $(srcdir)/Include/internal/pycore_function.h \
+               $(srcdir)/Include/internal/pycore_genobject.h \
                $(srcdir)/Include/internal/pycore_getopt.h \
                $(srcdir)/Include/internal/pycore_gil.h \
                $(srcdir)/Include/internal/pycore_hamt.h \
@@ -1598,6 +1601,7 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/internal/pycore_interpreteridobject.h \
                $(srcdir)/Include/internal/pycore_list.h \
                $(srcdir)/Include/internal/pycore_long.h \
+               $(srcdir)/Include/internal/pycore_long_state.h \
                $(srcdir)/Include/internal/pycore_moduleobject.h \
                $(srcdir)/Include/internal/pycore_namespace.h \
                $(srcdir)/Include/internal/pycore_object.h \
@@ -1609,14 +1613,17 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/internal/pycore_pymem.h \
                $(srcdir)/Include/internal/pycore_pystate.h \
                $(srcdir)/Include/internal/pycore_runtime.h \
+               $(srcdir)/Include/internal/pycore_sliceobject.h \
                $(srcdir)/Include/internal/pycore_strhex.h \
                $(srcdir)/Include/internal/pycore_structseq.h \
                $(srcdir)/Include/internal/pycore_symtable.h \
                $(srcdir)/Include/internal/pycore_sysmodule.h \
                $(srcdir)/Include/internal/pycore_traceback.h \
                $(srcdir)/Include/internal/pycore_tuple.h \
+               $(srcdir)/Include/internal/pycore_typeobject.h \
                $(srcdir)/Include/internal/pycore_ucnhash.h \
                $(srcdir)/Include/internal/pycore_unionobject.h \
+               $(srcdir)/Include/internal/pycore_unicodeobject.h \
                $(srcdir)/Include/internal/pycore_warnings.h \
                $(DTRACE_HEADERS) \
                \
index 66fd2ecc3c41de9d03bc1089ccf7018b27ecec76..2f7e0a6dde6fe032a2ba04fc0d7a4bd7d71e1655 100644 (file)
@@ -5,6 +5,7 @@
 #include "Python.h"
 #include "pycore_abstract.h"      // _PyIndex_Check()
 #include "pycore_bytes_methods.h" // _Py_bytes_startswith()
+#include "pycore_bytesobject.h"   // struct _Py_bytes_state
 #include "pycore_call.h"          // _PyObject_CallNoArgs()
 #include "pycore_format.h"        // F_LJUST
 #include "pycore_initconfig.h"    // _PyStatus_OK()
@@ -3086,7 +3087,7 @@ error:
 
 
 PyStatus
-_PyBytes_Init(PyInterpreterState *interp)
+_PyBytes_InitGlobalObjects(PyInterpreterState *interp)
 {
     struct _Py_bytes_state *state = &interp->bytes;
     if (bytes_create_empty_string_singleton(state) < 0) {
@@ -3096,6 +3097,25 @@ _PyBytes_Init(PyInterpreterState *interp)
 }
 
 
+PyStatus
+_PyBytes_InitTypes(PyInterpreterState *interp)
+{
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
+    if (PyType_Ready(&PyBytes_Type) < 0) {
+        return _PyStatus_ERR("Can't initialize bytes type");
+    }
+
+    if (PyType_Ready(&PyBytesIter_Type) < 0) {
+        return _PyStatus_ERR("Can't initialize bytes iterator type");
+    }
+
+    return _PyStatus_OK();
+}
+
+
 void
 _PyBytes_Fini(PyInterpreterState *interp)
 {
index e1a8c1363ef62eaa5ddebdb8284d453cb59e9887..134015752560db791ec9cfbc0196ae9a6a3ee083 100644 (file)
@@ -7,6 +7,7 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include <stdbool.h>
+#include "pycore_exceptions.h"    // struct _Py_exc_state
 #include "pycore_initconfig.h"
 #include "pycore_object.h"
 #include "structmember.h"         // PyMemberDef
@@ -3189,10 +3190,8 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning,
 #endif /* MS_WINDOWS */
 
 PyStatus
-_PyExc_Init(PyInterpreterState *interp)
+_PyExc_InitTypes(PyInterpreterState *interp)
 {
-    struct _Py_exc_state *state = &interp->exc_state;
-
 #define PRE_INIT(TYPE) \
     if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
         if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
@@ -3201,17 +3200,6 @@ _PyExc_Init(PyInterpreterState *interp)
         Py_INCREF(PyExc_ ## TYPE); \
     }
 
-#define ADD_ERRNO(TYPE, CODE) \
-    do { \
-        PyObject *_code = PyLong_FromLong(CODE); \
-        assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
-        if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
-            Py_XDECREF(_code); \
-            return _PyStatus_ERR("errmap insertion problem."); \
-        } \
-        Py_DECREF(_code); \
-    } while (0)
-
     PRE_INIT(BaseException);
     PRE_INIT(BaseExceptionGroup);
     PRE_INIT(Exception);
@@ -3282,10 +3270,37 @@ _PyExc_Init(PyInterpreterState *interp)
     PRE_INIT(ProcessLookupError);
     PRE_INIT(TimeoutError);
 
+    return _PyStatus_OK();
+
+#undef PRE_INIT
+}
+
+PyStatus
+_PyExc_InitGlobalObjects(PyInterpreterState *interp)
+{
     if (preallocate_memerrors() < 0) {
         return _PyStatus_NO_MEMORY();
     }
 
+    return _PyStatus_OK();
+}
+
+PyStatus
+_PyExc_InitState(PyInterpreterState *interp)
+{
+    struct _Py_exc_state *state = &interp->exc_state;
+
+#define ADD_ERRNO(TYPE, CODE) \
+    do { \
+        PyObject *_code = PyLong_FromLong(CODE); \
+        assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
+        if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
+            Py_XDECREF(_code); \
+            return _PyStatus_ERR("errmap insertion problem."); \
+        } \
+        Py_DECREF(_code); \
+    } while (0)
+
     /* Add exceptions to errnomap */
     assert(state->errnomap == NULL);
     state->errnomap = PyDict_New();
@@ -3317,7 +3332,6 @@ _PyExc_Init(PyInterpreterState *interp)
 
     return _PyStatus_OK();
 
-#undef PRE_INIT
 #undef ADD_ERRNO
 }
 
index 7fc192e7201171d483b3011bf85b411953f0b0da..f8620d6f8ef0b189a0cf06ebe0a05661ddf95fd0 100644 (file)
@@ -6,6 +6,7 @@
 #include "Python.h"
 #include "pycore_dtoa.h"          // _Py_dg_dtoa()
 #include "pycore_floatobject.h"   // _PyFloat_FormatAdvancedWriter()
+#include "pycore_initconfig.h"    // _PyStatus_OK()
 #include "pycore_interp.h"        // _PyInterpreterState.float_state
 #include "pycore_long.h"          // _PyLong_GetOne()
 #include "pycore_object.h"        // _PyObject_Init()
@@ -1981,8 +1982,12 @@ PyTypeObject PyFloat_Type = {
 };
 
 void
-_PyFloat_Init(void)
+_PyFloat_InitState(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return;
+    }
+
     /* We attempt to determine if this machine is using IEEE
        floating point formats by peering at the bits of some
        carefully chosen values.  If it looks like we are on an
@@ -2030,16 +2035,25 @@ _PyFloat_Init(void)
     float_format = detected_float_format;
 }
 
-int
-_PyFloat_InitTypes(void)
+PyStatus
+_PyFloat_InitTypes(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
+    if (PyType_Ready(&PyFloat_Type) < 0) {
+        return _PyStatus_ERR("Can't initialize float type");
+    }
+
     /* Init float info */
     if (FloatInfoType.tp_name == NULL) {
         if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) {
-            return -1;
+            return _PyStatus_ERR("can't init float info type");
         }
     }
-    return 0;
+
+    return _PyStatus_OK();
 }
 
 void
index 147194c38a0a1db82c0dab9a8a9796f5d48c5f6b..1b08b43ac22e901d6706413715c4a4ed7dcb56ba 100644 (file)
@@ -3,6 +3,7 @@
 #include "Python.h"
 #include "pycore_call.h"          // _PyObject_CallNoArgs()
 #include "pycore_ceval.h"         // _PyEval_EvalFrame()
+#include "pycore_genobject.h"     // struct _Py_async_gen_state
 #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
 #include "pycore_pyerrors.h"      // _PyErr_ClearExcState()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
index be84cf9c330e37518c1815776d39be29d72c88a5..e7023fb9eb1d2a60314e383bfe3cd0a5cc309047 100644 (file)
@@ -3,6 +3,7 @@
 #include "Python.h"
 #include "pycore_abstract.h"      // _PyIndex_Check()
 #include "pycore_interp.h"        // PyInterpreterState.list
+#include "pycore_list.h"          // struct _Py_list_state
 #include "pycore_object.h"        // _PyObject_GC_TRACK()
 #include "pycore_tuple.h"         // _PyTuple_FromArray()
 #include <stddef.h>
index ce4f0d72540d38e4c7169f7160ee70d7d2c2935c..f6d5e7648be16f180c9f47172eb1b48a77ac0393 100644 (file)
@@ -4,10 +4,11 @@
 
 #include "Python.h"
 #include "pycore_bitutils.h"      // _Py_popcount32()
-#include "pycore_runtime.h"       // _PY_NSMALLPOSINTS
+#include "pycore_initconfig.h"    // _PyStatus_OK()
 #include "pycore_long.h"          // _Py_SmallInts
 #include "pycore_object.h"        // _PyObject_InitVar()
 #include "pycore_pystate.h"       // _Py_IsMainInterpreter()
+#include "pycore_runtime.h"       // _PY_NSMALLPOSINTS
 
 #include <ctype.h>
 #include <float.h>
@@ -48,7 +49,7 @@ static PyObject *
 get_small_int(sdigit ival)
 {
     assert(IS_SMALL_INT(ival));
-    PyObject *v = (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS + ival];
+    PyObject *v = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + ival];
     Py_INCREF(v);
     return v;
 }
@@ -5828,31 +5829,51 @@ PyLong_GetInfo(void)
     return int_info;
 }
 
+
+/* runtime lifecycle */
+
 void
-_PyLong_Init(PyInterpreterState *interp)
+_PyLong_InitGlobalObjects(PyInterpreterState *interp)
 {
-    if (_PyRuntime.small_ints[0].ob_base.ob_base.ob_refcnt == 0) {
-        for (Py_ssize_t i=0; i < _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS; i++) {
-            sdigit ival = (sdigit)i - _PY_NSMALLNEGINTS;
-            int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
-            _PyRuntime.small_ints[i].ob_base.ob_base.ob_refcnt = 1;
-            _PyRuntime.small_ints[i].ob_base.ob_base.ob_type = &PyLong_Type;
-            _PyRuntime.small_ints[i].ob_base.ob_size = size;
-            _PyRuntime.small_ints[i].ob_digit[0] = (digit)abs(ival);
-        }
+    if (!_Py_IsMainInterpreter(interp)) {
+        return;
+    }
+
+    PyLongObject *small_ints = _PyLong_SMALL_INTS;
+    if (small_ints[0].ob_base.ob_base.ob_refcnt != 0) {
+        // Py_Initialize() must be running a second time.
+        return;
+    }
+
+    for (Py_ssize_t i=0; i < _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS; i++) {
+        sdigit ival = (sdigit)i - _PY_NSMALLNEGINTS;
+        int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
+        small_ints[i].ob_base.ob_base.ob_refcnt = 1;
+        small_ints[i].ob_base.ob_base.ob_type = &PyLong_Type;
+        small_ints[i].ob_base.ob_size = size;
+        small_ints[i].ob_digit[0] = (digit)abs(ival);
     }
 }
 
-int
-_PyLong_InitTypes(void)
+PyStatus
+_PyLong_InitTypes(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
+    if (PyType_Ready(&PyLong_Type) < 0) {
+        return _PyStatus_ERR("Can't initialize int type");
+    }
+
     /* initialize int_info */
     if (Int_InfoType.tp_name == NULL) {
         if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) {
-            return -1;
+            return _PyStatus_ERR("can't init int info type");
         }
     }
-    return 0;
+
+    return _PyStatus_OK();
 }
 
 void
index a1c2e16b6fa2ce4846d0e9da20dbf193a0000935..124485d64ab77069c1ab8bdc3e82195f398ca932 100644 (file)
 #include "pycore_namespace.h"     // _PyNamespace_Type
 #include "pycore_object.h"        // _PyType_CheckConsistency()
 #include "pycore_pyerrors.h"      // _PyErr_Occurred()
-#include "pycore_pylifecycle.h"   // _PyTypes_InitSlotDefs()
 #include "pycore_pymem.h"         // _PyMem_IsPtrFreed()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
 #include "pycore_symtable.h"      // PySTEntry_Type
+#include "pycore_typeobject.h"    // _PyTypes_InitSlotDefs()
 #include "pycore_unionobject.h"   // _PyUnion_Type
 #include "frameobject.h"          // PyFrame_Type
 #include "pycore_interpreteridobject.h"  // _PyInterpreterID_Type
@@ -1823,13 +1823,27 @@ PyObject _Py_NotImplementedStruct = {
 };
 
 PyStatus
-_PyTypes_Init(void)
+_PyTypes_InitState(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
     PyStatus status = _PyTypes_InitSlotDefs();
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
 
+    return _PyStatus_OK();
+}
+
+PyStatus
+_PyTypes_InitTypes(PyInterpreterState *interp)
+{
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
 #define INIT_TYPE(TYPE) \
     do { \
         if (PyType_Ready(&(TYPE)) < 0) { \
@@ -1843,13 +1857,11 @@ _PyTypes_Init(void)
     assert(PyBaseObject_Type.tp_base == NULL);
     assert(PyType_Type.tp_base == &PyBaseObject_Type);
 
-    // All other static types
+    // All other static types (unless initialized elsewhere)
     INIT_TYPE(PyAsyncGen_Type);
     INIT_TYPE(PyBool_Type);
     INIT_TYPE(PyByteArrayIter_Type);
     INIT_TYPE(PyByteArray_Type);
-    INIT_TYPE(PyBytesIter_Type);
-    INIT_TYPE(PyBytes_Type);
     INIT_TYPE(PyCFunction_Type);
     INIT_TYPE(PyCMethod_Type);
     INIT_TYPE(PyCallIter_Type);
@@ -1873,7 +1885,6 @@ _PyTypes_Init(void)
     INIT_TYPE(PyDict_Type);
     INIT_TYPE(PyEllipsis_Type);
     INIT_TYPE(PyEnum_Type);
-    INIT_TYPE(PyFloat_Type);
     INIT_TYPE(PyFrame_Type);
     INIT_TYPE(PyFrozenSet_Type);
     INIT_TYPE(PyFunction_Type);
@@ -1884,7 +1895,6 @@ _PyTypes_Init(void)
     INIT_TYPE(PyListRevIter_Type);
     INIT_TYPE(PyList_Type);
     INIT_TYPE(PyLongRangeIter_Type);
-    INIT_TYPE(PyLong_Type);
     INIT_TYPE(PyMemberDescr_Type);
     INIT_TYPE(PyMemoryView_Type);
     INIT_TYPE(PyMethodDescr_Type);
@@ -1910,10 +1920,6 @@ _PyTypes_Init(void)
     INIT_TYPE(PyStdPrinter_Type);
     INIT_TYPE(PySuper_Type);
     INIT_TYPE(PyTraceBack_Type);
-    INIT_TYPE(PyTupleIter_Type);
-    INIT_TYPE(PyTuple_Type);
-    INIT_TYPE(PyUnicodeIter_Type);
-    INIT_TYPE(PyUnicode_Type);
     INIT_TYPE(PyWrapperDescr_Type);
     INIT_TYPE(Py_GenericAliasType);
     INIT_TYPE(_PyAnextAwaitable_Type);
index 73795b677b404f13de8c92f8eb48b78ba289e368..a2eefb0455a17d32d3463cefa5f6bf50891115df 100644 (file)
@@ -12,6 +12,7 @@
 #include "pycore_object.h"        // _PyObject_GC_TRACK()
 #include "structmember.h"         // PyMemberDef
 #include "pycore_structseq.h"     // PyStructSequence_InitType()
+#include "pycore_initconfig.h"    // _PyStatus_OK()
 
 static const char visible_length_key[] = "n_sequence_fields";
 static const char real_length_key[] = "n_fields";
@@ -583,13 +584,20 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc)
     return type;
 }
 
-int _PyStructSequence_Init(void)
+
+/* runtime lifecycle */
+
+PyStatus _PyStructSequence_InitState(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
     if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL
         || _PyUnicode_FromId(&PyId_n_fields) == NULL
         || _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL)
     {
-        return -1;
+        return _PyStatus_ERR("can't initialize structseq state");
     }
-    return 0;
+    return _PyStatus_OK();
 }
index e9d1b5926abb377693cd06e31be2132099c6a77a..cb34c5eb15e4cac20a7083a4f45e52df3f08afe2 100644 (file)
@@ -7,6 +7,7 @@
 #include "pycore_initconfig.h"    // _PyStatus_OK()
 #include "pycore_object.h"        // _PyObject_GC_TRACK()
 #include "pycore_pyerrors.h"      // _Py_FatalRefcountError()
+#include "pycore_tuple.h"         // struct _Py_tuple_state()
 
 /*[clinic input]
 class tuple "PyTupleObject *" "&PyTuple_Type"
@@ -1066,7 +1067,7 @@ _PyTuple_ClearFreeList(PyInterpreterState *interp)
 
 
 PyStatus
-_PyTuple_Init(PyInterpreterState *interp)
+_PyTuple_InitGlobalObjects(PyInterpreterState *interp)
 {
     struct _Py_tuple_state *state = &interp->tuple;
     if (tuple_create_empty_tuple_singleton(state) < 0) {
@@ -1076,6 +1077,24 @@ _PyTuple_Init(PyInterpreterState *interp)
 }
 
 
+PyStatus
+_PyTuple_InitTypes(PyInterpreterState *interp)
+{
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
+    if (PyType_Ready(&PyTuple_Type) < 0) {
+        return _PyStatus_ERR("Can't initialize tuple type");
+    }
+
+    if (PyType_Ready(&PyTupleIter_Type) < 0) {
+        return _PyStatus_ERR("Can't initialize tuple iterator type");
+    }
+
+    return _PyStatus_OK();
+}
+
 void
 _PyTuple_Fini(PyInterpreterState *interp)
 {
index 2fd93b61c0b2b027c06566a4425d17dc90879058..af35180cdb98310b6ca22ec5a38fbdf7e4ae6fd7 100644 (file)
@@ -9,6 +9,7 @@
 #include "pycore_object.h"        // _PyType_HasFeature()
 #include "pycore_pyerrors.h"      // _PyErr_Occurred()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
+#include "pycore_typeobject.h"    // struct type_cache
 #include "pycore_unionobject.h"   // _Py_union_type_or
 #include "frameobject.h"          // PyFrameObject
 #include "pycore_frame.h"         // InterpreterFrame
@@ -294,7 +295,7 @@ PyType_ClearCache(void)
 
 
 void
-_PyType_Fini(PyInterpreterState *interp)
+_PyTypes_Fini(PyInterpreterState *interp)
 {
     struct type_cache *cache = &interp->type_cache;
     type_cache_clear(cache, NULL);
index 532c48ad4d4aadfe0d8ce5983eac8667d554a554..14449bce70839fca5a53aa4a99303ea24d32fd20 100644 (file)
@@ -53,6 +53,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "pycore_pylifecycle.h"   // _Py_SetFileSystemEncoding()
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
 #include "pycore_ucnhash.h"       // _PyUnicode_Name_CAPI
+#include "pycore_unicodeobject.h" // struct _Py_unicode_state
 #include "stringlib/eq.h"         // unicode_eq()
 
 #ifdef MS_WINDOWS
@@ -15504,41 +15505,56 @@ PyTypeObject PyUnicode_Type = {
 
 /* Initialize the Unicode implementation */
 
+void
+_PyUnicode_InitState(PyInterpreterState *interp)
+{
+    if (!_Py_IsMainInterpreter(interp)) {
+        return;
+    }
+
+    /* initialize the linebreak bloom filter */
+    const Py_UCS2 linebreak[] = {
+        0x000A, /* LINE FEED */
+        0x000D, /* CARRIAGE RETURN */
+        0x001C, /* FILE SEPARATOR */
+        0x001D, /* GROUP SEPARATOR */
+        0x001E, /* RECORD SEPARATOR */
+        0x0085, /* NEXT LINE */
+        0x2028, /* LINE SEPARATOR */
+        0x2029, /* PARAGRAPH SEPARATOR */
+    };
+    bloom_linebreak = make_bloom_mask(
+        PyUnicode_2BYTE_KIND, linebreak,
+        Py_ARRAY_LENGTH(linebreak));
+}
+
+
 PyStatus
-_PyUnicode_Init(PyInterpreterState *interp)
+_PyUnicode_InitGlobalObjects(PyInterpreterState *interp)
 {
     struct _Py_unicode_state *state = &interp->unicode;
     if (unicode_create_empty_string_singleton(state) < 0) {
         return _PyStatus_NO_MEMORY();
     }
 
-    if (_Py_IsMainInterpreter(interp)) {
-        /* initialize the linebreak bloom filter */
-        const Py_UCS2 linebreak[] = {
-            0x000A, /* LINE FEED */
-            0x000D, /* CARRIAGE RETURN */
-            0x001C, /* FILE SEPARATOR */
-            0x001D, /* GROUP SEPARATOR */
-            0x001E, /* RECORD SEPARATOR */
-            0x0085, /* NEXT LINE */
-            0x2028, /* LINE SEPARATOR */
-            0x2029, /* PARAGRAPH SEPARATOR */
-        };
-        bloom_linebreak = make_bloom_mask(
-            PyUnicode_2BYTE_KIND, linebreak,
-            Py_ARRAY_LENGTH(linebreak));
-    }
-
     return _PyStatus_OK();
 }
 
 
 PyStatus
-_PyUnicode_InitTypes(void)
+_PyUnicode_InitTypes(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
     if (PyType_Ready(&PyUnicode_Type) < 0) {
         return _PyStatus_ERR("Can't initialize unicode type");
     }
+    if (PyType_Ready(&PyUnicodeIter_Type) < 0) {
+        return _PyStatus_ERR("Can't initialize unicode iterator type");
+    }
+
     if (PyType_Ready(&EncodingMapType) < 0) {
          return _PyStatus_ERR("Can't initialize encoding map type");
     }
index a2ee95e0ae9fc5215ca3c19c004c0c6bacfff8ea..e3a71ca645143e3dc78941f0235bcb72fd2f0e4d 100644 (file)
     <ClInclude Include="..\Include\internal\pycore_atomic_funcs.h" />
     <ClInclude Include="..\Include\internal\pycore_bitutils.h" />
     <ClInclude Include="..\Include\internal\pycore_bytes_methods.h" />
+    <ClInclude Include="..\Include\internal\pycore_bytesobject.h" />
     <ClInclude Include="..\Include\internal\pycore_call.h" />
     <ClInclude Include="..\Include\internal\pycore_ceval.h" />
     <ClInclude Include="..\Include\internal\pycore_code.h" />
     <ClInclude Include="..\Include\internal\pycore_condvar.h" />
     <ClInclude Include="..\Include\internal\pycore_context.h" />
     <ClInclude Include="..\Include\internal\pycore_dtoa.h" />
+    <ClInclude Include="..\Include\internal\pycore_exceptions.h" />
     <ClInclude Include="..\Include\internal\pycore_fileutils.h" />
     <ClInclude Include="..\Include\internal\pycore_floatobject.h" />
     <ClInclude Include="..\Include\internal\pycore_format.h" />
     <ClInclude Include="..\Include\internal\pycore_function.h" />
     <ClInclude Include="..\Include\internal\pycore_gc.h" />
+    <ClInclude Include="..\Include\internal\pycore_genobject.h" />
     <ClInclude Include="..\Include\internal\pycore_getopt.h" />
     <ClInclude Include="..\Include\internal\pycore_gil.h" />
     <ClInclude Include="..\Include\internal\pycore_hamt.h" />
     <ClInclude Include="..\Include\internal\pycore_interpreteridobject.h" />
     <ClInclude Include="..\Include\internal\pycore_list.h" />
     <ClInclude Include="..\Include\internal\pycore_long.h" />
+    <ClInclude Include="..\Include\internal\pycore_long_state.h" />
     <ClInclude Include="..\Include\internal\pycore_moduleobject.h" />
     <ClInclude Include="..\Include\internal\pycore_namespace.h" />
     <ClInclude Include="..\Include\internal\pycore_object.h" />
     <ClInclude Include="..\Include\internal\pycore_pymem.h" />
     <ClInclude Include="..\Include\internal\pycore_pystate.h" />
     <ClInclude Include="..\Include\internal\pycore_runtime.h" />
+    <ClInclude Include="..\Include\internal\pycore_sliceobject.h" />
     <ClInclude Include="..\Include\internal\pycore_strhex.h" />
     <ClInclude Include="..\Include\internal\pycore_structseq.h" />
     <ClInclude Include="..\Include\internal\pycore_sysmodule.h" />
     <ClInclude Include="..\Include\internal\pycore_symtable.h" />
     <ClInclude Include="..\Include\internal\pycore_traceback.h" />
     <ClInclude Include="..\Include\internal\pycore_tuple.h" />
+    <ClInclude Include="..\Include\internal\pycore_typeobject.h" />
     <ClInclude Include="..\Include\internal\pycore_ucnhash.h" />
     <ClInclude Include="..\Include\internal\pycore_unionobject.h" />
+    <ClInclude Include="..\Include\internal\pycore_unicodeobject.h" />
     <ClInclude Include="..\Include\internal\pycore_warnings.h" />
     <ClInclude Include="..\Include\intrcheck.h" />
     <ClInclude Include="..\Include\iterobject.h" />
index c1667e3fb74fda6ec00728bb0000dc85d4320d86..c99595755e3dc12ee618d1b707d1bad2b2d058ab 100644 (file)
     <ClInclude Include="..\Include\cpython\initconfig.h">
       <Filter>Include\cpython</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_unicodeobject.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_warnings.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_bytes_methods.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_bytesobject.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_call.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_dtoa.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_exceptions.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_fileutils.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_gc.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_genobject.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_getopt.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_long.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_long_state.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_moduleobject.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_runtime.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_sliceobject.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_strhex.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_tuple.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_typeobject.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_ucnhash.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
index a20ec7123731c21028b2c4567c25b07db79b8022..9ed73b7444d44aa72ec1c6076ceb52f0c5597261 100644 (file)
@@ -3,6 +3,7 @@
 #include "pycore_context.h"
 #include "pycore_gc.h"            // _PyObject_GC_MAY_BE_TRACKED()
 #include "pycore_hamt.h"
+#include "pycore_initconfig.h"    // _PyStatus_OK()
 #include "pycore_object.h"
 #include "pycore_pyerrors.h"
 #include "pycore_pystate.h"       // _PyThreadState_GET()
@@ -1317,15 +1318,20 @@ _PyContext_Fini(PyInterpreterState *interp)
     struct _Py_context_state *state = &interp->context;
     state->numfree = -1;
 #endif
-    _PyHamt_Fini();
+    _PyHamt_Fini(interp);
 }
 
 
-int
-_PyContext_Init(void)
+PyStatus
+_PyContext_InitTypes(PyInterpreterState *interp)
 {
-    if (!_PyHamt_Init()) {
-        return 0;
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
+    PyStatus status = _PyHamt_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if ((PyType_Ready(&PyContext_Type) < 0) ||
@@ -1333,7 +1339,7 @@ _PyContext_Init(void)
         (PyType_Ready(&PyContextToken_Type) < 0) ||
         (PyType_Ready(&PyContextTokenMissing_Type) < 0))
     {
-        return 0;
+        return _PyStatus_ERR("can't init context types");
     }
 
     PyObject *missing = get_token_missing();
@@ -1341,9 +1347,9 @@ _PyContext_Init(void)
         PyContextToken_Type.tp_dict, "MISSING", missing))
     {
         Py_DECREF(missing);
-        return 0;
+        return _PyStatus_ERR("can't init context types");
     }
     Py_DECREF(missing);
 
-    return 1;
+    return _PyStatus_OK();
 }
index 44d2773acdb5cde2ddd4021f69327f834c2e7982..5be15e54db25b8b5af5a02b30dce6152140cedd6 100644 (file)
@@ -1241,8 +1241,12 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = {
 
 
 PyStatus
-_PyErr_InitTypes(void)
+_PyErr_InitTypes(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
     if (UnraisableHookArgsType.tp_name == NULL) {
         if (PyStructSequence_InitType2(&UnraisableHookArgsType,
                                        &UnraisableHookArgs_desc) < 0) {
index e272e8808fd956e8e2636116ea02dcddd99d3f1c..8c8e025a3eff37ae39008ba4352a60c0bb9adea8 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "pycore_bitutils.h"      // _Py_popcount32
 #include "pycore_hamt.h"
+#include "pycore_initconfig.h"    // _PyStatus_OK()
 #include "pycore_object.h"        // _PyObject_GC_TRACK()
 #include <stddef.h>               // offsetof()
 
@@ -2952,9 +2953,13 @@ PyTypeObject _PyHamt_CollisionNode_Type = {
 };
 
 
-int
-_PyHamt_Init(void)
+PyStatus
+_PyHamt_InitTypes(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
     if ((PyType_Ready(&_PyHamt_Type) < 0) ||
         (PyType_Ready(&_PyHamt_ArrayNode_Type) < 0) ||
         (PyType_Ready(&_PyHamt_BitmapNode_Type) < 0) ||
@@ -2963,14 +2968,14 @@ _PyHamt_Init(void)
         (PyType_Ready(&_PyHamtValues_Type) < 0) ||
         (PyType_Ready(&_PyHamtItems_Type) < 0))
     {
-        return 0;
+        return _PyStatus_ERR("can't init hamt types");
     }
 
-    return 1;
+    return _PyStatus_OK();
 }
 
 void
-_PyHamt_Fini(void)
+_PyHamt_Fini(PyInterpreterState *interp)
 {
     Py_CLEAR(_empty_hamt);
     Py_CLEAR(_empty_bitmap_node);
index 2b386a11f9f6e84d1aab218cf8ba0f548a4d2d95..b6d73a9ce22160f5bc262f7b20ae40ad535c51b7 100644 (file)
@@ -2,18 +2,31 @@
 
 #include "Python.h"
 
+#include "pycore_bytesobject.h"   // _PyBytes_InitTypes()
 #include "pycore_ceval.h"         // _PyEval_FiniGIL()
 #include "pycore_context.h"       // _PyContext_Init()
+#include "pycore_exceptions.h"    // _PyExc_InitTypes()
+#include "pycore_dict.h"          // _PyDict_Fini()
 #include "pycore_fileutils.h"     // _Py_ResetForceASCII()
+#include "pycore_floatobject.h"   // _PyFloat_InitTypes()
+#include "pycore_frame.h"         // _PyFrame_Fini()
+#include "pycore_genobject.h"     // _PyAsyncGen_Fini()
 #include "pycore_import.h"        // _PyImport_BootstrapImp()
 #include "pycore_initconfig.h"    // _PyStatus_OK()
+#include "pycore_list.h"          // _PyList_Fini()
+#include "pycore_long.h"          // _PyLong_InitTypes()
 #include "pycore_object.h"        // _PyDebug_PrintTotalRefs()
 #include "pycore_pathconfig.h"    // _PyConfig_WritePathConfig()
 #include "pycore_pyerrors.h"      // _PyErr_Occurred()
 #include "pycore_pylifecycle.h"   // _PyErr_Print()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
+#include "pycore_sliceobject.h"   // _PySlice_Fini()
+#include "pycore_structseq.h"     // _PyStructSequence_InitState()
 #include "pycore_sysmodule.h"     // _PySys_ClearAuditHooks()
 #include "pycore_traceback.h"     // _Py_DumpTracebackThreads()
+#include "pycore_tuple.h"         // _PyTuple_InitTypes()
+#include "pycore_typeobject.h"    // _PyTypes_InitTypes()
+#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
 
 #include <locale.h>               // setlocale()
 #include <stdlib.h>               // getenv()
@@ -659,27 +672,27 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
 
 
 static PyStatus
-pycore_init_singletons(PyInterpreterState *interp)
+pycore_init_global_objects(PyInterpreterState *interp)
 {
     PyStatus status;
 
-    _PyLong_Init(interp);
+    _PyLong_InitGlobalObjects(interp);
 
-    if (_Py_IsMainInterpreter(interp)) {
-        _PyFloat_Init();
-    }
+    _PyFloat_InitState(interp);
 
-    status = _PyBytes_Init(interp);
+    status = _PyBytes_InitGlobalObjects(interp);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
 
-    status = _PyUnicode_Init(interp);
+    status = _PyUnicode_InitGlobalObjects(interp);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
 
-    status = _PyTuple_Init(interp);
+    _PyUnicode_InitState(interp);
+
+    status = _PyTuple_InitGlobalObjects(interp);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
@@ -692,48 +705,70 @@ static PyStatus
 pycore_init_types(PyInterpreterState *interp)
 {
     PyStatus status;
-    int is_main_interp = _Py_IsMainInterpreter(interp);
 
-    if (is_main_interp) {
-        if (_PyStructSequence_Init() < 0) {
-            return _PyStatus_ERR("can't initialize structseq");
-        }
+    status = _PyStructSequence_InitState(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
 
-        status = _PyTypes_Init();
-        if (_PyStatus_EXCEPTION(status)) {
-            return status;
-        }
+    status = _PyTypes_InitState(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
 
-        if (_PyLong_InitTypes() < 0) {
-            return _PyStatus_ERR("can't init int type");
-        }
+    status = _PyTypes_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
 
-        status = _PyUnicode_InitTypes();
-        if (_PyStatus_EXCEPTION(status)) {
-            return status;
-        }
+    status = _PyBytes_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    if (is_main_interp) {
-        if (_PyFloat_InitTypes() < 0) {
-            return _PyStatus_ERR("can't init float");
-        }
+    status = _PyLong_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    status = _PyExc_Init(interp);
+    status = _PyUnicode_InitTypes(interp);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
 
-    status = _PyErr_InitTypes();
+    status = _PyFloat_InitTypes(interp);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
 
-    if (is_main_interp) {
-        if (!_PyContext_Init()) {
-            return _PyStatus_ERR("can't init context");
-        }
+    status = _PyTuple_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
+
+    status = _PyExc_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
+
+    status = _PyExc_InitGlobalObjects(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
+
+    status = _PyExc_InitState(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
+
+    status = _PyErr_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
+
+    status = _PyContext_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     return _PyStatus_OK();
@@ -799,7 +834,7 @@ pycore_interp_init(PyThreadState *tstate)
     // Create singletons before the first PyType_Ready() call, since
     // PyType_Ready() uses singletons like the Unicode empty string (tp_doc)
     // and the empty tuple singletons (tp_bases).
-    status = pycore_init_singletons(interp);
+    status = pycore_init_global_objects(interp);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
@@ -1641,7 +1676,7 @@ finalize_interp_types(PyInterpreterState *interp)
     _PyFrame_Fini(interp);
     _PyAsyncGen_Fini(interp);
     _PyContext_Fini(interp);
-    _PyType_Fini(interp);
+    _PyTypes_Fini(interp);
     // Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses
     // a dict internally.
     _PyUnicode_ClearInterned(interp);
@@ -1655,7 +1690,6 @@ finalize_interp_types(PyInterpreterState *interp)
     _PyBytes_Fini(interp);
     _PyUnicode_Fini(interp);
     _PyFloat_Fini(interp);
-    _PyLong_Fini(interp);
 }