gh-81057: Move More Globals in Core Code to _PyRuntimeState (gh-99516)

https://github.com/python/cpython/issues/81057
This commit is contained in:
Eric Snow 2022-11-16 09:37:14 -07:00 committed by GitHub
parent 5cfb7d19f5
commit 5f55067e23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 241 additions and 130 deletions

View File

@ -106,5 +106,3 @@ PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg(
(minpos), (maxpos), (minkw), (buf)))
PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(PyModuleDef*, int apiver);
PyAPI_DATA(const char *) _Py_PackageContext;

View File

@ -10,6 +10,11 @@ extern "C" {
#include <locale.h> /* struct lconv */
struct _fileutils_state {
int force_ascii;
};
typedef enum {
_Py_ERROR_UNKNOWN=0,
_Py_ERROR_STRICT,

View File

@ -19,6 +19,18 @@ extern void _PyFloat_FiniType(PyInterpreterState *);
/* other API */
enum _py_float_format_type {
_py_float_format_unknown,
_py_float_format_ieee_big_endian,
_py_float_format_ieee_little_endian,
};
struct _Py_float_runtime_state {
enum _py_float_format_type float_format;
enum _py_float_format_type double_format;
};
#ifndef WITH_FREELISTS
// without freelists
# define PyFloat_MAXFREELIST 0

View File

@ -32,6 +32,8 @@ struct _import_runtime_state {
_PyTime_t accumulated;
int header;
} find_and_load;
/* Package context -- the full module name for package imports */
const char * pkgcontext;
};

View File

@ -28,6 +28,7 @@ extern "C" {
struct _pending_calls {
int busy;
PyThread_type_lock lock;
/* Request for running pending calls. */
_Py_atomic_int calls_to_do;

View File

@ -5,6 +5,36 @@
# error "this header requires Py_BUILD_CORE define"
#endif
struct pyhash_runtime_state {
struct {
#ifndef MS_WINDOWS
int fd;
dev_t st_dev;
ino_t st_ino;
#else
// This is a placeholder so the struct isn't empty on Windows.
int _not_used;
#endif
} urandom_cache;
};
#ifndef MS_WINDOWS
# define _py_urandom_cache_INIT \
{ \
.fd = -1, \
}
#else
# define _py_urandom_cache_INIT {0}
#endif
#define pyhash_state_INIT \
{ \
.urandom_cache = _py_urandom_cache_INIT, \
}
uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t);
#endif
#endif // Py_INTERNAL_HASH_H

View File

@ -14,10 +14,6 @@ extern "C" {
struct _PyArgv;
struct pyruntimestate;
/* True if the main interpreter thread exited due to an unhandled
* KeyboardInterrupt exception, suggesting the user pressed ^C. */
PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt;
extern int _Py_SetFileSystemEncoding(
const char *encoding,
const char *errors);

View File

@ -10,11 +10,13 @@ extern "C" {
#include "pycore_atomic.h" /* _Py_atomic_address */
#include "pycore_dtoa.h" // struct _dtoa_runtime_state
#include "pycore_floatobject.h" // struct _Py_float_runtime_state
#include "pycore_gil.h" // struct _gil_runtime_state
#include "pycore_global_objects.h" // struct _Py_global_objects
#include "pycore_import.h" // struct _import_runtime_state
#include "pycore_interp.h" // PyInterpreterState
#include "pycore_pymem.h" // struct _pymem_allocators
#include "pycore_pyhash.h" // struct pyhash_runtime_state
#include "pycore_obmalloc.h" // struct obmalloc_state
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids
@ -92,6 +94,12 @@ typedef struct pyruntimestate {
struct _pymem_allocators allocators;
struct _obmalloc_state obmalloc;
struct pyhash_runtime_state pyhash_state;
struct {
/* True if the main interpreter thread exited due to an unhandled
* KeyboardInterrupt exception, suggesting the user pressed ^C. */
int unhandled_keyboard_interrupt;
} signals;
struct pyinterpreters {
PyThread_type_lock mutex;
@ -131,6 +139,7 @@ typedef struct pyruntimestate {
struct _PyTraceMalloc_Config config;
} tracemalloc;
struct _dtoa_runtime_state dtoa;
struct _fileutils_state fileutils;
PyPreConfig preconfig;
@ -140,7 +149,8 @@ typedef struct pyruntimestate {
void *open_code_userdata;
_Py_AuditHookEntry *audit_hook_head;
struct _Py_unicode_runtime_ids unicode_ids;
struct _Py_float_runtime_state float_state;
struct _Py_unicode_runtime_state unicode_state;
struct {
/* Used to set PyTypeObject.tp_version_tag */

View File

@ -19,30 +19,18 @@ extern "C" {
#define _PyRuntimeState_INIT(runtime) \
{ \
.gilstate = { \
.check_enabled = 1, \
/* A TSS key must be initialized with Py_tss_NEEDS_INIT \
in accordance with the specification. */ \
.autoTSSkey = Py_tss_NEEDS_INIT, \
}, \
.allocators = { \
_pymem_allocators_standard_INIT(runtime), \
_pymem_allocators_debug_INIT, \
_pymem_allocators_obj_arena_INIT, \
}, \
.obmalloc = _obmalloc_state_INIT(runtime.obmalloc), \
.pyhash_state = pyhash_state_INIT, \
.interpreters = { \
/* This prevents interpreters from getting created \
until _PyInterpreterState_Enable() is called. */ \
.next_id = -1, \
}, \
.tracemalloc = { \
.config = _PyTraceMalloc_Config_INIT, \
}, \
.dtoa = _dtoa_runtime_state_INIT(runtime), \
.types = { \
.next_version_tag = 1, \
}, \
.imports = { \
.lock = { \
.mutex = NULL, \
@ -53,6 +41,26 @@ extern "C" {
.header = 1, \
}, \
}, \
.gilstate = { \
.check_enabled = 1, \
/* A TSS key must be initialized with Py_tss_NEEDS_INIT \
in accordance with the specification. */ \
.autoTSSkey = Py_tss_NEEDS_INIT, \
}, \
.tracemalloc = { \
.config = _PyTraceMalloc_Config_INIT, \
}, \
.dtoa = _dtoa_runtime_state_INIT(runtime), \
.fileutils = { \
.force_ascii = -1, \
}, \
.float_state = { \
.float_format = _py_float_format_unknown, \
.double_format = _py_float_format_unknown, \
}, \
.types = { \
.next_version_tag = 1, \
}, \
.global_objects = { \
.singletons = { \
.small_ints = _Py_small_ints_INIT, \

View File

@ -31,6 +31,10 @@ struct _Py_unicode_runtime_ids {
Py_ssize_t next_index;
};
struct _Py_unicode_runtime_state {
struct _Py_unicode_runtime_ids ids;
};
/* fs_codec.encoding is initialized to NULL.
Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
struct _Py_unicode_fs_codec {

View File

@ -296,10 +296,10 @@ pymain_run_module(const wchar_t *modname, int set_argv0)
Py_DECREF(module);
return pymain_exit_err_print();
}
_Py_UnhandledKeyboardInterrupt = 0;
_PyRuntime.signals.unhandled_keyboard_interrupt = 0;
result = PyObject_Call(runmodule, runargs, NULL);
if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
_Py_UnhandledKeyboardInterrupt = 1;
_PyRuntime.signals.unhandled_keyboard_interrupt = 1;
}
Py_DECREF(runpy);
Py_DECREF(runmodule);
@ -696,7 +696,7 @@ Py_RunMain(void)
pymain_free();
if (_Py_UnhandledKeyboardInterrupt) {
if (_PyRuntime.signals.unhandled_keyboard_interrupt) {
exitcode = exit_sigint();
}

View File

@ -1723,12 +1723,14 @@ float___getnewargs___impl(PyObject *self)
}
/* this is for the benefit of the pack/unpack routines below */
typedef enum _py_float_format_type float_format_type;
#define unknown_format _py_float_format_unknown
#define ieee_big_endian_format _py_float_format_ieee_big_endian
#define ieee_little_endian_format _py_float_format_ieee_little_endian
typedef enum {
unknown_format, ieee_big_endian_format, ieee_little_endian_format
} float_format_type;
#define float_format (_PyRuntime.float_state.float_format)
#define double_format (_PyRuntime.float_state.double_format)
static float_format_type double_format, float_format;
/*[clinic input]
@classmethod
@ -1929,13 +1931,9 @@ PyTypeObject PyFloat_Type = {
.tp_vectorcall = (vectorcallfunc)float_vectorcall,
};
void
_PyFloat_InitState(PyInterpreterState *interp)
static void
_init_global_state(void)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}
float_format_type detected_double_format, detected_float_format;
/* We attempt to determine if this machine is using IEEE
@ -1985,6 +1983,15 @@ _PyFloat_InitState(PyInterpreterState *interp)
float_format = detected_float_format;
}
void
_PyFloat_InitState(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}
_init_global_state();
}
PyStatus
_PyFloat_InitTypes(PyInterpreterState *interp)
{

View File

@ -218,6 +218,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
_Py_PackageContext, and PyModule_Create*() will substitute this
(if the name actually matches).
*/
#define _Py_PackageContext (_PyRuntime.imports.pkgcontext)
if (_Py_PackageContext != NULL) {
const char *p = strrchr(_Py_PackageContext, '.');
if (p != NULL && strcmp(module->m_name, p+1) == 0) {
@ -225,6 +226,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
_Py_PackageContext = NULL;
}
}
#undef _Py_PackageContext
if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
return NULL;

View File

@ -1856,7 +1856,7 @@ _PyUnicode_FromId(_Py_Identifier *id)
Py_ssize_t index = _Py_atomic_size_get(&id->index);
if (index < 0) {
struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_ids;
struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids;
PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK);
// Check again to detect concurrent access. Another thread can have
@ -14491,12 +14491,14 @@ PyTypeObject PyUnicode_Type = {
/* Initialize the Unicode implementation */
void
_PyUnicode_InitState(PyInterpreterState *interp)
static void
_init_global_state(void)
{
if (!_Py_IsMainInterpreter(interp)) {
static int initialized = 0;
if (initialized) {
return;
}
initialized = 1;
/* initialize the linebreak bloom filter */
const Py_UCS2 linebreak[] = {
@ -14514,6 +14516,15 @@ _PyUnicode_InitState(PyInterpreterState *interp)
Py_ARRAY_LENGTH(linebreak));
}
void
_PyUnicode_InitState(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}
_init_global_state();
}
PyStatus
_PyUnicode_InitGlobalObjects(PyInterpreterState *interp)

View File

@ -1,6 +1,7 @@
#include "Python.h"
#include "pycore_initconfig.h"
#include "pycore_fileutils.h" // _Py_fstat_noraise()
#include "pycore_runtime.h" // _PyRuntime
#ifdef MS_WINDOWS
# include <windows.h>
@ -263,11 +264,7 @@ py_getentropy(char *buffer, Py_ssize_t size, int raise)
#endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */
static struct {
int fd;
dev_t st_dev;
ino_t st_ino;
} urandom_cache = { -1 };
#define urandom_cache (_PyRuntime.pyhash_state.urandom_cache)
/* Read random bytes from the /dev/urandom device:
@ -402,6 +399,9 @@ dev_urandom_close(void)
urandom_cache.fd = -1;
}
}
#undef urandom_cache
#endif /* !MS_WINDOWS */

View File

@ -819,11 +819,10 @@ make_pending_calls(PyInterpreterState *interp)
}
/* don't perform recursive pending calls */
static int busy = 0;
if (busy) {
if (interp->ceval.pending.busy) {
return 0;
}
busy = 1;
interp->ceval.pending.busy = 1;
/* unsignal before starting to call callbacks, so that any callback
added in-between re-signals */
@ -851,11 +850,11 @@ make_pending_calls(PyInterpreterState *interp)
}
}
busy = 0;
interp->ceval.pending.busy = 0;
return res;
error:
busy = 0;
interp->ceval.pending.busy = 0;
SIGNAL_PENDING_CALLS(interp);
return res;
}

View File

@ -191,7 +191,7 @@ extern int _Py_normalize_encoding(const char *, char *, size_t);
Py_DecodeLocale() uses mbstowcs()
-1: unknown, need to call check_force_ascii() to get the value
*/
static int force_ascii = -1;
#define force_ascii (_PyRuntime.fileutils.force_ascii)
static int
check_force_ascii(void)

View File

@ -160,6 +160,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
p0 = (PyModInitFunction)exportfunc;
/* Package context is needed for single-phase init */
#define _Py_PackageContext (_PyRuntime.imports.pkgcontext)
oldcontext = _Py_PackageContext;
_Py_PackageContext = PyUnicode_AsUTF8(name_unicode);
if (_Py_PackageContext == NULL) {
@ -168,6 +169,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
}
m = _PyImport_InitFunc_TrampolineCall(p0);
_Py_PackageContext = oldcontext;
#undef _Py_PackageContext
if (m == NULL) {
if (!PyErr_Occurred()) {

View File

@ -10,9 +10,6 @@ typedef double va_double;
static PyObject *va_build_value(const char *, va_list, int);
static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*);
/* Package context -- the full module name for package imports */
const char *_Py_PackageContext = NULL;
int
_Py_convert_optional_to_ssize_t(PyObject *obj, void *result)

View File

@ -77,8 +77,6 @@ static PyStatus init_sys_streams(PyThreadState *tstate);
static void wait_for_thread_shutdown(PyThreadState *tstate);
static void call_ll_exitfuncs(_PyRuntimeState *runtime);
int _Py_UnhandledKeyboardInterrupt = 0;
/* The following places the `_PyRuntime` structure in a location that can be
* found without any external information. This is meant to ease access to the
* interpreter state for various runtime debugging tools, but is *not* an

View File

@ -137,8 +137,8 @@ init_runtime(_PyRuntimeState *runtime,
// Set it to the ID of the main thread of the main interpreter.
runtime->main_thread = PyThread_get_thread_ident();
runtime->unicode_ids.next_index = unicode_next_index;
runtime->unicode_ids.lock = unicode_ids_mutex;
runtime->unicode_state.ids.next_index = unicode_next_index;
runtime->unicode_state.ids.lock = unicode_ids_mutex;
runtime->_initialized = 1;
}
@ -154,7 +154,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
_Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head;
// bpo-42882: Preserve next_index value if Py_Initialize()/Py_Finalize()
// is called multiple times.
Py_ssize_t unicode_next_index = runtime->unicode_ids.next_index;
Py_ssize_t unicode_next_index = runtime->unicode_state.ids.next_index;
PyThread_type_lock lock1, lock2, lock3, lock4;
if (alloc_for_runtime(&lock1, &lock2, &lock3, &lock4) != 0) {
@ -186,7 +186,7 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
FREE_LOCK(runtime->interpreters.mutex);
FREE_LOCK(runtime->xidregistry.mutex);
FREE_LOCK(runtime->unicode_ids.lock);
FREE_LOCK(runtime->unicode_state.ids.lock);
FREE_LOCK(runtime->getargs.mutex);
#undef FREE_LOCK
@ -209,7 +209,7 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex);
int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex);
int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_ids.lock);
int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_state.ids.lock);
int reinit_getargs = _PyThread_at_fork_reinit(&runtime->getargs.mutex);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

View File

@ -1688,7 +1688,8 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
* uncaught exception to trigger an unexplained signal exit from a future
* Py_Main() based one.
*/
_Py_UnhandledKeyboardInterrupt = 0;
// XXX Isn't this dealt with by the move to _PyRuntimeState?
_PyRuntime.signals.unhandled_keyboard_interrupt = 0;
/* Set globals['__builtins__'] if it doesn't exist */
if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) {
@ -1702,7 +1703,7 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
v = PyEval_EvalCode((PyObject*)co, globals, locals);
if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) {
_Py_UnhandledKeyboardInterrupt = 1;
_PyRuntime.signals.unhandled_keyboard_interrupt = 1;
}
return v;
}

View File

@ -336,17 +336,7 @@ Python/perf_trampoline.c - perf_status -
Python/perf_trampoline.c - extra_code_index -
Python/perf_trampoline.c - code_arena -
Python/perf_trampoline.c - trampoline_api -
Parser/pegen.c - memo_statistics -
Python/bootstrap_hash.c - urandom_cache -
Python/ceval_gil.c make_pending_calls busy -
Python/ceval.c _PyEval_SetProfile reentrant -
Python/ceval.c _PyEval_SetTrace reentrant -
Python/modsupport.c - _Py_PackageContext -
Python/thread_pthread_stubs.h - py_tls_entries -
Python/pyfpe.c - PyFPE_counter -
Python/pylifecycle.c _Py_FatalErrorFormat reentrant -
Python/pylifecycle.c - _Py_UnhandledKeyboardInterrupt -
Python/pylifecycle.c fatal_error reentrant -
##################################

Can't render this file because it has a wrong number of fields in line 4.

View File

@ -1,16 +1,95 @@
filename funcname name reason
#??? - somevar ???
# All globals here are technically mutable but known to be safe.
##################################
# mutable but known to be safe
# process-global resources
# Initialization for these should be idempotent.
#-----------------------
# effectively const, set once before/during first init
Modules/getbuildinfo.c - buildinfo -
Modules/getbuildinfo.c - initialized -
Python/getversion.c - initialized -
Python/getversion.c - version -
#-----------------------
# effectively const, set once during first init
Python/bootstrap_hash.c - _Py_HashSecret_Initialized -
Python/pyhash.c - _Py_HashSecret -
Python/thread.c - initialized -
Python/thread_pthread.h - condattr_monotonic -
# safe static buffer used during one-time initialization
Python/thread_pthread.h init_condattr ca -
# indicators for process-global resource availability/capability
Python/bootstrap_hash.c py_getrandom getrandom_works -
Python/fileutils.c - _Py_open_cloexec_works -
Python/fileutils.c set_inheritable ioctl_works -
#-----------------------
# effectively const but set once lazily (*after* first init)
Objects/longobject.c long_from_non_binary_base log_base_BASE -
Objects/longobject.c long_from_non_binary_base convwidth_base -
Objects/longobject.c long_from_non_binary_base convmultmax_base -
Objects/unicodeobject.c - bloom_linebreak -
Objects/unicodeobject.c _init_global_state initialized -
# XXX Move to _PyRuntimeState?
Parser/action_helpers.c _PyPegen_dummy_name cache -
##################################
# state tied to C main() (only in main thread)
#-----------------------
# handling C argv
Python/getopt.c - _PyOS_optarg -
Python/getopt.c - _PyOS_opterr -
Python/getopt.c - _PyOS_optind -
Python/getopt.c - opt_ptr -
Python/pathconfig.c - _Py_path_config -
#-----------------------
# REPL
Parser/myreadline.c - _PyOS_ReadlineLock -
Parser/myreadline.c - _PyOS_ReadlineTState -
Parser/myreadline.c - PyOS_InputHook -
Parser/myreadline.c - PyOS_ReadlineFunctionPointer -
##################################
# state tied to each runtime init/fini cycle
Python/pylifecycle.c - _PyRuntime -
Python/pylifecycle.c - runtime_initialized -
# All uses of _PyArg_Parser are handled in c-analyzr/cpython/_analyzer.py.
#-----------------------
# legacy config flags
# effectively const once init finishes
# set by embedders before init (whether directly or through a call)
Python/initconfig.c - _Py_StandardStreamEncoding -
Python/initconfig.c - _Py_StandardStreamErrors -
Python/initconfig.c - orig_argv -
# deprecated
Python/preconfig.c - Py_FileSystemDefaultEncoding -
Python/preconfig.c - Py_HasFileSystemDefaultEncoding -
Python/preconfig.c - Py_FileSystemDefaultEncodeErrors -
Python/preconfig.c - _Py_HasFileSystemDefaultEncodeErrors -
# legacy config flags
Python/initconfig.c - Py_UTF8Mode -
Python/initconfig.c - Py_DebugFlag -
Python/initconfig.c - Py_VerboseFlag -
@ -30,75 +109,34 @@ Python/initconfig.c - Py_IsolatedFlag -
Python/initconfig.c - Py_LegacyWindowsFSEncodingFlag -
Python/initconfig.c - Py_LegacyWindowsStdioFlag -
#-----------------------
# effectively const, initialized before init
# initialized statically, customized by embedders
Python/frozen.c - PyImport_FrozenModules -
Python/import.c - inittab_copy -
Python/import.c - PyImport_Inittab -
#-----------------------
# effectively const, initialized before/during init
Modules/getbuildinfo.c - buildinfo -
Modules/getbuildinfo.c - initialized -
Python/getversion.c - initialized -
Python/getversion.c - version -
#-----------------------
# effectively const, initialized during init
Objects/floatobject.c - double_format -
Objects/floatobject.c - float_format -
Objects/unicodeobject.c - bloom_linebreak -
Python/bootstrap_hash.c py_getrandom getrandom_works -
Python/bootstrap_hash.c - _Py_HashSecret_Initialized -
Python/fileutils.c - _Py_open_cloexec_works -
Python/fileutils.c - force_ascii -
Python/fileutils.c set_inheritable ioctl_works -
Python/import.c import_find_and_load header -
Python/initconfig.c - orig_argv -
Python/preconfig.c - Py_FileSystemDefaultEncoding -
Python/preconfig.c - Py_HasFileSystemDefaultEncoding -
Python/preconfig.c - Py_FileSystemDefaultEncodeErrors -
Python/preconfig.c - _Py_HasFileSystemDefaultEncodeErrors -
Python/pyhash.c - _Py_HashSecret -
Python/pylifecycle.c - runtime_initialized -
# used temporarily during init
Python/sysmodule.c - _preinit_warnoptions -
Python/sysmodule.c - _preinit_xoptions -
Python/thread.c - initialized -
Python/thread_pthread.h - condattr_monotonic -
Python/thread_pthread.h init_condattr ca -
# set by embedders during init
Python/initconfig.c - _Py_StandardStreamEncoding -
Python/initconfig.c - _Py_StandardStreamErrors -
#-----------------------
# effectively const but initialized lazily
# XXX Move them to _PyRuntimeState?
##################################
# special-use diagnistic state
# idempotent
Objects/longobject.c long_from_non_binary_base log_base_BASE -
Objects/longobject.c long_from_non_binary_base convwidth_base -
Objects/longobject.c long_from_non_binary_base convmultmax_base -
Parser/action_helpers.c _PyPegen_dummy_name cache -
Parser/pegen.c - memo_statistics -
#-----------------------
# used only in the main thread
# REPL
Parser/myreadline.c - _PyOS_ReadlineLock -
Parser/myreadline.c - _PyOS_ReadlineTState -
Parser/myreadline.c - PyOS_InputHook -
Parser/myreadline.c - PyOS_ReadlineFunctionPointer -
##################################
# one-off temporary state
# handling C argv
Python/getopt.c - _PyOS_optarg -
Python/getopt.c - _PyOS_opterr -
Python/getopt.c - _PyOS_optind -
Python/getopt.c - opt_ptr -
Python/pathconfig.c - _Py_path_config -
# This is safe enough.
Python/pylifecycle.c _Py_FatalErrorFormat reentrant -
Python/pylifecycle.c fatal_error reentrant -
##################################
# not used (kept for compatibility)
Python/pyfpe.c - PyFPE_counter -
##################################

Can't render this file because it has a wrong number of fields in line 4.