summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2021-12-09 12:59:26 -0700
committerGitHub <noreply@github.com>2021-12-09 12:59:26 -0700
commitc8749b578324ad4089c8d014d9136bc42b065343 (patch)
tree8b74af3da8568651c2c2068d9fe544617d70554f
parentd8a464ef0380692975d73a3a1513d901b6af8e65 (diff)
downloadcpython-git-c8749b578324ad4089c8d014d9136bc42b065343.tar.gz
bpo-46008: Make runtime-global object/type lifecycle functions and state consistent. (gh-29998)
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
-rw-r--r--Include/internal/pycore_bytesobject.h30
-rw-r--r--Include/internal/pycore_context.h29
-rw-r--r--Include/internal/pycore_dict.h26
-rw-r--r--Include/internal/pycore_exceptions.h37
-rw-r--r--Include/internal/pycore_floatobject.h29
-rw-r--r--Include/internal/pycore_frame.h8
-rw-r--r--Include/internal/pycore_genobject.h46
-rw-r--r--Include/internal/pycore_hamt.h11
-rw-r--r--Include/internal/pycore_interp.h183
-rw-r--r--Include/internal/pycore_list.h24
-rw-r--r--Include/internal/pycore_long.h16
-rw-r--r--Include/internal/pycore_long_state.h33
-rw-r--r--Include/internal/pycore_pyerrors.h8
-rw-r--r--Include/internal/pycore_pylifecycle.h28
-rw-r--r--Include/internal/pycore_runtime.h24
-rw-r--r--Include/internal/pycore_sliceobject.h20
-rw-r--r--Include/internal/pycore_structseq.h7
-rw-r--r--Include/internal/pycore_tuple.h37
-rw-r--r--Include/internal/pycore_typeobject.h47
-rw-r--r--Include/internal/pycore_unicodeobject.h71
-rw-r--r--Makefile.pre.in7
-rw-r--r--Objects/bytesobject.c22
-rw-r--r--Objects/exceptions.c44
-rw-r--r--Objects/floatobject.c24
-rw-r--r--Objects/genobject.c1
-rw-r--r--Objects/listobject.c1
-rw-r--r--Objects/longobject.c53
-rw-r--r--Objects/object.c28
-rw-r--r--Objects/structseq.c14
-rw-r--r--Objects/tupleobject.c21
-rw-r--r--Objects/typeobject.c3
-rw-r--r--Objects/unicodeobject.c54
-rw-r--r--PCbuild/pythoncore.vcxproj7
-rw-r--r--PCbuild/pythoncore.vcxproj.filters21
-rw-r--r--Python/context.c22
-rw-r--r--Python/errors.c6
-rw-r--r--Python/hamt.c15
-rw-r--r--Python/pylifecycle.c108
38 files changed, 811 insertions, 354 deletions
diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h
new file mode 100644
index 0000000000..b00ed9784e
--- /dev/null
+++ b/Include/internal/pycore_bytesobject.h
@@ -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 */
diff --git a/Include/internal/pycore_context.h b/Include/internal/pycore_context.h
index a482dd4212..31ca0a43fa 100644
--- a/Include/internal/pycore_context.h
+++ b/Include/internal/pycore_context.h
@@ -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 */
diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h
index 2f0536801e..faa8bb49bb 100644
--- a/Include/internal/pycore_dict.h
+++ b/Include/internal/pycore_dict.h
@@ -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
index 0000000000..1651966dad
--- /dev/null
+++ b/Include/internal/pycore_exceptions.h
@@ -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 */
diff --git a/Include/internal/pycore_floatobject.h b/Include/internal/pycore_floatobject.h
index 18227c9e36..be6045587d 100644
--- a/Include/internal/pycore_floatobject.h
+++ b/Include/internal/pycore_floatobject.h
@@ -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-
diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h
index f4f7ab942c..a55877b55f 100644
--- a/Include/internal/pycore_frame.h
+++ b/Include/internal/pycore_frame.h
@@ -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
index 0000000000..74a676df4a
--- /dev/null
+++ b/Include/internal/pycore_genobject.h
@@ -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 */
diff --git a/Include/internal/pycore_hamt.h b/Include/internal/pycore_hamt.h
index aaf6559095..cf9c19e022 100644
--- a/Include/internal/pycore_hamt.h
+++ b/Include/internal/pycore_hamt.h
@@ -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 */
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index e421aa4bc4..e4d7b1b875 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -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.
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index f18fb052c4..0717a1f956 100644
--- a/Include/internal/pycore_list.h
+++ b/Include/internal/pycore_list.h
@@ -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)
diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h
index b9f926996d..a5639ceb69 100644
--- a/Include/internal/pycore_long.h
+++ b/Include/internal/pycore_long.h
@@ -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
index 0000000000..5fe8e623a9
--- /dev/null
+++ b/Include/internal/pycore_long_state.h
@@ -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 */
diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h
index 14ea182f4f..3134afeb86 100644
--- a/Include/internal/pycore_pyerrors.h
+++ b/Include/internal/pycore_pyerrors.h
@@ -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);
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 5e0f36ab2a..766e889f23 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -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);
diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h
index 39e30b785a..bd88510d1f 100644
--- a/Include/internal/pycore_runtime.h
+++ b/Include/internal/pycore_runtime.h
@@ -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
index 0000000000..e81834c041
--- /dev/null
+++ b/Include/internal/pycore_sliceobject.h
@@ -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 */
diff --git a/Include/internal/pycore_structseq.h b/Include/internal/pycore_structseq.h
index 84c8d477e0..3a61cb9a12 100644
--- a/Include/internal/pycore_structseq.h
+++ b/Include/internal/pycore_structseq.h
@@ -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,
diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h
index 79c827fe88..624c21caec 100644
--- a/Include/internal/pycore_tuple.h
+++ b/Include/internal/pycore_tuple.h
@@ -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
index 0000000000..7fd8a1f350
--- /dev/null
+++ b/Include/internal/pycore_typeobject.h
@@ -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
index 0000000000..c50c42011a
--- /dev/null
+++ b/Include/internal/pycore_unicodeobject.h
@@ -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 */
diff --git a/Makefile.pre.in b/Makefile.pre.in
index f6801353cf..57928eead4 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -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) \
\
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 66fd2ecc3c..2f7e0a6dde 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -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)
{
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index e1a8c1363e..1340157525 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -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
}
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 7fc192e720..f8620d6f8e 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -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
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 147194c38a..1b08b43ac2 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -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()
diff --git a/Objects/listobject.c b/Objects/listobject.c
index be84cf9c33..e7023fb9eb 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -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>
diff --git a/Objects/longobject.c b/Objects/longobject.c
index ce4f0d7254..f6d5e7648b 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -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
diff --git a/Objects/object.c b/Objects/object.c
index a1c2e16b6f..124485d64a 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -10,10 +10,10 @@
#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);
diff --git a/Objects/structseq.c b/Objects/structseq.c
index 73795b677b..a2eefb0455 100644
--- a/Objects/structseq.c
+++ b/Objects/structseq.c
@@ -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();
}
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index e9d1b5926a..cb34c5eb15 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -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)
{
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 2fd93b61c0..af35180cdb 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -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);
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 532c48ad4d..14449bce70 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -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");
}
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index a2ee95e0ae..e3a71ca645 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -196,6 +196,7 @@
<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" />
@@ -203,11 +204,13 @@
<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" />
@@ -218,6 +221,7 @@
<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" />
@@ -229,14 +233,17 @@
<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" />
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index c1667e3fb7..c99595755e 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -468,6 +468,9 @@
<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>
@@ -498,6 +501,9 @@
<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>
@@ -519,6 +525,9 @@
<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>
@@ -531,6 +540,9 @@
<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>
@@ -561,6 +573,9 @@
<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>
@@ -594,6 +609,9 @@
<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>
@@ -609,6 +627,9 @@
<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>
diff --git a/Python/context.c b/Python/context.c
index a20ec71237..9ed73b7444 100644
--- a/Python/context.c
+++ b/Python/context.c
@@ -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();
}
diff --git a/Python/errors.c b/Python/errors.c
index 44d2773acd..5be15e54db 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -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) {
diff --git a/Python/hamt.c b/Python/hamt.c
index e272e8808f..8c8e025a3e 100644
--- a/Python/hamt.c
+++ b/Python/hamt.c
@@ -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);
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 2b386a11f9..b6d73a9ce2 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -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);
}